<?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="baseDraw" extends="view" >

	<attribute name="currentlayer" value="null" />
	<attribute name="layers" value="null" />
	
	<attribute name="redolayers" value="null" />

  	<attribute name="mx" type="number" value="0"/>
  	<attribute name="my" type="number" value="0"/>
  	<attribute name="prevx" type="number" value="0"/>
  	<attribute name="prevy" type="number" value="0"/>
  	
  	<!--- If true it will try to load the ObjectIdentifier Extension from the Server -->
  	<attribute name="isRemoteOID" value="false" type="boolean" />
  	
  	<attribute name="startx" value="0" type="number" />
  	<attribute name="starty" value="0" type="number" />
  	<attribute name="endx" value="0" type="number" />
  	<attribute name="endy" value="0" type="number" />
  	
  	<attribute name="restricted" value="false" type="boolean"/>
  	
  	<!-- This Counter just adds, it dosen't shows the absolute number of items
  		(ask this.layers.length to get the number of drawings) -->
  	<attribute name="counter" value="0" type="number" />
  	
  	<event name="onupdateScale" />
  	
  	<attribute name="showGrid" type="boolean" value="false"/>
  	<attribute name="isSnapToGrid" type="boolean" value="false"/>
	<attribute name="gridWidth" value="24" type="number" />
	
	<attribute name="copyObject" value="null"/>
	<attribute name="selectedObjects" value="null"/>
	
	<attribute name="ObjectByName" value="null" />

  	<method name="getCounter">
		//Debug.write("### getCounter :",this.counter);
		var now = new Date();
		return "_"+now.getTime();
  	</method>
  	
  	<!--
  	 not needed anymore, Issue 507
    <netRemoteCallHib name="getOID" funcname="getOID" showLoading="false"
    				  remotecontext="$once{ canvas.thishib }" > 
        <handler name="ondata" args="value">
            <![CDATA[
                //The onResult-Handler will be called be the rtmpconnection
                if($debug) Debug.write("getOID: ",value);
                parent.counter = value;
            ]]>
        </handler>   
    </netRemoteCallHib>     
     -->
	
	<method name="compareAndSetCounter" args="c">
		<![CDATA[
			if (c>this.counter) this.counter = c;
		]]>
	</method>
  	
	<attribute name="mousetracker_del" value="$once{ new LzDelegate(this, 'trackmouse' )}" />
	
	<!-- 
	This is the very basic decision what to do
	the modus pointer is only  a temp modus which is inited while draging
	a new selected object
	 -->
	<attribute name="drawmodus" value="hand" type="string" />
	
	<!-- This List holds all ActionObject
		currently paintings
				  letters -->
	<attribute name="baseactionobjectList" value="null" />
	<attribute name="baseredoactionobjectList" value="null" />
	
	<!-- This List hold a reference to all 
		Array of Drawing Action, it is needed for coping the view and undo/redo -->
	<attribute name="basetempactionobjectList" value="null" />
	
	<attribute name="basdrawredoView" value="null" />
	
	<attribute name="hasprevious" value="false" type="boolean" />
	<attribute name="hasenext" value="false" type="boolean" />
	
	<attribute name="doClearAll" value="false" type="boolean" />
	<attribute name="doClearSlide" value="false" type="boolean" />
	
	<!-- For the dragging resizeing there is a bounding box -->
	<attribute name="boundingIsActive" value="false" type="boolean" />
	<attribute name="boundingref" value="null" />
	
	<!-- For sending messages in shared modus -->
	<method name="onsharedMessage" args="action,obj" />
	
	<!-- this event must be triggered AFTER
		the nesseccary room + domain for this conferenceView is set
		-->
	<event name="onopenWhiteBoard" />
	
	<attribute name="isDragging" value="false" type="boolean"/>
	
	<attribute name="last_x" value="0" type="number" />
	<attribute name="last_y" value="0" type="number" />
	
	<!-- ############
		init
	 -->
	<handler name="oninit">
		if (this.isRemoteOID){
            //wrong reference, swagner 20.09.2008
			//this.getOID.doCall();
		}
        //Debug.write("********** this oninit: ",this);
		this.basdrawredoView = new LzView(canvas,{visible:false,y:440});
		this.layers = new Array();
		this.last_x = this.x;
		this.last_y = this.y;
		this.redolayers = new Array();
		this.baseactionobjectList = new Array();
		this.baseredoactionobjectList = new Array();
	</handler>
      
    <method name="clearSlideOnly">
    	<![CDATA[
            
            var itemsToDelete = this.getCurrentSlideAnnotations();
            
            this.onsharedMessage('clearSlide',itemsToDelete); 
            
            this.clearSlideRemote(itemsToDelete);
        ]]>
    </method>  
            
	<method name="clearAll">
		<![CDATA[
			this.onsharedMessage('clear',null);	
			this.clearRemote();
		]]>
	</method>
	
	<method name="getCurrentSlideAnnotations">
		<![CDATA[
		
		    var currentSlideNumber = -1;
		
            for (var i=0;i<this.baseactionobjectList.length;i++) {
            	
            	if (this.baseactionobjectList[i][0] == "swf") {
            		currentSlideNumber = this.baseactionobjectList[i][8];
            		break;
            	}
            	
            }
            
            var itemsToDelete = new Array();
            
            for (var i=0;i<this.baseactionobjectList.length;i++) {
            	
            	if (this.baseactionobjectList[i][0] == "ellipse" 
                        || this.baseactionobjectList[i][0] == "drawarrow"
                        || this.baseactionobjectList[i][0] == "line"
                        || this.baseactionobjectList[i][0] == "paint"
                        || this.baseactionobjectList[i][0] == "rectangle"
                        || this.baseactionobjectList[i][0] == "uline"
                        || this.baseactionobjectList[i][0] == "image"
                        || this.baseactionobjectList[i][0] == "clipart"
                        || this.baseactionobjectList[i][0] == "letter") {
                        	
                	var swfObj = this.baseactionobjectList[i][this.baseactionobjectList[i].length-7];
                	
                	if (swfObj.slide == currentSlideNumber) {
                		itemsToDelete.push(this.baseactionobjectList[i][this.baseactionobjectList[i].length-1]);
                	}
                	
                }
            	
            }
            
            return itemsToDelete;
		]]>
	</method>
	
	<method name="clearSlideRemote" args="itemsToDelete">
        <![CDATA[
        
            var indexOfItemsToDelete = new Array();
        
            for (var i=0;i<this.baseactionobjectList.length;i++) {
                
            	
            	for (var k=0;k<itemsToDelete.length;k++) {
            	
                    if (this.baseactionobjectList[i][this.baseactionobjectList[i].length-1] == itemsToDelete[k]) {
                                
                        indexOfItemsToDelete.push(i);
                        
                    }
                
            	}
                
            }
            
            for (var i=indexOfItemsToDelete.length-1;i>=0;i--) {
                
                var itemToDelete = this.baseactionobjectList[indexOfItemsToDelete[i]];
                
                var refObj = this.getObjectByName(itemToDelete[itemToDelete.length-1]);
                
                refObj.destroy();
                
                this.baseactionobjectList.splice(indexOfItemsToDelete[i],1);
                
            }   
        ]]>
    </method>        
	
	<method name="clearRemote">
        <![CDATA[
        
            if (this.boundingref!=null) this.boundingref.removeIt();
            while (this.subviews.length > 1) {
                this.subviews[1].prepareForDelete.sendEvent();
                this.subviews[1].destroy();
            }
            while (this.basdrawredoView.subviews.length > 0) {
                this.basdrawredoView.subviews[0].destroy();
            }   
            
            this.setAttribute("x",0);
            this.setAttribute("y",0);
            
            this.getDisplayObject()._xscale = 100;
            this.getDisplayObject()._yscale = 100;
            
            this.onupdateScale.sendEvent(null);
            
            parent.parent.zoombox.setWhiteboardValues(true,100);
            
            this.layers = new Array();
            this.redolayers = new Array();
            this.baseactionobjectList = new Array();
            this.baseredoactionobjectList = new Array();    
            this.checkStepLayers(); 
            this.clearDocumentsBar();
        ]]>
    </method>
	
	<method name="doAction" args="modi">
		if (modi=='saveobj'){
			if (this.sendObject) this.sendObject.sendEvent();
		} else if (modi=='loadobj'){
		
		}
	</method>
	
	<method name="setModusWithUpdate" args="modi">
		var paintToolBar = this.getPaintToolBar();
		paintToolBar.updateToolSelection(modi);
		this.setModus(modi);
	</method>
	
	<method name="setModus" args="modi">
		<![CDATA[
		  
		    if ($debug) Debug.write("setModus AAA: ",this.baseactionobjectList);
		
    		//check if previous modi has been txt, which might not be saved to the board yet
            var previousModus = this.drawmodus;
    		if ($debug) Debug.write("setModus: ",modi);
    		if (this.drawmodus=='letter'){
    			if (this.letterObjectIsActive){
    				if ($debug) Debug.write("setModus:drawtoArray",modi);
    				this.currentletterObj.drawtoArray();
    			}
    		}
    		
    		if (modi != 'print' && modi != 'plain') {
    		    this.setAttribute('drawmodus',modi);
    		} else if (modi == 'print') {
    			var my_pj = new PrintJob();
                var myResult = my_pj.start();
                
                if ($debug) Debug.write("myResult ",myResult);
                
                if (myResult) {
                	
                	var mc = this.getDisplayObject();
                	
                	// boolean to track whether addPage succeeded, change this to a counter
                    // if more than one call to addPage is possible
                    var pageAdded:Boolean = false;
                
                    // check the user's printer orientation setting
                    // and add appropriate print area to print job
                    if (my_pj.orientation == "portrait") {
                        // Here, the printArea measurements are appropriate for an 8.5" x 11"
                        // portrait page.
                        pageAdded = my_pj.addPage(mc._parent,{xMin:0,xMax:600,yMin:0,yMax:800});
                    } else {
                        // my_pj.orientation is "landscape".
                        // Now, the printArea measurements are appropriate for an 11" x 8.5"
                        // landscape page.
                        pageAdded = my_pj.addPage(mc._parent,{xMin:0,xMax:750,yMin:0,yMax:600});
                    }
                
                    // send pages from the spooler to the printer
                    if (pageAdded) {
                        my_pj.send(); 
                    }

                	
                	//if ($debug) Debug.write("mc ",mc);
                	//if ($debug) Debug.write("mc.name ",mc._name);
                	
                    //myResult = my_pj.addPage(mc, null, {printAsBitmap:true}, 1);
                    //my_pj.send();
                    delete my_pj;
                }
    		}
    		
    		if (modi=='plainSlide'){
    			this.doClearSlide = true;
                this.doClearAll = false;
    			new lz.confirmationSingle(canvas.main_content._content.inner,{
                                           labelid:1339,labeliderror:1359,
                                           refObj:this,showCheckBox:false});
    			
    			this.setAttribute('drawmodus',previousModus);
    		} else if (modi=='plainConfirm'){
    			this.doClearSlide = false;
    			this.doClearAll = true;
                new lz.confirmationSingle(canvas.main_content._content.inner,{
                                           labelid:1339,labeliderror:1340,
                                           refObj:this,showCheckBox:false});
                //this.clearAll();
                //if ($debug) Debug.write("clearAll and RESET Modus to",previousModus);
                this.setAttribute('drawmodus',previousModus);
            } else if (modi=='plain'){
                this.clearAll();
                //if ($debug) Debug.write("clearAll and RESET Modus to",previousModus);
                this.setAttribute('drawmodus',previousModus);
            } else if (modi=='hand' || modi=='letter' || modi=='triangle' 
    			|| modi=='paint' || modi=='line' || modi=='uline' || modi=='clipart' 
    			|| modi=='rectangle' || modi=='ellipse' || modi=='drawarrow'){
    			if (this.boundingref!=null) this.boundingref.removeIt();
    		}
    		if (modi=='rectangle') {
    			//Open Up Recording
    			
    		}
		]]>
	</method>
	
	<method name="sendConfirmation" args="yesno" >
		if (this.doClearSlide) {
			this.clearSlideOnly();
		} else if (this.doClearAll) {
            this.clearAll();
        }
    </method>
    
    <method name="sendNoConfirmation" args="ref">
    	//Do nothing
    </method>
	
	<method name="getModusItems" args="modi">
		<![CDATA[
		//Debug.write("getModusItems: ",modi,this.baseactionobjectList);
		if (modi=='pointer'){
			return this.baseactionobjectList;
		} else {
			var tempList = new Array();
			//Debug.write("this.baseactionobjectList: ",modi);
			for (var eg=0;eg<this.baseactionobjectList.length;eg++){
				//Debug.write("this.baseactionobjectList[eg][0]==modi",this.baseactionobjectList[eg][0],modi);
				if (this.baseactionobjectList[eg][0]==modi) {
					tempList.push(this.baseactionobjectList[eg]);
				}
			}		
			return tempList;
		}
		]]>
	</method>
	
	<method name="getObjectByName" args="objName">
		if (this[objName]) {
			return this[objName];
		}
		return null;
	</method>
	
	<method name="getBaseObjectByName" args="bName">
        <![CDATA[
            //Debug.write("getModusItems: ",modi,this.baseactionobjectList);
            //Debug.write("this.baseactionobjectList: ",modi);
            for (var eg=0;eg<this.baseactionobjectList.length;eg++){
                //Debug.write("this.baseactionobjectList[eg][0]==modi",this.baseactionobjectList[eg][0],modi);
                if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-1]==bName) {
                    return this.baseactionobjectList[eg];
                }
            }       
            return null;
        ]]>
    </method>
	
	<method name="deleteItemByName" args="objName">
        <![CDATA[
            var newA = this.deleteItemByNameSync(objName);
            if (newA[0]=='paint') newA[1] = new Array();
            this.onsharedMessage('delete',newA);    
        ]]>
    </method>
    
	<method name="deleteItemByNameSync" args="objName">
    	<![CDATA[
    	    if ($debug) Debug.write("deleteItemByNameSync :: ",objName);
    	    this[objName].prepareForDelete.sendEvent();
    	    this[objName].destroy();
            if (this.boundingref!=null) this.boundingref.removeIt();
    		
    		var pos = -1;
    		for (var eg=0;eg<this.layers.length;eg++){
    			if (this.layers[eg]['name']==objName) {
    				pos = eg;
    				//Debug.write("Found Object in Layer: ",eg);
    				this.layers[eg].prepareForDelete.sendEvent();
    				this.layers[eg].destroy();
    			}
    		}	
    		if (pos!=-1) this.layers.splice(pos, 1);
    		//get Item Position
    		pos = -1;
    		for (var eg=0;eg<this.baseactionobjectList.length;eg++){
    			if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-1]==objName) {
    				pos = eg;
    				//Debug.write("Found Object: ",eg);
    				break;
    			}
    		}
    		
    		if ($debug) Debug.write("deleteItemByNameSync Found Object: ",eg);
    		
    		var newA = this.baseactionobjectList[pos];
    		
    		for (var eg=0;eg<this.baseactionobjectList.length;eg++){
    			if (this.baseactionobjectList[eg][0]!="pointerWhiteBoard") {
		    		if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-8]>newA[newA.length-8]) {
		    				this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-8]-=1;
					}
    			}
    		}
    		
    		if (pos!=-1) this.baseactionobjectList.splice(pos, 1);
    		
    		//if ($debug) Debug.write("this.baseactionobjectList.length: ",this.baseactionobjectList.length);
    		//if ($debug) Debug.write("this.layers.length: ",this.layers.length);
    		
    		if ($debug) Debug.warn("deleteItemByName :: ",objName);
    		
    		this.checkStepLayers();
    		
    		if (newA[0] == "swf") {
                this.doDeleteFromDocumentsBar(objName);
    		}
    		
    		return newA;
    	]]>
	</method>
	
	<method name="UpdateByObject" args="objRef">
		<![CDATA[
		//Debug.write("UpdateByObject : ",objRef,objRef.name);
		var objName = objRef.name;
		//for (var eg=0;eg<this.layers.length;eg++){
		//	if (this.layers[eg]['name']==objName) {
		//		//Debug.write("Found Object in Layer: ",this.layers[eg]);
		//	}
		//}
		
		var tx = objRef.x;
        var ty = objRef.y;
        
        if(this.isSnapToGrid){   
            
            tx = Math.round(tx/this.gridWidth)*this.gridWidth;
            ty = Math.round(ty/this.gridWidth)*this.gridWidth;
            
        }
		
		for (var eg=0;eg<this.baseactionobjectList.length;eg++){
			if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-1]==objName) {
				//Debug.write("Found Object: ",this.baseactionobjectList[eg]);
				this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-5] = tx;
				this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-4] = ty;
				this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-3] = objRef.width;
				this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-2] = objRef.height;
				var newA = this.baseactionobjectList[eg];
				if (newA[0]=='paint') newA[1] = new Array();				
				this.onsharedMessage('size',newA);	
			    break;
			}
		}	
			
		]]>
	</method>
	
	<!-- ##############
		undo/redo
	 -->
	
	<method name="undoredo">
		<![CDATA[
		if (this.baseactionobjectList.length>0){
			if (this.boundingref!=null) this.boundingref.removeIt();
			var lastActionObject = this.baseactionobjectList.pop();
			this.deleteItemByNameSync(lastActionObject[lastActionObject.length-1]);
			this.onsharedMessage('undo',lastActionObject);
		}
		]]>
	</method>

	
	<method name="checkStepLayers">
		if (this.layers.length==0){
			this.setAttribute('hasprevious',false);
		} else {
			this.setAttribute('hasprevious',true);
		}
		if (this.redolayers.length==0){
			this.setAttribute('hasenext',false);
		} else {
			this.setAttribute('hasenext',true);
		}	
		//this.setAttribute('drawmodus',this.getAttribute('drawmodus'));				
	</method>
	
	<method name="onmouseoverMethod">
		
	</method>
	
	<method name="onmouseoutMethod">
        
    </method>
             
	<method name="onmousedownMethod" >
		<![CDATA[
		if ($debug) Debug.write("onmousedownMethod this.drawmodus: ",this.drawmodus);
		
		
		if(this.selectedObjects != null && this.selectedObjects.length > 0){
			for (var eg=0;eg<this.selectedObjects.length;eg++){
				var  objectToUpdate = this.getObjectByName(this.selectedObjects[eg][this.selectedObjects[eg].length-1]);
	            objectToUpdate.setAttribute('opacity', 1);
			}
		}
		
		if (canvas.ismoderator || canvas.isAllowedToDraw) {
			var knownModus = true;
			var initialBoundingIsActive = this.boundingIsActive;
			if (this.letterObjectIsActive){
				this.currentletterObj.drawtoArray();
				this.setModusWithUpdate("hand");
				knownModus = false;
			}
			
			if(this.drawmodus=="drag"){
				this.isDragging = true;
				this.dragger.apply();
			} else if(this.drawmodus=="hand"){
				this.doSetHandBodus();				
			} else if(this.drawmodus=="paint"){
				this.startPaint();
				mousetracker_del.register(lz.Idle,'onidle');
			} else if(this.drawmodus=="line"){
				this.startLine(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 			
				mousetracker_del.register(lz.Idle,'onidle');
			} else if(this.drawmodus=="uline"){
				this.startUline(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 			
				mousetracker_del.register(lz.Idle,'onidle');
			} else if(this.drawmodus=="drawarrow"){
				this.startDrawarrowline(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 			
				mousetracker_del.register(lz.Idle,'onidle');
			} else if (this.drawmodus == 'rectangle') {
				this.startRect(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 				
	            mousetracker_del.register(lz.Idle,'onidle');
	        } else if (this.drawmodus == 'ellipse') {
				this.startEllipse(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 				
	            mousetracker_del.register(lz.Idle,'onidle');
	        } else if (this.drawmodus == 'letter') {
                this.startLetter();
                this.startx = currentlayer.getMouse('x');
                this.starty = currentlayer.getMouse('y');               
                mousetracker_del.register(lz.Idle,'onidle');
            } else if (this.drawmodus == 'clipart') {
            	this.startDrawClipArt(null);
                this.startx = currentlayer.getMouse('x');
                this.starty = currentlayer.getMouse('y');  
                mousetracker_del.register(lz.Idle,'onidle');
            } else if (this.drawmodus == 'triangle') {
				this.startTriangle(null);
	  	 		this.startx = currentlayer.getMouse('x');
				this.starty = currentlayer.getMouse('y'); 				
	            mousetracker_del.register(lz.Idle,'onidle');
	        } else if (this.drawmodus == 'paste') {
	  	 		var paste_x = parent.getMouse('x');
				var paste_y = parent.getMouse('y'); 				
	            this.paste(paste_x, paste_y);
	            
	            if ($debug) Debug.write("paste mouse down ",this);
	        } else {
	        	knownModus = false;
	        	if ($debug) Debug.write("onmousedownMethod Unkown Modus ",this.drawmodus);
	        }
			if (knownModus && !initialBoundingIsActive && !this.letterObjectIsActive) {
				startTyping();
			}
        }
        ]]>
	</method>

	<method name="onmouseupMethod" >
        if ($debug) Debug.write("onmouseupMethod this.drawmodus: ",this.drawmodus);
		<![CDATA[	
	        if (canvas.ismoderator || canvas.isAllowedToDraw) {
				
				var knownModus = true;
	        	if(this.drawmodus=="drag"){
	        		this.isDragging = false;
	        		this.dragger.remove();
	        		
	        		this.setAttribute("x",Math.round(this.x));
	        		this.setAttribute("y",Math.round(this.y));
	        		
	        		if (this.last_x == this.x && this.last_x == this.x) {
	        			if ($debug) Debug.write("No Change");
	        			return;
	        		}
	        		
	        		this.last_x = this.x;
	        		this.last_y = this.y;
	        		
	        		var tArray = new Array();
		    		tArray[0] = "moveMap";
		    		tArray[1] = this.x;
		    		tArray[2] = this.y;
		    		
		    		this.onsharedMessage('moveMap',tArray);
	        		
	        	} else if(this.drawmodus=="paint"){
					this.endPaint();
					mousetracker_del.unregisterAll();
				} else if(this.drawmodus=="line"){
					this.endLine();
					mousetracker_del.unregisterAll();
				} else if(this.drawmodus=="drawarrow"){
					this.endDrawarrowline();
					mousetracker_del.unregisterAll();
				} else if(this.drawmodus=="uline"){
					this.endUline();
					mousetracker_del.unregisterAll();
				} else if(this.drawmodus=="letter"){
					this.endLetter();
					mousetracker_del.unregisterAll();
				} else if (this.drawmodus == 'rectangle') {
					this.endRect();
		        	mousetracker_del.unregisterAll();
		        } else if (this.drawmodus == 'ellipse') {
					this.endEllipse();
		        	mousetracker_del.unregisterAll();
		        } else if (this.drawmodus == 'pointer') {
		        	this.setAttribute('drawmodus','hand');
					if (this.boundingIsActive){
						this.boundingref._innerDrag.onmouseup.sendEvent();
					}
		        } else if (this.drawmodus == 'pointerWhiteboard') {
                    if ($debug) Debug.write("pointerWhiteboard set New Point ");
                    this.endPointerWhiteBoard();
                } else if(this.drawmodus=="clipart"){
                    this.endDrawClipArt();
                    mousetracker_del.unregisterAll();
                } else if (this.drawmodus == 'triangle') {
					this.endTriangle();
		        	mousetracker_del.unregisterAll();
		        } else if (this.drawmodus == 'hand') {
					this.endSelect();
		        	mousetracker_del.unregisterAll();
		        } else if (this.drawmodus == 'paste') {
		        } else {
					knownModus = true;
		        	if ($debug) Debug.write("onmouseupMethod Unkown Modus ",this.drawmodus);
		        }
				if (knownModus && !this.boundingIsActive && !this.letterObjectIsActive) {
					endTyping();
				}
	                
				this.checkStepLayers();
	        } else {
	        	if (!this.restricted) {
                    this.endPointerWhiteBoard();
	        	}
            }
		]]>
	</method>  
    
    <method name="startTyping">
		if ($debug) Debug.info("Start typing ..... ", canvas.publicSID);
		var msg = new Array();
		msg[0] = 'typingActivity';
		msg[1] = true;
		msg[2] = canvas.publicSID;
		canvas.objMessage = msg;
		canvas.thishib.sendMessage.doCall();
    </method>
    
    <method name="endTyping">
		if ($debug) Debug.info("..... end typing ", canvas.publicSID);
		var msg = new Array();
		msg[0] = 'typingActivity';
		msg[1] = false;
		msg[2] = canvas.publicSID;
		canvas.objMessage = msg;
		canvas.thishib.sendMessage.doCall();
    </method>
    
    <!--
    <handler name="onclick" args="obj">
        //Debug.write("click on whiteBoard ",obj);
    </handler>
     -->

  	<method name="trackmouse" args="item">
    	<![CDATA[

    	this.mx = currentlayer.getMouse('x');
    	this.my = currentlayer.getMouse('y');   
	    	    	
    	if (this.drawmodus=="paint"){	    	
		    if (mx != prevx || my != prevy) {
		        if (prevx == null) {
		            prevx = mx;
		        }
		        if (prevy == null) {
		            prevy = my;
		        }
	            var mmx = this.mx;
	            var mmy = this.my;
	            var px = this.prevx;
	            var py = this.prevy;

	            this.drawline(px, py, mmx, mmy);
	            this.drawlineRegisterPaint(px, py, mmx, mmy);
	            
	            this.prevx  = this.mx;
	            this.prevy = this.my;            
	        } 
	    } else if (this.drawmodus=="line"){	 
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startLine(oid_name);
			this.endx = this.mx;
			this.endy = this.my;
            this.drawline(this.startx, this.starty, this.endx, this.endy);
	    } else if (this.drawmodus=="uline"){
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startUline(oid_name);
			this.endx = this.mx;
			this.endy = this.my;
            this.drawline(this.startx, this.starty, this.endx, this.endy);
	    } else if (this.drawmodus=="drawarrow"){	
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startDrawarrowline(oid_name);
			this.endx = this.mx;
			this.endy = this.my;
	    } else if (this.drawmodus == 'rectangle') {
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startRect(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawrectangle (this.startx, this.starty, this.mx, this.my);
		} else if (this.drawmodus == 'triangle') {
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startTriangle(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawtriangle (this.startx, this.starty, this.mx, this.my);
		} else if (this.drawmodus == 'ellipse') {
			var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startEllipse(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawellipse (this.startx, this.starty, this.mx, this.my);			
		} else if (this.drawmodus == 'letter') {
			var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startLetter(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawletterBoundingBox (this.startx, this.starty, this.mx, this.my);			
		} else if (this.drawmodus=="clipart"){ 
            //var oid_name = this.currentlayer.name;
            //this.currentlayer.destroy();
            this.trackDrawClipArt();
            this.endx = this.mx;
            this.endy = this.my;
        } else if (this.drawmodus == 'copy') {
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startSelect(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawrectangle (this.startx, this.starty, this.mx, this.my);
        }else if (this.drawmodus == 'hand') {
	    	var oid_name = this.currentlayer.name;
	    	this.currentlayer.destroy();
	    	this.startSelect(oid_name);
			// stretchy rect mode
			this.endx = this.mx;
			this.endy = this.my;
			this.drawrectangle (this.startx, this.starty, this.mx, this.my);
        }
		
    	]]>
    </method>
	
	<!-- ####################
		Handmodus
	 -->
	<method name="doSetHandBodus" >
		<![CDATA[
		////Debug.write("doSetHandBodus: ");
		var objList = this.getObjectInBounds(this.getMouse('x'),this.getMouse('y'));
		if(objList.length==1){
			this.setAttribute('drawmodus','pointer');
			////Debug.write(objList[0][objList[0].length-1]);
			this.doShowObjectBounds(objList[0][objList[0].length-1]);
		} else if (objList.length>1){
			this.setAttribute('drawmodus','pointer');
			////Debug.write(objList[objList.length-1][objList[objList.length-1].length-1]);
			this.doShowObjectBounds(objList[objList.length-1][objList[objList.length-1].length-1]);
		} else {
			this.startSelect(null);
  	 		this.startx = currentlayer.getMouse('x');
			this.starty = currentlayer.getMouse('y'); 				
            mousetracker_del.register(lz.Idle,'onidle');
            if ($debug) Debug.write("this.startSelect ",this);
	            
			this.setModus("hand");
		}
		]]>
	</method>
	
    <method name="doShowObjectBounds" args="val">
    <![CDATA[
    	if (val !=null && val!=''){
	    	this.ObjectByName = this.getObjectByName(val);
	    	//FIXME: Set Corrent Value to Document Toolbar or use another var
               
            var boundingDoUpdateOnInit = true;
            if (this.ObjectByName instanceof lz.swfResourceView){
                //Debug.write("is swf Presentation");
                boundingDoUpdateOnInit=false;
            }
            
            //if ($debug) Debug.write("this.ObjectByName ",val,this.ObjectByName);
                
	    	var x = this.ObjectByName.x;
	    	var y = this.ObjectByName.y;
            //if ($debug) Debug.write("doShowObjectBounds: ",x,y);
	    	var width = this.ObjectByName.width;
	    	var height = this.ObjectByName.height;
	    	if (this.boundingref!=null)this.boundingref.removeIt();
	    	this.boundingref = new lz.boundingBoxAll(this.parent.parent._drawareaMask._drawarea,{whiteboardRef:this,
                    objRef:this.ObjectByName,x:x-200,y:y-200,width:width+400,height:height+400,
                    canBeDragged:boundingDoUpdateOnInit,canBeResized:boundingDoUpdateOnInit,
                    ex:x,ey:y,ewidth:width,eheight:height,boundingDoUpdateOnInit:boundingDoUpdateOnInit});
	    	this.setAttribute('boundingIsActive',true);
        
            //if (!boundingDoUpdateOnInit) {
            //    this.boundingref._inner._inner.setAttribute('width',this.ObjectByName._swfView.width);
            //    this.boundingref._inner._inner.setAttribute('height',this.ObjectByName._swfView.height);
            //    if ($debug) Debug.write("NEW WIDTH AND HEIGHT OF SWF ",this.ObjectByName._swfView.width,this.ObjectByName._swfView.height);
            //    this.boundingref._inner.setAttribute('visible',true);
            //    parent.parent.changeMenu(2,true);
            //    this.doUpdateDocumentToolBar();
            //} else {
            //    parent.parent.changeMenu(1,true);
            //}
             
    	}
    ]]>
    </method>   
    
    <method name="reselectShowObjectBounds" args="val">
    <![CDATA[
        if (val !=null && val!=''){
            this.ObjectByName = this.getObjectByName(val);
            //FIXME: Set Corrent Value to Document Toolbar or use another var
               
            
            //if ($debug) Debug.write("this.ObjectByName ",val,this.ObjectByName);
                
            var x = this.ObjectByName.x;
            var y = this.ObjectByName.y;
            //if ($debug) Debug.write("doShowObjectBounds: ",x,y);
            var width = this.ObjectByName.width;
            var height = this.ObjectByName.height;
            if (this.boundingref!=null)this.boundingref.removeIt();
            this.boundingref = new lz.boundingBoxAll(this.parent.parent._drawareaMask._drawarea,{
                                whiteboardRef:this,
                                objRef:this.ObjectByName,
                                x:x-200,y:y-200,
                                width:width+400,height:height+400,
                                canBeDragged:true,canBeResized:false,
                                ex:x,ey:y,ewidth:width,eheight:height,
                                boundingDoUpdateOnInit:false
                            });
            this.setAttribute('boundingIsActive',true);
        
            //if (!boundingDoUpdateOnInit) {
            //    this.boundingref._inner._inner.setAttribute('width',this.ObjectByName._swfView.width);
            //    this.boundingref._inner._inner.setAttribute('height',this.ObjectByName._swfView.height);
            //    if ($debug) Debug.write("NEW WIDTH AND HEIGHT OF SWF ",this.ObjectByName._swfView.width,this.ObjectByName._swfView.height);
            //    this.boundingref._inner.setAttribute('visible',true);
            //    parent.parent.changeMenu(2,true);
            //    this.doUpdateDocumentToolBar();
            //} else {
            //    parent.parent.changeMenu(1,true);
            //}
             
        }
    ]]>
    </method>   
	
	<method name="updateObjectBounds">
		if (this.boundingref!=null) this.boundingref.resetValues();
	</method>
	
	<method name="removeObjectBounds">
		if (this.boundingref!=null) this.boundingref.removeIt();
	</method>
    
	<method name="getObjectInBounds" args="x,y">
		<![CDATA[
		var tempList = new Array();
		if ($debug) Debug.write("getObjectInBounds this.baseactionobjectList1: ",x,y,this.baseactionobjectList);
		
		for (var eg=0;eg<this.baseactionobjectList.length;eg++){
			
			
			//if ($debug) Debug.write("c1 ",this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-5],"<",x);
            //if ($debug) Debug.write("c2 ",(this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-5]+this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-3]),">",x);
            //if ($debug) Debug.write("c3 ",this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-4],"<",y);
            //if ($debug) Debug.write("c4 ",( this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-4]+this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-2] ),">",y);
        
			
			if ( ( this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-5]<=x 
				&& ( (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-5]+this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-3]) >=x ) ) 
				&& ( this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-4]<=y 
				&& ( this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-4]+this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-2] )>=y  ) ) {
					
				if (this.baseactionobjectList[eg][0] != "mindMapNode"
				        && this.baseactionobjectList[eg][0] != "mindMapCenter")	{
    				if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-7] == null) {
        				tempList.push(this.baseactionobjectList[eg]);
    		        } else {
    		        	var swfObject = this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-7];
    		        	
    		        	if ($debug) Debug.write("getObjectInBounds :: swfObject ",swfObject.isVisible);
    		        	
    		        	if(swfObject.isVisible) {
    	        	        tempList.push(this.baseactionobjectList[eg]);
    		        	}
    		        }
		        }
				////Debug.write("found obj: ",this.baseactionobjectList[eg]);
			}
		}		
		return tempList;
		]]>
	</method>
	
	
	<method name="getZIndex">
		<![CDATA[
			if ($debug) Debug.write("getZIndex ",this.subviews.length-1);
			return this.subviews.length-1;
		]]>
	</method>
	
	
	
	<!-- ##################
		SharedModus
		action => type of action
		actionObject => necessary information to reproduce the event
		isWmlLoader => true means this object is loaded through a stored wml-file
		so do not spread any update-notifications to connected clients for each 
		object cause the file loading will make a seperate notification
	 -->
	<method name="sendWatchObject" args="action,actionObject,isWmlLoader">
		if ($debug) Debug.write("sendWatchObject: ",action,actionObject);
		<![CDATA[
		if (action=='draw' || action=='redo'){
			var lastactionObject = actionObject;
			
			//Redraw the View on the paintarea
			if (actionObject[0]=='paint'){
				this.paintactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='line'){
				this.lineactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='uline'){
				this.ulineactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='drawarrow'){
				this.drawarrowlineactionHistory(lastactionObject,this);
			} else if(action,actionObject[0]=='letter'){
				this.drawactionHistory(lastactionObject,this);
			} else if(actionObject[0]=='image'){
				//Image will send the onwmlLoaderSend later cause it has to be send
				//once the image has been loaded completely
				this.addImageToLayerHistorySynced(lastactionObject,this);
			} else if(actionObject[0]=='swf'){
				//Image will send the onwmlLoaderSend later cause it has to be send
				//once the image has been loaded completely
				this.addSWFToLayerHistorySynced(lastactionObject,this);
			} else if(actionObject[0]=='rectangle'){
				this.drawrectangleToHistory(lastactionObject,this);
			} else if(actionObject[0]=='triangle'){
				this.drawtriangleToHistory(lastactionObject,this);
			} else if(actionObject[0]=='ellipse'){
				this.drawellipseToHistory(lastactionObject,this);
			} else if(actionObject[0]=='pointerWhiteBoard'){
                this.drawPointerToHistory(lastactionObject,this);
            } else if(actionObject[0]=='flv'){
                this.drawFlvToHistory(lastactionObject,this);
            } else if(actionObject[0]=='mindMapCenter'){
                this.drawMindMapCenterToHistory(lastactionObject,this);
            } else if(actionObject[0]=='mindMapNode'){
                this.drawMindMapNodeToHistory(lastactionObject,this);
            } else if(actionObject[0]=='clipart'){
                this.drawClipArtToHistory(lastactionObject,this);
            }
			//set counter to maximum otherwise trouble in naming conventions
			//the 6th array index count from the end of each object is always the counter of the
			//object
			this.compareAndSetCounter(lastactionObject[lastactionObject.length-6]);
			this.baseactionobjectList.push(lastactionObject);
			
			//Send a notifcation for the library loader sothat it can show progress
			//and Browser does not hangUp and images can be proceed
			//only send if type ain#t image cause image will send its own one after 
			// it has been loaded completely
			if (isWmlLoader && actionObject[0]!='image' && isWmlLoader && actionObject[0]!='swf') {
				if (this.onwmlLoaderSend) this.onwmlLoaderSend.sendEvent(actionObject[0]);
			}
         
        } else if(action=='clear'){
            
            this.clearRemote();
            
        } else if(action=='clearSlide'){
            
            this.clearSlideRemote(actionObject);
            
        } else if(action=='moveMap'){
			
			this.setAttribute("x",actionObject[1]);
			this.setAttribute("y",actionObject[2]);
			
        } else if(actionObject[0]=='whiteboardObj'){
            this.doUpdateFullFitAndZoomRemote(actionObject);
		} else if(action=='flv'){
			
			this.playFLVRemote(actionObject);
			
		} else if(action=='addBrainStorming'){
            
            this.brainStormingIdeasGathering(actionObject);
        
        } else if(action=='addBrainStormingIdeaPhase2'){
            
        	//Adding Idea in Phase 2
            this.addIdeaToPhase2(actionObject);
        
        } else if(action=='deleteBrainStorming'){
			
			this.brainStormingClose(actionObject);
			
		} else if(action=='updateBrainStormingPhase'){
            
            this.brainStormingPhase2(actionObject);
            
        } else if(action=='updateBrainStormingPhase'){
            
            this.brainStormingPhase2(actionObject);
            
        } else if(action=='updatePrioBrainStormingIdea'){
            
            this.updatePrioBrainStormingIdea(actionObject);
        
        } else if(action=='updateTextBrainStormingIdeaColor'){
            
            this.updateTextBrainStormingIdeaColor(actionObject);
        
        } else if(action=='updateBrainStormingGroupName'){
            
            this.updateBrainStormingGroupName(actionObject);
            
        } else if(action=='deleteBrainStormingGroup'){
            
            this.deleteBrainStormingGroup(actionObject);
			
		} else if(action=='deleteBrainStormingIdea'){
            
            this.deleteBrainStormingIdea(actionObject);
			
		} else if(action=='addBrainStormingGroup'){
            
            this.addNewGroupRemote(actionObject,false);
            
		} else if(action=='updateGroupBrainStormingIdea'){
            
			if (actionObject[3] == "") {
                this.moveIdeaToResultListRemote(actionObject);
			} else {
                this.moveIdeaToGroupRemote(actionObject);
			}
			
		} else if(action=='delete' || action=='undo'){
			
			var lastactionObject = actionObject;	
			this.deleteItemByNameSync(lastactionObject[lastactionObject.length-1]);
			
		} else if(action=='size'){
			
			var lastactionObject = actionObject;	
			
			if (lastactionObject[0] == "clipart") {
				
				var obj = this.getObjectByName(lastactionObject[lastactionObject.length-1]);
                obj.destroy();
                
                this.drawClipArtToHistory(lastactionObject,this);
                
                for (var eg=0;eg<this.baseactionobjectList.length;eg++){
                    if (this.baseactionobjectList[eg][this.baseactionobjectList[eg].length-1]==lastactionObject[lastactionObject.length-1]) {
                        
                        //if ($debug) Debug.write("Found Object 1: ",this.baseactionobjectList[eg]);
                        
                        this.baseactionobjectList[eg] = lastactionObject;
                        
                        break;
                    }
                }   
                
                if (this.boundingIsActive) {
                    this.reselectShowObjectBounds(lastactionObject[lastactionObject.length-1]);
                }
				
			} else {
			
    			var obj = this.getObjectByName(lastactionObject[lastactionObject.length-1]);
    			
    			if ($debug) Debug.write("Set Size for Object ",obj);
    			obj.setAttribute('x',lastactionObject[lastactionObject.length-5]);
    			obj.setAttribute('y',lastactionObject[lastactionObject.length-4]);
    			obj.setAttribute('width',lastactionObject[lastactionObject.length-3]);
    			obj.setAttribute('height',lastactionObject[lastactionObject.length-2]);
    			
    			this.updateBaseObjectByName(lastactionObject[lastactionObject.length-1],
    			                         lastactionObject[lastactionObject.length-5],
    			                         lastactionObject[lastactionObject.length-4],
    			                         lastactionObject[lastactionObject.length-3],
    			                         lastactionObject[lastactionObject.length-2]);
    			                         
    			//if ($debug) Debug.write("BaseObject List ?? ",this.baseactionobjectList);
    			
                if (this.boundingIsActive) {
                	this.boundingref.sendRemoteUpdate(obj)
                }
            
			}
			                         
		} else if (action=="loadwml"){
			//Debug.write(actionObject,actionObject["wmlfileName"],actionObject["wmlroom"],actionObject["wmldomain"]);
			this.remoteWmlLoader(actionObject["wmlfileName"],actionObject["wmlroom"],actionObject["wmldomain"]);
		} else if (action=="editText"){
            this.editTextByHistory(actionObject,this);
		}else if (action=="editTextMindMapFontColor") {
            this.editTextMindMapFontColor(actionObject,this);
        } else if (action=="editTextMindMapColor"){
            this.editTextMindMapColor(actionObject,this);   
        } else if (action=="editTextMindMapNode"){
            this.editTextMindMapNode(actionObject,this);
        } else if (action=="sendItemToFront"){
            this.bringItemToFrontByName(actionObject[1]);
        } else if (action=="initgetVars"){
			//Debug.write("initUser isMod ",canvas.ismoderator,actionObject);
			if (canvas.ismoderator){
				//Debug.write("send all whiteBoard objects to new user");
				var obj = new Array();
			    obj[0] = 'whiteboard';
			    obj[1] = 'inituser';
			    obj[2] = this.baseactionobjectList;
				this.oninitUser(actionObject,obj);
			}
		} else if (action=="swf"){
			this.remoteObjectUpdate(actionObject);	
		}
		]]>
	</method>
	
	
	<method name="updateBaseObjectByName" args="tName,x,y,width,height">
		<![CDATA[
		
		    
		
            for (var i=0;i<this.baseactionobjectList.length;i++) {
            	
            	if (this.baseactionobjectList[i][this.baseactionobjectList[i].length-1] == tName) {
            		this.baseactionobjectList[i][this.baseactionobjectList[i].length-5] = x;
            		this.baseactionobjectList[i][this.baseactionobjectList[i].length-4] = y;
            		this.baseactionobjectList[i][this.baseactionobjectList[i].length-3] = width;
            		this.baseactionobjectList[i][this.baseactionobjectList[i].length-2] = height;
            		return;
            	}
            	
            }
		    
            
            if ($debug) Debug.warn("Could Not Find Item on List ",tName);
		]]>
	</method>
	
	<method name="sendRecordedObject" args="action,actionObject,isWmlLoader">
		//Debug.write("sendWatchObject: ",action,actionObject);
		<![CDATA[
		if (action=='draw' || action=='redo'){
			var lastactionObject = actionObject;
			
			//Redraw the View on the paintarea
			if (actionObject[0]=='paint'){
				this.paintactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='line'){
				this.lineactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='uline'){
				this.ulineactionHistory(lastactionObject,this);
			} else if (actionObject[0]=='drawarrow'){
				this.drawarrowlineactionHistory(lastactionObject,this);
			} else if(action,actionObject[0]=='letter'){
				this.drawactionHistory(lastactionObject,this);
			} else if(actionObject[0]=='image'){
				//Image will send the onwmlLoaderSend later cause it has to be send
				//once the image has been loaded completely
				this.addImageToLayerHistoryRecorded(lastactionObject,this,isWmlLoader);
			} else if(actionObject[0]=='swf'){
				//Image will send the onwmlLoaderSend later cause it has to be send
				//once the image has been loaded completely
				this.addSWFToLayerHistoryRecording(lastactionObject,this,isWmlLoader);
			} else if(actionObject[0]=='rectangle'){
				this.drawrectangleToHistory(lastactionObject,this);
			} else if(actionObject[0]=='ellipse'){
				this.drawellipseToHistory(lastactionObject,this);
			}
			//set counter to maximum otherwise trouble in naming conventions
			//the 6th array index count from the end of each object is always the counter of the
			//object
			this.compareAndSetCounter(lastactionObject[lastactionObject.length-6]);
			this.baseactionobjectList.push(lastactionObject);
			
			//Send a notifcation for the library loader sothat it can show progress
			//and Browser does not hangUp and images can be proceed
			//only send if type ain#t image cause image will send its own one after 
			// it has been loaded completely
			if (isWmlLoader && actionObject[0]!='image' && isWmlLoader && actionObject[0]!='swf') {
				if (this.onwmlLoaderSend) this.onwmlLoaderSend.sendEvent(actionObject[0]);
			}
            
		} else if(action=='clear'){
			this.clearAll();
		} else if(action=='delete' || action=='undo'){
			var lastactionObject = actionObject;	
			var obj = this.getObjectByName(lastactionObject[lastactionObject.length-1]);
			obj.destroy();
		} else if(action=='size'){
			var lastactionObject = actionObject;	
			var obj = this.getObjectByName(lastactionObject[lastactionObject.length-1]);
			obj.setAttribute('x',lastactionObject[lastactionObject.length-5]);
			obj.setAttribute('y',lastactionObject[lastactionObject.length-4]);
			obj.setAttribute('width',lastactionObject[lastactionObject.length-3]);
			obj.setAttribute('height',lastactionObject[lastactionObject.length-2]);
		} else if (action=="loadwml"){
			//Debug.write(actionObject,actionObject["wmlfileName"],actionObject["wmlroom"],actionObject["wmldomain"]);
			this.remoteWmlLoaderRecording(actionObject["wmlfileName"],actionObject["wmlroom"],actionObject["wmldomain"]);
		} else if (action=="editText"){
			this.editTextByHistory(actionObject,this);
		} else if (action=="initgetVars"){
			//Debug.write("initUser isMod ",canvas.ismoderator,actionObject);
			if (canvas.ismoderator){
				//Debug.write("send all whiteBoard objects to new user");
				var obj = new Array();
			    obj[0] = 'whiteboard';
			    obj[1] = 'inituser';
			    obj[2] = this.baseactionobjectList;
				this.oninitUser(actionObject,obj);
			}
		} else if (action=="swf"){
			this.remoteObjectUpdate(actionObject);	
		}
		]]>
	</method>
	
  	<method name="getSWFDocumentStatus">
  		<![CDATA[
  		
  		    for (var i=0;i<this.baseactionobjectList.length;i++) {
  		    	
  		    	if (this.baseactionobjectList[i][0] == "swf") {
  		    		
  		    		var tSWF = new Object();
  		    		
  		    		tSWF.name = this.baseactionobjectList[i][this.baseactionobjectList[i].length-1];
  		    		tSWF.slide = this.baseactionobjectList[i][8];
  		    		tSWF.isVisible = true;
  		    		
  		    		return tSWF;
  		    	}
  		    	
  		    }
  		    
  		    return null;
  		]]>
  	</method>

    <method name="checkSWFDocumentStatus" args="swfObj">
        <![CDATA[
        
            if (swfObj != null) {
        
                var swfBaseObj = this.getBaseObjectByName(swfObj.name);
                
                if (swfBaseObj != null) {
            
                    if (swfObj.slide == swfBaseObj[8]) {
                    	return true;
                    } else {
                    	return false;
                    }
                    
                }
            
            }
            
            return true;
        ]]>
    </method>

    <method name="doSWFDocumentStatus" args="refObj,swfObj">
        <![CDATA[
        
            if (swfObj != null) {
        
                if (swfObj.isVisible) {
                	
                	refObj.setAttribute("visibility","visible");
                	
                } else {
                	
                	refObj.setAttribute("visibility","hidden");
                	
                }
            
            } else {
            	
            	refObj.setAttribute("visibility","visible");
            	
            }
            
        ]]>
    </method>
    
    <method name="updateObjectsToSlideNumber" args="baseObject">
    	<![CDATA[
    	
            var baseObjectName = baseObject[baseObject.length-1];
            var slidesNumber = baseObject[8];
    	   
            if ($debug) Debug.write("updateObjectsToSlideNumber :: ",baseObjectName,slidesNumber)
    	
            for (var i=0;i<this.baseactionobjectList.length;i++) {
    	   	
                if (this.baseactionobjectList[i][0] == "ellipse" 
                        || this.baseactionobjectList[i][0] == "drawarrow"
                        || this.baseactionobjectList[i][0] == "line"
                        || this.baseactionobjectList[i][0] == "paint"
                        || this.baseactionobjectList[i][0] == "rectangle"
                        || this.baseactionobjectList[i][0] == "uline"
                        || this.baseactionobjectList[i][0] == "image"
                        || this.baseactionobjectList[i][0] == "clipart"
                        || this.baseactionobjectList[i][0] == "letter") {
                	
                	var swfObj = this.baseactionobjectList[i][this.baseactionobjectList[i].length-7];
                	if ($debug) Debug.write("swfObj :: ",swfObj);
                	
                	if (swfObj != null) {
                		
                		if (swfObj.name == baseObjectName) {
                			
                			if (swfObj.slide == slidesNumber) {
                				
                				swfObj.isVisible = true;
                				
                				this.baseactionobjectList[i][this.baseactionobjectList[i].length-7] = swfObj; 
                				
                				this[this.baseactionobjectList[i][this.baseactionobjectList[i].length-1]].setAttribute("visibility","visible");
                				
                			} else {
                				
                				swfObj.isVisible = false;
                				
                				this.baseactionobjectList[i][this.baseactionobjectList[i].length-7] = swfObj; 
                				
                				this[this.baseactionobjectList[i][this.baseactionobjectList[i].length-1]].setAttribute("visibility","hidden");
                				
                			}
                			
                		}
                		
                	}
                	
                }
    	   	
            }
    	
    	]]>
    </method>
    
    <method name="updateAllObjectsToSlideNumber">
        <![CDATA[
        
            if ($debug) Debug.write(" :: updateAllObjectsToSlideNumber :: ")
        
            for (var i=0;i<this.baseactionobjectList.length;i++) {
            
                if (this.baseactionobjectList[i][0] == "ellipse" 
                        || this.baseactionobjectList[i][0] == "drawarrow"
                        || this.baseactionobjectList[i][0] == "line"
                        || this.baseactionobjectList[i][0] == "paint"
                        || this.baseactionobjectList[i][0] == "rectangle"
                        || this.baseactionobjectList[i][0] == "uline"
                        || this.baseactionobjectList[i][0] == "image"
                        || this.baseactionobjectList[i][0] == "letter") {
                    
                    var swfObj = this.baseactionobjectList[i][this.baseactionobjectList[i].length-7];
                    if ($debug) Debug.write("swfObj :: ",swfObj);
                    
                    if (swfObj != null) {
                        
                            
                        if (swfObj.isVisible) {
                            
                            this[this.baseactionobjectList[i][this.baseactionobjectList[i].length-1]].setAttribute("visibility","visible");
                            
                        } else {
                            
                            this[this.baseactionobjectList[i][this.baseactionobjectList[i].length-1]].setAttribute("visibility","hidden");
                            
                        }
                            
                        
                    }
                    
                }
            
            }
        
        ]]>
    </method>

    <dragstate name="dragger"/>
    
</class>

</library>
