<?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>

	<class name="lzViewCalendarEvent" extends="view" bgcolor="0xBBBBBB" clickable="true" 
							showhandcursor="false" width="300" height="120"  focusable="true">
	
		<attribute name="dataElement" value="null" />
		
		<attribute name="lzCalendarRef" value="null" />
		
		<dataset name="eventDS" />
		
		<attribute name="refCalendarEventView" value="null" />
		
		<attribute name="appointmentId" value="0" type="number" />
		
		<handler name="oninit">
			<![CDATA[
				//this._content._title.setAttribute("fgcolor",this.refCalendarEventView.bgcolor);
			
				var x_canvas = canvas.getMouse("x") - (this.width/2) + 60;
				
				if (x_canvas + this.width + 4 > canvas.width) {
					x_canvas = canvas.width - 310;
					var tX = canvas.getMouse("x")-x_canvas-8;
					if (tX + 24 > this.width) {
						tX = this.width - 24;
					}
					this.pointerToEvent.setAttribute("x",tX);
				}
				this.setAttribute("x",x_canvas);
				var y_canvas = canvas.getMouse("y");
				this.setAttribute("y",y_canvas-this.height-12);
				
            	this.eventDS.setAttribute("data", this.dataElement.childNodes);
            	
            	this.appointmentId = this.eventDS.getPointer().xpathQuery('appointmentId/text()');
	            
	            if ($debug) Debug.write("this.eventDS ",this.eventDS);
	            if ($debug) Debug.write("this.appointmentId ",this.appointmentId);
	            
	            lz.Focus.setFocus(this);
	            this.setShadow();
	            lz.ModeManager.makeModal(this);
            ]]>
		</handler>
		
		<method name="setShadow">
	        <![CDATA[
	            var normalMC = this.getDisplayObject();
	            var displacementMap = new flash.filters.DropShadowFilter();
	            normalMC.filters = [displacementMap];
	        ]]>              
	    </method>
	    
	    <netRemoteCallHib name="deleteAppointment" funcname="calendarservice.deleteAppointment" 
							  remotecontext="$once{ canvas.thishib }" >     
			<netparam><method name="getValue">return canvas.sessionId; </method></netparam>
			<netparam><method name="getValue">return parent.parent.appointmentId;</method></netparam>	
			<netparam><method name="getValue">return hib.userlang;</method></netparam>
	    	<handler name="ondata" args="value">
	    		<![CDATA[
		    		if ($debug) Debug.write("deleteAppointment ",value);
		    		parent.lzCalendarRef.reload();
					parent.close();
	    		 ]]>
	    	</handler>
	    </netRemoteCallHib> 
	
		<method name="close">
			if ($debug) Debug.write("CLOSE lzViewCalendarEvent");
			this.lzCalendarRef.lzViewCalendarEvent = null;
			lz.ModeManager.release(this);
			this.destroy();
		</method>
		
		<!--- @keywords private -->
	    <method name="passModeEvent" args="eventStr,view" > 
	        <![CDATA[
	            if ( eventStr == "onmousedown"  ){
	                if ( view != null ) {
	                   if ( !view.childOf(this) ) {
	                        this.close();
	                   }
	                } else {
	                    this.close();
	                }
	            }
	            if (view && view.childOf(this)) {
	                if (view[ eventStr ]) {
	                    view[ eventStr ].sendEvent( view );
	                }
	                return false;
	            }
	            return true;
	        ]]> 
	    </method> 	
	
		<view name="_content" width="$once{ parent.width-3 }" height="$once{ parent.height-3 }" 
									x="1.5" y="1.5" bgcolor="0xFFFFFF">
		
			<labelText name="_title" x="5" y="4" datapath="local:classroot.eventDS:/title" 
						fontsize="12" fontstyle="bold" fgcolor="0x320DC8" multiline="true" 
						text="$path{'text()'}" width="$once{ parent.width-40 }" height="60"/>
			
			<!-- Start  -->
			<labelText name="_start" x="5" y="26" datapath="local:classroot.eventDS:/start">
				<handler name="ondata" args="d">
					this.setAttribute("text",canvas.getLabelName(570)+ " " +parseDateTimeStringFromXmlString(d.childNodes[0].data));
				</handler>
			</labelText>
			
			<labelText name="_end" x="5" y="44" datapath="local:classroot.eventDS:/end">
				<handler name="ondata" args="d">
					this.setAttribute("text",canvas.getLabelName(571)+ " " +parseDateTimeStringFromXmlString(d.childNodes[0].data));
				</handler>
			</labelText>
		
			<view name="_closeButton" x="${ this.parent.parent.width-20 }"
					y="2" resource="btn_presenter_close"
	                onmouseover="this.setAttribute('frame',2)"
	                onmouseout="this.setAttribute('frame',1)"
	                onmouseup="this.setAttribute('frame',1)" >
				<handler name="onclick">
					this.parent.parent.close();
				</handler>									
			</view>
			
			<simpleLabelButton labelid="1282" width="110" x="$once{ parent.width-115 }" y="$once{ parent.height-50 }" 
						datapath="local:classroot.eventDS:/roomId" >
						
				<attribute name="roomId" value="$path{ 'text()' }" type="number" />
						
		        <handler name="onclick">
		        	if ($debug) Debug.write("roomId ",roomId);
		        	if (roomId > 0) {
		        		parent.parent.close();
                   		canvas.initroomid = roomId;
                   		canvas.thishib.getRoomById.doCall();
                   	} else {
                   		new lz.labelerrorPopup(canvas,{errorlabelid:1285});
                   	}
	           	</handler>
	        </simpleLabelButton>
			
			<simpleLabelButton labelid="814" width="100" x="5" y="$once{ parent.height-24 }" >
		        <handler name="onclick">
		        	//check if event is from other user
		        	new lz.confirmationSingle(parent.parent,{
			        				x:0,y:0,
		        					width:parent.parent.width,
		        					height:parent.parent.height+16,
			        				refObj:this,labelid:797,
	           						showCheckBox:false,
	           						labeliderror:796,
	           						doCalcPosition:false,
	           						docking:false,
	           						allowDragging:false
           						});
	           	</handler>
	           	<method name="sendConfirmation" args="refObj,t">
	           		parent.parent.deleteAppointment.doCall();
	           	</method>
	        </simpleLabelButton>
		
		    <simpleLabelButton labelid="1446" width="110" x="$once{ parent.width-115 }" 
		           y="$once{ parent.height-24 }" 
		           onclick="this.parent.close();">
		        <handler name="onclick">
		        	var tElement = parent.parent.eventDS.cloneNode(true);
		        	if ($debug) Debug.write("tElement ",tElement);
	         		parent.parent.lzCalendarRef.editCalendarEvent(tElement);
	         		parent.parent.close();
	           	</handler>
            </simpleLabelButton>
			
		
		</view>
		
		<view name="pointerToEvent" y="118" x="$once{ ((parent.width/2) - 8) - 60 }"
			resource="single_event_popup_background_rsc" />>
	
	</class>
	
</library>