<?xml version="1.0" encoding="UTF-8" ?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
    	  
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
  
-->
<library>

<!--- configuration edit panel. -->
<class name="confAdminValueForm" extends="baseContentSaveView">

	<!-- recordContent-id -->
	<attribute name="configuration_id" value="0" type="number" />
    <attribute name="confobj" value="null" />
	
	<!--handlers -->

	<handler name="onsavecompleted" >
		this.getConfByConfigurationId.doCall();
	</handler>
	
	<handler name="onreload" >
		if (this.configuration_id!=0) this.getConfByConfigurationId.doCall();
	</handler>	

	<handler name="onnew">
		this.configuration_id=0;
		this.comment.setAttribute('text','');
		this.conf_key.setAttribute('text','');
		this.conf_value.setAttribute('text','');
		this.updatetime.setAttribute('text','');
        this.users_login.setAttribute('text','');
	</handler>
	
    <handler name="ondelete" >
		if (this.configuration_id!=0){
            this.deleteConfiguration.prepareCall();
			this.deleteConfiguration.doCall();
		}
    </handler>
	
	<!-- methods -->

    <method name="initValueFieldsByObject" args="obj">
		this.configuration_id = obj.configuration_id;
		if (this.configuration_id!=0){
			this.getConfByConfigurationId.doCall();
		}
    </method>
    
    <method name="initFields" args="obj">
    	<![CDATA[
            //Debug.write("initFields: ",obj);
            this.confobj = obj;
			this.comment.setAttribute('text',obj.comment);
			this.conf_key.setAttribute('text',obj.conf_key);
			this.conf_value.setAttribute('text',obj.conf_value);
			this.updatetime.setAttribute('text',obj.updatetime);
            if(obj.users!=null){
			    this.users_login.setAttribute('text',obj.users.login);
            } else {
                this.users_login.setAttribute('text','');
            }
        ]]>
    </method>
	
	<!-- remotecalls -->
	
  	<netRemoteCallHib name="getConfByConfigurationId" funcname="configservice.getConfByConfigurationId" 
  		remotecontext="$once{ canvas.thishib }" > 
  		<netparam><method name="getValue">return canvas.sessionId; </method></netparam>
    	<netparam><method name="getValue">return parent.parent.configuration_id;</method></netparam>
    	<handler name="ondata" args="value">
    		parent.initFields(value);
    	</handler>
  	</netRemoteCallHib>
	
	<netRemoteCallHib name="deleteConfiguration" funcname="configservice.deleteConfiguration" remotecontext="$once{ canvas.thishib }" >      
        <attribute name="sendObject" value="null" />
		<method name="prepareCall">
  			this.sendObject=new Array();
            this.sendObject["configuration_id"] = this.parent.configuration_id;
            this.sendObject["comment"] = this.parent.comment.getText();
            this.sendObject["conf_key"] = this.parent.conf_key.getText();
            this.sendObject["conf_value"] = this.parent.conf_value.getText();
  			//Debug.write("prepareCall: ",this.sendObject);
  		</method>
  		<netparam><method name="getValue">return canvas.sessionId; </method></netparam>
    	<netparam><method name="getValue">return parent.sendObject;</method></netparam>	
        <handler name="ondata" args="value">
			//Debug.write("deleteConfiguration ",value);
			if (value>0){
				this.parent.parent._turnoverlist.oncallnext.sendEvent();
				this.parent.onnew.sendEvent();
			}
		</handler>
	</netRemoteCallHib>		

  	<netRemoteCallHib name="saveOrUpdateConfiguration" funcname="configservice.saveOrUpdateConfiguration" 
  		remotecontext="$once{ canvas.thishib }" registerObject="true" >   
		<attribute name="sendObject" value="null" />
		<!-- gets called by Observer -->
  		<method name="prepareCall">
  			this.sendObject=new Array();
            this.sendObject["configuration_id"] = this.parent.configuration_id;
            this.sendObject["comment"] = this.parent.comment.getText();
            this.sendObject["conf_key"] = this.parent.conf_key.getText();
            this.sendObject["conf_value"] = this.parent.conf_value.getText();
            //Debug.write("prepareCall: ",this.sendObject);
  		</method>
  		<netparam><method name="getValue">return canvas.sessionId; </method></netparam>
    	<netparam><method name="getValue">return parent.sendObject;</method></netparam>	  		
    	<handler name="ondata" args="val">
			<![CDATA[
    		//Debug.write("saveOrUpdateConfiguration ",val);
			if (val>0){
				//Debug.write("updateConfByConfigurationId val greater 0: ",val);
				this.parent.parent._turnoverlist.oncallnext.sendEvent();
				var obj = new Array();
				obj["configuration_id"] = val;
				this.parent.initValueFieldsByObject(obj);
			}
			]]>
    	</handler>
  	</netRemoteCallHib>	
	
	<!-- content -->
    
    <labelText labelid="266" width="200" y="40" resize="false" fontstyle="bold" />
    
    <labelText labelid="267" width="200" y="70" resize="false" x="2"/>
        <customEdittext name="conf_key" y="70" x="120" width="270" text="" />

    <labelText labelid="271" width="200" y="100" resize="false" x="2"/>
        <customEdittext name="conf_value" y="100" x="120" width="270" text="" />

    <labelText labelid="268" width="200" y="130" resize="false" x="2"/>
        <labelText name="updatetime" y="130" x="120" width="270" text="" />
 
    <labelText labelid="269" width="200" y="160" resize="false" x="2"/>
        <labelText name="users_login" y="160" x="120" width="270" text="" />

    <labelText labelid="270" width="200" y="190" resize="false" x="2"/>
        <customScrollEdittext name="comment" y="190" x="120" width="270" 
            height="100" text="" />    
         
</class>

</library>
