<?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: ",canvas.getUrl());
  		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>
