<?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="baseDrawImage" extends="baseDrawLetter">
	
  	<!-- attribute shows if this image is loaded as part of a wml-file-object
		if true it will send a onwmlLoaderSend message and NO extra loading bar
		if false it will show a loading abr for that image
	-->
	<attribute name="isWmlLoaderImage" value="false" type="boolean" />
    
    <!-- indicates if this client is still loading an old image for the screenViwer -->
    <attribute name="isScreenImageLoading" value="false" type="boolean" />
    <attribute name="screenImageRefNumber" value="1" type="number" />
    <attribute name="screenImageRef1" value="null" />
    <attribute name="screenImageRef2" value="null" />
	
    <event name="setNewScreenUserName" />
  	
  	<!-- invoked by clicking on the confirmation dialog after 
  		clicking on an image in the Library -->
  	<method name="addNewSyncImage" args="urlname,posx,posy,baseurl,fileName,moduleName,parentPath,room,domain">
  		if ($debug) Debug.write("urlname: ",urlname);
  		var now = new Date();
  		//This invokes a Method which is in the remoteWhiteboard.lzx
  		this.startNewObjectSyncProcess.isStarting = true;
  		this.startNewObjectSyncProcess.uniqueObjectSyncName = fileName + now.getTime();
  		this.startNewObjectSyncProcess.doCall();
  		this.addNewImage(urlname,posx,posy,baseurl,fileName,
  			moduleName,parentPath,room,domain,
  			this.startNewObjectSyncProcess.uniqueObjectSyncName,false);
  	</method>
  	
  	<!-- standard add Function -->
  	<method name="addNewImage" args="urlname,posx,posy,baseurl,fileName,moduleName,parentPath,room,domain,uniqueObjectSyncName,isLocalSync">
  		if ($debug) Debug.write("urlname posx: ",urlname,posx);
  		this.addImageToLayer(this,'image'+this.getCounter(),urlname,
  			posx,posy,0,0,
  			true,
  			baseurl,fileName,moduleName,parentPath,room,domain,uniqueObjectSyncName,isLocalSync);
  	</method>
  	
	<!--
		alterModus => this is added by the mod not remotely
		
	 -->
  	<method name="addImageToLayer" args="obj,nameing,urlname,posx,posy,width,height,alterModus,baseurl,fileName,moduleName,parentPath,room,domain,uniqueObjectSyncName,isLocalSync">
        <![CDATA[
			//only show if it is not part of wml-file-object
			//do not show at all as this is handled via the remote Object
			//if (!this.isWmlLoaderImage) {
			//	this.loadimageDataWinRef = new lz.loadWhiteboardWindow(canvas.main_content._content.inner,{refObj:this});
			//	this.loadimageDataWinRef.setMessage(canvas.getLabelName(this.imageLoadMessageId));
			//}
			
            if ($debug) Debug.write("addImageToLayer ",urlname);
        	//if ($debug) Debug.write("addImageToLayer ",obj,nameing,urlname,posx,posy,width,height,alterModus,baseurl,fileName,moduleName,parentPath,room,domain);
			//if ($debug) Debug.write("addImageToLayer posx ",posx);
        	
	  		if ($debug) Debug.write("addImageToLayer urlname : ", canvas.getUrl() + 'DownloadHandler');
			var src = canvas.getUrl() + 'DownloadHandler' + '?fileName=' + encodeURIComponent(fileName) + 
				'&moduleName=' + moduleName +
				'&parentPath=' + encodeURIComponent(parentPath) +
				'&room_id=' + room + 
				'&sid=' + canvas.sessionId;
	
	        if ($debug) Debug.write("addImageToLayer -src- ",src);
		      
			if ($debug) Debug.write("alterModus: ",alterModus);
			
	  		this.currentlayer = new lz.imageForDrawView(obj,{
	  			src:src,refObj:this,name:nameing,x:posx,y:posy,
	  			remotewidth:width,remoteheight:height,
	  			downloadurl:urlname,alterModus:alterModus,
	  			baseurl:baseurl,fileName:fileName,moduleName:moduleName,
	  			parentPath:parentPath,room:room,domain:domain,
	  			uniqueObjectSyncName:uniqueObjectSyncName,
	  			isLocalSync:isLocalSync});	
			
			//this.parent.parent.isloadingImage.sendEvent(this.currentlayer);
			//this.parent._loading.setAttribute('visible',true);
			
			//Add Layer to global Layer  	
		    return this.currentlayer;
		]]>
  	</method>
  	
  	<!--
  	    @deprecated
  	 -->
  	<method name="addImageToLayerRecorded" args="obj,nameing,urlname,posx,posy,width,height,alterModus,baseurl,fileName,moduleName,parentPath,room,domain">
        <![CDATA[
			//only show if it is not part of wml-file-object
			if (!this.isWmlLoaderImage) {
				this.loadimageDataWinRef = new lz.loadWhiteboardWindow(canvas.main_content._content.inner,{refObj:this});
				this.loadimageDataWinRef.setMessage(canvas.getLabelName(this.imageLoadMessageId));
			}
			var src = baseurl+'?fileName='+fileName+'&moduleName='+moduleName+'&parentPath='+parentPath+'&room_id='+room+'&sid='+canvas.sessionId;
	
			this.currentlayer = new lz.imageForDrawView(obj,{
				src:src,refObj:this,name:nameing,x:posx,y:posy,
				downloadurl:urlname,remotewidth:width,remoteheight:height,
				alterModus:alterModus,baseurl:baseurl,fileName:fileName,
				moduleName:moduleName,parentPath:parentPath,
				room:room,domain:domain,recorderModus:true});

			this.parent.parent.isloadingImage.sendEvent(this.currentlayer);
			//this.parent._loading.setAttribute('visible',true);
			//Add Layer to global Layer  	
		    return this.currentlayer;
		]]>
  	</method>
  	
  	<method name="incomingScreenSharing" args="value">
        <![CDATA[
		//only do if last image has been loading successfully
            if (!this.isScreenImageLoading){
                this.isScreenImageLoading = true;
                var downloadurl = canvas.getUrl() + 'ScreenViewHandler?'
                    +'fileName='+encodeURIComponent(value.fileName)
                    +'&room='+hib.currentroomid
                    +'&domain='+hib.conferencedomain
                    +'&sid='+canvas.sessionId;
            
                //Debug.write("incomingScreenSharing URL: ",downloadurl);
                if (this.screenImageRefNumber==1){
                    this.screenImageRef1 = new lz.imageForScreenViewer(this,{visible:false,src:downloadurl,refObj:this,name:'screen1',x:0,y:0,downloadurl:downloadurl});
                    this.screenImageRefNumber = 2;
                } else if (this.screenImageRefNumber==2){
                    this.screenImageRef2 = new lz.imageForScreenViewer(this,{visible:false,src:downloadurl,refObj:this,name:'screen2',x:0,y:0,downloadurl:downloadurl});
                    this.screenImageRefNumber = 1;
                }
                this.setNewScreenUserName.sendEvent('Screen of User: '+value.user.firstname+','+value.user.lastname);
            } else {
                //Debug.write("frame dropped!");
                Debug.warn("frame dropped!");
                (new lz.singletonErrorPopupHolder()).setError(canvas.getLabelName(240));
            }
		]]>
  	</method>   
    
    <!--
    TODO: Make new Base Class including the Screen sharing Functions
     -->
    <method name="toggleVisibleScreenSharing">
        if (this.screenImageRefNumber==1){
            if (this.screenImageRef1) this.screenImageRef1.destroy();
            this.screenImageRef2.setAttribute('visible',true);
        } else if (this.screenImageRefNumber==2){
            this.screenImageRef1.setAttribute('visible',true);
            if (this.screenImageRef2) this.screenImageRef2.destroy();
        }
        this.isScreenImageLoading = false;
    </method> 
	
	<!--
		actionObject => attributes neccessary for loading image
		refObj = drawarea
		isWmlLoader => (true)is loaded as part of wml-object
		
		-->
		
	<!-- method adds a new Image to the Layer,
	but without making an Update-Event, 
	Image added by remote host -->	
  	<method name="addImageToLayerHistorySynced" args="actionObject,refObj">
  		if ($debug) Debug.write("addImageToLayerHistory: ",actionObject,refObj);
  		//start sync process using the remote uniqueObjectSyncName as identifier
  		//This invokes a Method which is in the remoteWhiteboard.lzx
  		this.startNewObjectSyncProcess.isStarting = false;
  		this.startNewObjectSyncProcess.uniqueObjectSyncName = actionObject[8];
  		this.startNewObjectSyncProcess.doCall();
  		this.addImageToLayer(refObj,actionObject[actionObject.length-1],actionObject[1],
		  		actionObject[actionObject.length-5],actionObject[actionObject.length-4],
		  		actionObject[actionObject.length-3],actionObject[actionObject.length-2],
		  		false,
		  		actionObject[2],actionObject[3],actionObject[4],actionObject[5],
		  		actionObject[6],actionObject[7],actionObject[8],false);
		  		
  		this.doSWFDocumentStatus(this.currentlayer,actionObject[actionObject.length-7]);
  	</method>
  			
  	<!--- 
		invoke by the initial Loading process in remoteWhiteboard.lzx, 
		does not invoke any Update Handler
		once this object is loaded, it will throw an Update event of kind
		addImageToLayerHistoryToLocalLoaded		
  	 -->
  	<method name="addImageToLayerHistoryToLocal" args="actionObject,refObj">
  		if ($debug) Debug.write("addImageToLayerHistoryToLocal: ",actionObject,refObj);
  		this.addImageToLayer(refObj,actionObject[actionObject.length-1],actionObject[1],
		  		actionObject[actionObject.length-5],actionObject[actionObject.length-4],
		  		actionObject[actionObject.length-3],actionObject[actionObject.length-2],
		  		false,
		  		actionObject[2],actionObject[3],actionObject[4],actionObject[5],
		  		actionObject[6],actionObject[7],actionObject[8],true);
  	</method>
  	
  	<!-- 
  		this handler is implemented also in remoteWhiteboard.lzx to sync a Local Object list
  		but throws NO Update Event, cause its only needed Locally, the whole Sync Process
  		has a different Sync-Object for Loading the complete Object List from the Sever.
  		Each Object is loaded Locally, once all Objects are loaded the Complete-Event is broadcasted
  		to the server, but every Item on the List is only controlled locally
  	-->
  	<handler name="addImageToLayerHistoryToLocalLoaded" args="objRef">
  		if ($debug) Debug.write("addImageToLayerHistoryToLocal: ",objRef);
		this.syncImageRefObj = objRef;
		
		this.registerNewImage(this.syncImageRefObj.src,
			this.syncImageRefObj.x,this.syncImageRefObj.y,
			this.syncImageRefObj.width,this.syncImageRefObj.height,
			this.syncImageRefObj.baseurl,this.syncImageRefObj.fileName,
			this.syncImageRefObj.moduleName,this.syncImageRefObj.parentPath,
			this.syncImageRefObj.room,this.syncImageRefObj.domain,
			false,this.syncImageRefObj.uniqueObjectSyncName,this.getSWFDocumentStatus(),
                this.getZIndex());
  	</handler>
  	
  	<!--- @keywords deprecated
  	TODO: uniqueObjectSyncName missing
  	 -->
  	<method name="addImageToLayerHistoryRecorded" args="actionObject,refObj,isWmlLoader">
		this.isWmlLoaderImage = isWmlLoader;
  		this.addImageToLayerRecorded(refObj,
  			actionObject[actionObject.length-1],actionObject[1],
  			actionObject[actionObject.length-5],actionObject[actionObject.length-4],
  			actionObject[actionObject.length-3],actionObject[actionObject.length-2],
  			false,
  			actionObject[2],actionObject[3],actionObject[4],actionObject[5],
  			actionObject[6],actionObject[7]);
  	</method>
  	
  	<method name="registerNewImage" args="urlname,posx,posy,width,height,baseurl,fileName,moduleName,parentPath,room,domain,doCallUpdate,uniqueObjectSyncName,swfObj,zIndex">
		if ($debug) Debug.write("registerNewImage doCallUpdate: ",doCallUpdate);
		if ($debug) Debug.write("registerNewImage swfObj: ",swfObj);
		var actionObject = new Array();
	    actionObject.push('image');
	    actionObject.push(urlname);
		actionObject.push(baseurl);
		actionObject.push(fileName);
		actionObject.push(moduleName);
		actionObject.push(parentPath);
		actionObject.push(room);
		actionObject.push(domain);
		actionObject.push(uniqueObjectSyncName);
		actionObject.push(zIndex);//-8
		actionObject.push(swfObj);//-7
		actionObject.push(this.counter);//-6
	    actionObject.push(posx);//-5
	    actionObject.push(posy);//-4
	    actionObject.push(width);//-3
	    actionObject.push(height);//-2
	    actionObject.push(this.currentlayer.name);//-1
	    this.baseactionobjectList.push(actionObject);	
	    this.checkStepLayers();
	    if (doCallUpdate) this.onsharedMessage('draw',actionObject);	
  	</method>
	
	<!-- 
		adds the Image to the Layers and throws a onsharedMessage,
		this can only happen _after_ loading the Image cause you do not know its 
		width and height 
	-->
	<method name="storeTempValsAndLoadSyncList" args="objRef">
		if ($debug) Debug.write("storeTempValsAndLoadSyncList: ",objRef);
		this.syncImageRefObj = objRef;
		
		//This invokes a Method which is in the remoteWhiteboard.lzx
		this.sendCompletedObjectSyncEvent.uniqueObjectSyncName = this.syncImageRefObj.uniqueObjectSyncName;
		this.sendCompletedObjectSyncEvent.doCall();
		
		this.registerNewImage(this.syncImageRefObj.src,
			this.syncImageRefObj.x,this.syncImageRefObj.y,
			this.syncImageRefObj.width,this.syncImageRefObj.height,
			this.syncImageRefObj.baseurl,this.syncImageRefObj.fileName,
			this.syncImageRefObj.moduleName,this.syncImageRefObj.parentPath,
			this.syncImageRefObj.room,this.syncImageRefObj.domain,
			true,this.syncImageRefObj.uniqueObjectSyncName,this.getSWFDocumentStatus(),
                this.getZIndex());		
	
	</method>
	
	<!--- @keywords deprecated
  	TODO: check Recorder Modus
  	 -->
	<method name="storeTempValsAndLoadSyncListRecording" args="objRef">
		if ($debug) Debug.write("########### storeTempValsAndLoadSyncListRecording: ",objRef);
		this.syncImageRefObj = objRef;
		this.doRegisterAfterLoadingOrRecording();
		this.sendCompleteImageSync();
	</method>
	
	<method name="sendLoadNotificationImage" args="objRef" >
		if ($debug) Debug.write("sendLoadNotificationImage: ",objRef);
		this.syncImageRefObj = objRef;
		this.registerNewImage(this.syncImageRefObj.src,
			this.syncImageRefObj.x,this.syncImageRefObj.y,
			this.syncImageRefObj.width,this.syncImageRefObj.height,
			this.syncImageRefObj.baseurl,this.syncImageRefObj.fileName,
			this.syncImageRefObj.moduleName,this.syncImageRefObj.parentPath,
			this.syncImageRefObj.room,this.syncImageRefObj.domain,
			false,this.syncImageRefObj.uniqueObjectSyncName,this.getSWFDocumentStatus(),
                this.getZIndex());	
		//This invokes a Method which is in the remoteWhiteboard.lzx
		this.sendCompletedObjectSyncEvent.uniqueObjectSyncName = this.syncImageRefObj.uniqueObjectSyncName;
		this.sendCompletedObjectSyncEvent.doCall();
	</method>
    
    <!--- @keywords deprecated
    TODO: Check recorder Modus
     -->
    <method name="doRegisterAfterLoadingOrRecording">
    	if ($debug) Debug.write("########### doRegisterAfterLoadingOrRecording");
		this.imageSyncMessageText = canvas.getLabelName(this.imageSyncMessageId);
		//now send notifications to connected clients
		this.setAttribute('drawmodus','image');
		this.registerNewImage(this.syncImageRefObj.src,
		              this.syncImageRefObj.x,this.syncImageRefObj.y,
		              this.syncImageRefObj.width,this.syncImageRefObj.height,
		              this.syncImageRefObj.baseurl,this.syncImageRefObj.fileName,
		              this.syncImageRefObj.moduleName,this.syncImageRefObj.parentPath,
		              this.syncImageRefObj.room,this.syncImageRefObj.domain,
		              this.getSWFDocumentStatus(),
                      this.getZIndex());		
    </method>
	
</class>

</library>
