<?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="baseDrawSave" extends="baseDrawImage" >
	
	<!-- saveing a file to a wml Object -->
	<attribute name="savefileName" value="savefileName1" type="string" />
	<attribute name="fileData" value="null" />
	<attribute name="savefileDataWinRef" value="null" />
	
	<!-- loading a file from a wml Object -->
	<attribute name="loadfileData" value="null" />
	<attribute name="loadfileDataIndex" value="0" type="number" />
	<attribute name="loadfileDataWinRef" value="null" />
	<attribute name="loadObjectTimer" value="null" />
	<attribute name="loadmessageId" value="206" type="number" />
	<attribute name="syncmessageId" value="207" type="number" />
	<attribute name="_loadmessageTxt" value="" type="string" />
	<!-- loading a file from wml synchronize with remote Users -->
	<attribute name="_loadingUsers" value="null" />
	<attribute name="wmlfileName" value="" type="string" />
	<attribute name="wmlroom" value="" type="string" />
	<attribute name="wmldomain" value="" type="string" />
	<attribute name="wmlspreadNews" value="false" type="boolean" />
	<attribute name="wmlLoadingCompleteMessage" value="null" />
	<attribute name="synccheckTime" value="1000" type="number" />
	
	<!-- loading all stage objects on init -->
	<attribute name="isInitLoader" value="false" type="boolean" />
    
    <!-- Export Image Type -->
    <attribute name="exportType" value="svg" type="string" />
    
	<!-- Vars for storing screenshot
		removed cause of performance and 
		no php backend availible anymore -->		
    <attribute name="MCRef" value="null" />
    
    <attribute name="pixelArray" value="null" />
    <attribute name="snap" value="null" />
    <attribute name="bpData" value="null" />
    <attribute name="MatrixValue" value="null" />
    
    <attribute name="w" value="0" type="number" />
    <attribute name="h" value="0" type="number" />
    
    <attribute name="a" value="0" type="number" />
    
    <attribute name="pixel_del" value="$once{ new LzDelegate(this, 'buildPixelArray' )}" />
    
    <attribute name="sendpictureName" value="snapchot.jpg" type="string" />
    
    <attribute name="isSendPartArray" value="true" type="boolean" />
    
    <attribute name="isRecordingLoad" value="false" type="boolean" />
    <attribute name="isinitRecordingLoad" value="false" type="boolean" />
	
	<!-- Start and Stop Event will be thrown by the loading process -->
	<event name="onwmlloadStart" />
	<event name="onwmlloadStop" />
    
    <!-- Images will be send in packages 
    	so timeout is workaround
     -->
    <attribute name="sendPartURL" value="http://www.webbase-design.de/dokeos/videoconference/createimagefrombitmap.php" type="string" />
    
    <!-- create Image from whole Array
    	Large Images will not be rendered correctly here cause
    	there can be a timeout -->
    <attribute name="sendURL" value="http://www.webbase-design.de/dokeos/videoconference/createimagefrombitmap.php" type="string" />
    
    <event name="onprogress" />
    
    <method name="catchSnapshot">
        <![CDATA[
        this.MCRef = this.getDisplayObject();
        //Debug.write("this.MCRef: ",this.MCRef);
        this.snap = new flash.display.BitmapData(this.width, this.height, false, 0 );
        
        //Matrix to scale the new image
        this.MatrixValue = new flash.geom.Matrix();
        this.MatrixValue.scale(1, 1);
        //Copy video image
        this.snap.draw(this.MCRef,  this.MatrixValue); 
        
        this.bpData = this.snap.getPixels(this.snap.rectangle);
        
        this.w = this.width;
        this.h = this.height;
        this.a = 0;
        this.pixelArray = new Array();
        
        //pixel_del.register(lz.Idle,'onidle');
        this.saveAsImage.doCall();
        ]]>
    </method>
    
	  	<netRemoteCallHib name="saveAsImage" funcname="fileservice.saveAsImage" remotecontext="$once{ canvas.thishib }" >   
	  		<netparam><method name="getValue">return parent.parent.bpData;</method></netparam>
	        <handler name="ondata" args="value">	
	        	//Debug.write("  saveAsImage: ",value);              	          				
	        </handler>	
	  	</netRemoteCallHib>     
    
    <method name="buildPixelArray" args="item">
        <![CDATA[
        
        for(var b=0; b<=this.h; b++){
            var tmp = this.snap.getPixel(a, b);
            this.pixelArray.push(tmp.toString(16));
        }
        var perc =  Math.round((this.a*100)/this.w);
        if (this.onprogress) this.onprogress.sendEvent(perc);            
        this.a++
        if(this.a>this.w){ 
            //Finish capturing
            if (this.isSendPartArray){
            	this.sendPHPData(this.pixelArray, this.h, this.w);
            } else {
	            this.sendPHPData(this.pixelArray, this.h, this.w);
	        }
            //free memory
            this.snap.dispose();
            pixel_del.unregisterAll();
        }
        
        ]]>
    </method>
    
    <method name="sendPHPData" args="pix,pixH,pixW">
        //Debug.write("### sendPHPData: ",pix,pixH,pixW);
        <![CDATA[
	        //Create the LoadVars object and pass data to PHP script
	        var output = new LoadVars();
	        output.img = pix.toString();
	        output.height = pixH;
	        output.width = pixW;
	        //The page (and this movie itself) should be in a server to work
	        output.send(this.sendURL, "output", "POST");
        ]]> 
    </method>
	
	<!-- saving all object on whiteBoard as wml-file -->
	
	<handler name="sendObject">
		if ($debug) Debug.write("sendObject doSave: ",this.baseactionobjectList);
		this.fileData = this.baseactionobjectList;
		this.savefileDataWinRef = new lz.saveAsWmlWindow(canvas.main_content._content.inner,{
                                                refObj:this});
	</handler>
	
	<method name="confirmSaveAsObject" args="fileName" >
		this.savefileName = fileName;
		this.saveAsObject.doCall();
	</method>
    
  	<netRemoteCallHib name="saveAsObject" funcname="fileservice.saveAsObject" remotecontext="$once{ canvas.thishib }" >   
  		<netparam><method name="getValue"> return canvas.sessionId; </method></netparam>
		<netparam><method name="getValue">return hib.currentroomid;</method></netparam>        				  
		<netparam><method name="getValue"> return parent.parent.savefileName; </method></netparam>
		<netparam><method name="getValue"> return parent.parent.fileData;</method></netparam>
        <handler name="ondata" args="value">	
			<![CDATA[
				if ($debug) Debug.write("  saveAsImage: ",value);   
			    if (value>0){
					parent.savefileDataWinRef.close();
					canvas.currentFileExplorer.loadFiles();
				} else {
					new lz.rpcErrorDialog(canvas.main_content._content.inner,{errorid:value});
				}
			]]>  	          				
        </handler>	
  	</netRemoteCallHib>  
        
    <method name="confirmSaveAsImageTypeExport" args="fileName,type">
        this.savefileName = fileName;
        this.exportType = type;
        this.fileData = this.baseactionobjectList;
        this.addPrintList.doCall();
    </method> 
     
    <method name="confirmSaveAsImageExport" args="fileName">
        this.savefileName = fileName;
        this.exportType = "svg";
        this.fileData = this.baseactionobjectList;
        this.addPrintList.doCall();
    </method>	
    
        <netRemoteCallHib name="addPrintList" funcname="printservice.addPrintList" remotecontext="$once{ canvas.thishib }" > 
          
            <netparam><method name="getValue">return canvas.sessionId; </method></netparam>
            <!--             
            <netparam><method name="getValue">return parent.parent.savefileName; </method></netparam>
             -->
            <netparam><method name="getValue">return parent.parent.fileData;</method></netparam>
            <netparam><method name="getValue">return parent.parent.width;</method></netparam>
            <netparam><method name="getValue">return parent.parent.height;</method></netparam>
            <handler name="ondata" args="value">    
                <![CDATA[
                    if ($debug) Debug.write("addPrintList: ",value);   
                    var downloadurl = canvas.protocol + '://'+canvas.rtmphostlocal+':'+canvas.red5httpport+canvas.httpRootKey+'ExportToImage?' +
					                    'fileName=' + parent.savefileName +
					                    '&hash='+value + 
                                        '&exportType=' + parent.exportType +
					                    '&sid='+canvas.sessionId;
                                        
                    lz.Browser.loadURL(downloadurl,"_BLANK");
                ]]>                             
            </handler>  
        </netRemoteCallHib>     
    
	<!-- Loading the wml Object from the library 
		invoked wether directly (spreadNews=true) from the library
		or by remoteClient (Moderator spreadNews=false)-->
	
    <method name="loadwmlObjectToStage" args="loadObject,fileName,room,domain,spreadNews,isInitLoader">
        
        //Debug.write("loadwmlObjectToStage: ",loadObject,fileName,room,domain,spreadNews,isInitLoader);
		<![CDATA[
		if (loadObject!=null && loadObject.length>0){
			
			this.wmlfileName = fileName;
			this.wmlroom = room;
			this.wmldomain = domain;
			this.wmlspreadNews = spreadNews;
			this.isInitLoader = isInitLoader;
			
			this.loadfileData = loadObject;
			this.loadfileDataIndex = -1;
			if (this.onwmlloadStart) this.onwmlloadStart.sendEvent();
			this._loadmessageTxt = canvas.getLabelName(this.loadmessageId);
			this.loadfileDataWinRef = new lz.loadWhiteboardWindow(canvas.main_content._content.inner,{refObj:this});
			
			if (this.wmlspreadNews){
				//get remotely connected users sothat we can trigger event when everyBody has synchronized loading
				this.getClientListScope.doCall();
			} else {
				this.loadObjectTimer = new LzDelegate( this, "loadNextObjectFromList" );
				lz.Timer.addTimer( this.loadObjectTimer, 50 );
			}
		//check if this is syncing cause if init of new user
		//no init-object so load directly
		} else if (isInitLoader){
			//check if this is conferenceView or audienceView modus
			if (canvas.thishib.modus == "conference"){
				if ($debug) Debug.write("############## showDevicePopUp 1 xyz");
				canvas._videocontainer._videoviewcontent.showDevicePopUp(false);
			} else if(canvas.thishib.modus == "audience"){
				//check in audince modus if this user is the current moderator
				//this users cannot be the moderator cause he has downloaded
				//some objects from teh current moderator
				//Debug.error("WARNING 1 - ERROR - this users cannot be the moderator cause he has downloaded some objects from teh current moderator");
			}

		}
		]]>	
	</method>
	
	<!-- get list of clients before loading wml-file-objects cause
		we have to show the sync process
		-->
    <netRemoteCallHib name="getClientListScope" funcname="getClientListScope" remotecontext="$once{ canvas.thishib }" >          
        <handler name="ondata" args="value">
        	<![CDATA[
				//The onResult-Handler will be called by the rtmpconnection
				//Debug.write("getClientListScope wml and sync Instance: ",value);
				parent._loadingUsers = new Array();
				for (var eg in value){
					if (canvas.streamid != value[eg].streamid){
						////Debug.write("parent._loadingUsers value eg ",eg,value[eg]);
						parent._loadingUsers.push(value[eg]);
					}
				}
				if (!parent.isInitLoader) {
				    parent.notifyClient();			
				} else {
				    parent.notifyClientInitSyncing();
				}
				//it is necessary to use lz.Timer cause i want to make status updates
				//after each loaded object
                //Debug.write("loadNextObjectFromList 2 this.loadObjectTimer");
				this.parent.loadObjectTimer = new LzDelegate( this.parent, "loadNextObjectFromList" );
				lz.Timer.addTimer( this.parent.loadObjectTimer, 50 );	
            ]]>
        </handler>   
    </netRemoteCallHib>
	
	<!-- send notification to all clients that a
		 wml-file has been loaded -->	
	<method name="notifyClient">
		var obj = new Array();
		obj["wmlfileName"] = this.wmlfileName;
		obj["wmlroom"] = this.wmlroom;
		obj["wmldomain"] = this.wmldomain;
		obj["wmlspreadNews"] = this.wmlspreadNews;
		
		var tempSendArray = new Array ();
		tempSendArray[0] = 'whiteboard';
		tempSendArray[1] = new Date();
		////Debug.write("Setting Message");
		tempSendArray[2] = "loadwml";
		tempSendArray[3] = obj;
		
		canvas.objWhiteboard = tempSendArray;
        hib.sendVars.doCall();
	</method>
	
	<method name="notifyClientInitSyncing">
		this.wmlLoadingCompleteMessage = new Array();
		this.wmlLoadingCompleteMessage[0] = "whiteboard";
		this.wmlLoadingCompleteMessage[1] = "syncinitLoader";
		this.wmlLoadingCompleteMessage[2] = this.wmlfileName;
		this.sendMessageWithClient.doCall();
	</method>
	
	<!-- invoked the loading of a wml-file by the moderator -->
	<method name="remoteWmlLoader" args="fileName,room,domain">
		this.loadWmlObject.String3 = room;
		this.loadWmlObject.String1 = fileName;
		this.loadWmlObject.doCall();
	</method>
	
	<!-- invoked the loading of a wml-file by the moderator -->
	<method name="remoteWmlLoaderRecording" args="fileName,room,domain">
		this.isRecordingLoad = true;
		this.loadWmlObject.String3 = room;
		this.loadWmlObject.String1 = fileName;
		this.loadWmlObject.doCall();
	</method>
	
		<!-- load the objects of that wml file -->
	  	<netRemoteCallHib name="loadWmlObject" funcname="fileservice.loadWmlObject" remotecontext="$once{ canvas.thishib }" >   
			<netparam><method name="getValue"> return canvas.sessionId; </method></netparam>
			<netparam><method name="getValue">return parent.String3;</method></netparam>        	
			  <netparam><method name="getValue">return parent.String1;</method></netparam>
	        <handler name="ondata" args="value">	
				<![CDATA[
					////Debug.write("  loadWmlObject ",value); 
					parent.loadwmlObjectToStage(value,this.String1,hib.currentroomid,hib.conferencedomain,false);
				]]>       	     				
	        </handler>	
	  	</netRemoteCallHib> 
	
	<!-- this event gets triggered when a new user arrives and
		start loading the init-objects
		-->
	<method name="remoteSyncLoader">
		this.loadfileDataWinRef = new lz.loadWhiteboardWindow(canvas.main_content._content.inner,{refObj:this});
		this._loadmessageTxt = canvas.getLabelName(this.syncmessageId);
	    this.loadfileDataWinRef.setMessage(this._loadmessageTxt);
	</method>
			
	
	<!-- gets triggered once one object of the wml-file has been added completely to the
		whiteborad -->
	
	<handler name="onwmlLoaderSend" args="type">
		//Debug.write("loadNextObjectFromList 3 this.loadObjectTimer ",type);
		this.loadObjectTimer = new LzDelegate( this, "loadNextObjectFromList" );
		lz.Timer.addTimer( this.loadObjectTimer, 50 );
	</handler>
	
	<!-- invoke by lz.Timer
		checks if object is loaded completely once it is completely loaded it checks wether
		the process was invoked by moderator, so this is a remoteClient or this client is 
		really the moderator (this.wmlspreadNews=true)
		if it ain't the mod it just throws a message to moderator and waits untill the moderator
		spreads a message that all clients did succeed in loading the wml-file-objects
		-->
	<method name="loadNextObjectFromList">
		<![CDATA[
			if ($debug) Debug.write("loadNextObjectFromList");
			this.loadfileDataIndex++;
			if (this.loadfileDataIndex<this.loadfileData.length){
				var txt = (this.loadfileDataIndex+1)+'/'+this.loadfileData.length+' '+this._loadmessageTxt;
				this.loadfileDataWinRef.setMessage(txt);
				////Debug.write("  loadObject[this.loadfileDataIndex] ",this.loadfileData[this.loadfileDataIndex]);
				this.sendWatchObject('draw',this.loadfileData[this.loadfileDataIndex],true);
			} else {
				////Debug.write("this.loadfileDataIndex complete",this.loadfileDataIndex);
				this._loadmessageTxt = canvas.getLabelName(this.syncmessageId);
			    this.loadfileDataWinRef.setMessage(this._loadmessageTxt);
				if (this.onwmlloadStop) this.onwmlloadStop.sendEvent();
				if (this.isRecordingLoad || this.isinitRecordingLoad) {
					this.sendCompleteWmlSync(null);
				} else if (!this.wmlspreadNews){
					this.wmlloadingComplete();
				} else {
                    //Debug.write("loadNextObjectFromList this.startWmlsyncCheck");
					this.startWmlsyncCheck();
				}
			}
		]]>
	</method>
	
	<!-- remoteClient will send a notification to moderator 
		that he has completed loading -->
	<method name="wmlloadingComplete">
		if ($debug) Debug.warn("?? wmlloadingComplete ??");
		new lz.errorPopup(canvas,{error:"?? wmlloadingComplete ??"});
		this.wmlLoadingCompleteMessage = new Array();
		this.wmlLoadingCompleteMessage[0] = "whiteboard";
		this.wmlLoadingCompleteMessage[1] = "wmlloadcomplete";
		this.wmlLoadingCompleteMessage[2] = this.wmlfileName;
		this.sendMessageWithClient.doCall();
	</method>
	
	<!-- sending messages/notifications of sync process -->
	<netRemoteCallHib name="sendMessageWithClient" funcname="sendMessageWithClient" remotecontext="$once{ canvas.thishib }" >   
		<netparam name="vars"><method name="getValue">return parent.parent.wmlLoadingCompleteMessage;</method></netparam>
		<handler name="ondata" args="value">
			<![CDATA[
			//The onResult-Handler will be called be the rtmpconnection
			////Debug.write("getValue : ",value);
			
			]]>
		</handler>   
	</netRemoteCallHib> 	
	
	<!-- after loading the objects check if all connected clients of that conference
		have loaded the file completely, check it every 1 seconds -->
	<method name="startWmlsyncCheck">
		<![CDATA[
            if ($debug) Debug.write("startWmlsyncCheck: ");
			if (this._loadingUsers.length==0 || this.isInitLoader){
                //Debug.write("wmlsyncComplete ");
				this.wmlsyncComplete();
			} else {
				var txt = this._loadmessageTxt+' '+this._loadingUsers.length;
				this.loadfileDataWinRef.setMessage(txt);
				this.loadObjectTimer = new LzDelegate( this, "startWmlsyncCheck" );
				lz.Timer.addTimer( this.loadObjectTimer, this.synccheckTime );
			}
		]]>
	</method>
	
	<!-- the sync process is complete, 
		remove all loading windows from connected clients -->
	<method name="wmlsyncComplete">
		//set modus to hand so users can directly interact with object's
		this.setModus('hand');	
		this.wmlLoadingCompleteMessage = new Array();
		this.wmlLoadingCompleteMessage[0] = "whiteboard";
		this.wmlLoadingCompleteMessage[1] = "wmlsynccomplete";
		this.wmlLoadingCompleteMessage[2] = this.wmlfileName;
		this.sendMessageWithClient.doCall();
	</method>
	
	<!-- invoked by remote client once he has completely loaded the wml-file 
		remote client is waiting/still shows loading window untill all clients have 
		completely loaded the object/moderator sends "synccomplete" message -->
	<method name="sendCompleteWmlLoadedRClient" args="client">
		<![CDATA[
			//detect self messageing
			if (client.streamid!=canvas.streamid){
				//remove client from sync list
				for (var i=0;i<this._loadingUsers.length;i++){
					if (this._loadingUsers[i].streamid==client.streamid){
						////Debug.write("deleteing client from list: ",this._loadingUsers[i].streamid);
						this._loadingUsers.splice(i,1);
					}
				}
			}
		]]>
	</method>
	
	<!-- invoked remotely by Moderator
		all clients have succeed in loading the wml-file-objects
		loading win can be closed
		Alert: This notification will be send from Moderator and received by ALL clients INCLUDING
		the moderator, so the moderator needs no extra command *close* for loading bar cause he
		gets its own *sync* complete nofification
		 -->
	<method name="sendCompleteWmlSync" args="client">
		if ($debug) Debug.write("sendCompleteWmlSync: ",client);
		this.loadfileDataWinRef.close();
		if (this.isinitRecordingLoad){
			this.isinitRecordingLoad = false;
			if ($debug) Debug.write("this.isinitRecordingLoad",this);
			if ($debug) Debug.write(this.parent.parent.parent.parent);
			this.parent.parent.parent.parent.timeLineAction();
		}
		//Debug.write("this.loadfileDataWinRef closed: ",this.loadfileDataWinRef);
		//check if this is syncing cause if init of new user
		if (this.isInitLoader){
			//check if this is conferenceView or audienceView modus
			if (canvas.thishib.modus == "conference"){
				if ($debug) Debug.write("############## showDevicePopUp 2 xyz");
				canvas._videocontainer._videoviewcontent.showDevicePopUp(false);
			} else if(canvas.thishib.modus == "audience"){
				//check in audince modus if this user is the current moderator
				//this users cannot be the moderator cause he has downloaded
				//some objects from teh current moderator
				if ($debug) Debug.warn("WARNING 2 - ERROR - this users cannot be the moderator cause he has downloaded some objects from teh current moderator");
			}
		}
	</method>
</class>

</library>
