<?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', canvas.getNotNullString(obj.updatetime));
			this.users_login.setAttribute('text', canvas.getNotNullString(obj.user.login));
        ]]>
    </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>
