<?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 newWhiteBoard
    
    
    @keywords deprecated
    
 -->


<class name="fixedFileExplorerWhiteBoard" extends="view" showhandcursor="false">
    
    <attribute name="baseurl" value="" type="string" />
    <attribute name="fileName" value="" type="string" />
    <attribute name="moduleName" value="" type="string" />
    <attribute name="parentPath" value="" type="string" />
    <attribute name="room" value="" type="string" />
    <attribute name="domain" value="" type="string" />
    
    <attribute name="downloadurl" value="" type="string" />
    <attribute name="iamgex" value="" type="string" />
    <attribute name="imagey" value="" type="string" />
    
    <attribute name="restricted" value="false" type="boolean" />
    
    <event name="onsharedMessage" />
    
    <attribute name="sendObject" value="null" />
    <attribute name="sendObjectToClientID" value="0" type="number"  />
    
    <attribute name="confirmdialog" value="null" />
    
    <attribute name="documentmenuIsInited" value="false" type="boolean" />
    
    <handler name="oninit">
        if ($debug) Debug.info("Init Whiteboard ",this.restricted);
    </handler>

    <handler name="ondestroy">
		//if ($debug) Debug.write("############## fixedFileExplorerWhiteBoard::ondestroy : ", this);
		this._drawareaMask._drawarea.clearRemote();
    </handler>

    <method name="sendConfirmation" args="yesno,askagain" >
        
        ////Debug.write("clear yesno,askagain: ",yesno,askagain);
    
         var g = canvas.getUserData();
         if (g["image"]==null) g["image"]=new Array();
         g["image"]["clearField"]=yesno;
         g["image"]["askagainclear"]=!askagain;
         canvas.setUserData(g);

         if (yesno){
            ////Debug.write("clear field!!");
            canvas._drawarea.setModus('plain');
            canvas._drawarea.addNewSyncImage(this.downloadurl,this.iamgex,this.imagey,this.baseurl,this.fileName,this.moduleName,this.parentPath,this.room,this.domain);
         } else {
            ////Debug.write("don't clear field!!");
            canvas._drawarea.addNewSyncImage(this.downloadurl,this.iamgex,this.imagey,this.baseurl,this.fileName,this.moduleName,this.parentPath,this.room,this.domain);
         }
         this.confirmdialog.close();
    </method>
    
    <method name="getconfirmationscode">
        var g = canvas.getUserData();
        if (g["image"]==null) {
            g["image"]=new Array();
            g["image"]["clearField"]=false;
            g["image"]["askagainclear"]=true;
            canvas.setUserData(g);
        }
        return g["image"];
    </method>
    
    <method name="resetDefaultConfirmations">
        var g = canvas.getUserData();
        if (g["image"]==null) g["image"]=new Array();
        g["image"]["clearField"]=false;
        g["image"]["askagainclear"]=true;
        canvas.setUserData(g);
    </method>   
    
    <method name="clearAreaAndAddImage" args="downloadurlVal,xVal,yVal,baseurl,fileName,moduleName,parentPath,room,domain">
        <![CDATA[
        ////Debug.write("clearAreaAndAddImage: ",downloadurlVal,xVal,yVal,baseurl,fileName,moduleName,parentPath,room,domain);
        this.downloadurl=downloadurlVal;
        this.iamgex=xVal;
        this.imagey=yVal;   
        this.baseurl=baseurl;
        this.fileName=fileName;
        this.moduleName=moduleName;
        this.parentPath=parentPath;
        this.room=room;
        this.domain=domain;
        var storedImageDate = this.getconfirmationscode();
        ////Debug.write(" g[image] ",storedImageDate);
        if (storedImageDate["clearField"] && !storedImageDate["askagainclear"]){
            canvas._drawarea.setModus('plain');
            if ($debug) Debug.write(" canvas._drawarea.addNewImage 1 ",this.downloadurl,this.x,this.y);
            canvas._drawarea.addNewImage(this.downloadurl,this.x,this.y,this.baseurl,this.fileName,this.moduleName,this.parentPath,this.room,this.domain);
        } else if (!storedImageDate["askagainclear"] && !storedImageDate["clearField"]){
            canvas._drawarea.addNewImage(this.downloadurl,this.x,this.y,this.baseurl,this.fileName,this.moduleName,this.parentPath,this.room,this.domain);
            if ($debug) Debug.write(" canvas._drawarea.addNewImage 2 ",this.downloadurl,this.x,this.y);
        } else if (storedImageDate["askagainclear"]){
            this.confirmdialog = new lz.confirmationBox(canvas.main_content._content.inner,{labelid:62,labeliderror:63,refObj:this});
        } else {
            this.confirmdialog = new lz.confirmationBox(canvas.main_content._content.inner,{labelid:62,labeliderror:63,refObj:this});
        }
        ]]> 
    </method>
    
    <event name="isloadingImage" />
    <event name="isloadedImage" />
    
    
    <text fontsize="11" x="10" y="2" 
        name="_sharingClientName" fontstyle="bold" />    
    
    
	<method name="checkForApplyScreen">
		lz.Browser.loadURL(canvas.getScreenSharingUrl(), '_blank');
	</method> 
	
    <!-- 
        The Content Area    
     -->
    <view width="${ parent.parent.width-2 }" 
          height="${ (canvas.ismoderator) ? (parent.parent.height-42-parent._propertyPanel.height) : ((canvas.isAllowedToDraw) ? (parent.parent.height-42-parent._propertyPanel.height) : (parent.parent.height-42)) }" 
          y="0" name="_drawareaMask" clip="true" bgcolor="0xFFFFFF" >
    	
    	<handler name="oninit">
            if ($debug) Debug.info("lz.Track.register ",canvas.currentImagesListdraw.currentTrackGroupName);
            lz.Track.register(this, canvas.currentImagesListdraw.currentTrackGroupName);
        </handler>
    	
    	<handler name="onmousedown">
            this._drawarea.onmousedownMethod();
        </handler>
        
        <handler name="onmouseup">
            this._drawarea.onmouseupMethod();
        </handler>
        
        <handler name="onmouseover">
        	lz.Cursor.restoreCursor();
        	lz.Cursor.showHandCursor(false);
            this._drawarea.onmouseoverMethod();
        </handler>
        
        <handler name="onmouseout">
        	lz.Cursor.showHandCursor(true);
        	lz.Cursor.unlock();
            this._drawarea.onmouseoutMethod();
        </handler>
        
        <handler name="onmousetrackover">
            if ($debug) Debug.write("onmousetrackover");
            canvas.currentImagesListdraw.currentDragItem.sendOverItem(this);
            this.setAttribute("bgcolor",0x93FE92);
        </handler>
        
        <handler name="onmousetrackout">
            if ($debug) Debug.write("onmousetrackout");
            canvas.currentImagesListdraw.currentDragItem.sendOutItem(this);
            this.setAttribute("bgcolor",0xFFFFFF);
        </handler>
        
        <handler name="onmousetrackup">
            if ($debug) Debug.write("onmousetrackup");
            this.setAttribute("bgcolor",0xFFFFFF);
        </handler>   
    	
    	<remoteWhiteboard y="0" name="_drawarea" isRemoteOID="true" height="${parent.height}" width="${parent.height}"
                          restricted="$once{ parent.parent.restricted }" >
    		
    		<attribute name="sendUpdate" value="true" type="boolean"/>
    		
    		<handler name="onx" args="x">
                if (this.sendUpdate) {
                    if ($debug) Debug.write("# x",x);
					if ('scrollContainer' in parent.parent) {
    	                parent.parent.scrollContainer.calcScrollContent();
					}
                }
            </handler>
            
            <handler name="ony" args="y">
                if (this.sendUpdate) {
                    if ($debug) Debug.write("# y",y);
					if ('scrollContainer' in parent.parent) {
                    	parent.parent.scrollContainer.calcScrollContent();
					}
                }
            </handler>
            
            <handler name="onheight" args="h">
                if ($debug) Debug.write("# height",h);
                //this.dragger.drag_min_x = parent.width - w;
				if ('scrollContainer' in parent.parent) {
	                parent.parent.scrollContainer.calcScrollContent();
				}
            </handler>
            
            <handler name="onwidth" args="w">
                if ($debug) Debug.write("# width",w);
                //this.dragger.drag_min_y = parent.height - h;
				if ('scrollContainer' in parent.parent) {
	                parent.parent.scrollContainer.calcScrollContent();
				}
            </handler>
            
            <handler name="onupdateScale" args="tRef">
                if ($debug) Debug.write("# updateScale",this.getDisplayObject()._xscale);
				if ('scrollContainer' in parent.parent) {
	                parent.parent.scrollContainer.calcScrollContent();
				}
            </handler>
    		
            <attribute name="initH"/>
            <attribute name="initW"/>
            <handler name="oninit">
                canvas._drawarea = this; 
            </handler>
            
            <handler name="onprogress" args="perc">
                //Debug.write("onprogress: ",perc);
                this.parent.parent._progress.setProgress(perc);
            </handler>
            <!--
            <handler name="onmousedown" >
                //Debug.write("onprogress: ",perc);
            </handler>
             -->
            <handler name="ondrawmodus" args="d">
                this.drawmodus = d;
                //change Enabled Status of Toolbar Menu Button
                parent.parent._propertyPanel.loadPanelByModus(this);
            </handler>
            <handler name="setNewScreenUserName" args="value">
                this.parent.parent._sharingClientName.setAttribute('text',value);
            </handler>
            <!-- @overwrite -->
            <method name="onsharedMessage" args="action,obj">
                
                if ($debug) Debug.write("###### onsharedMessage",action,obj);
    
                var tempSendArray = new Array ();
                tempSendArray[0] = 'whiteboard';
                tempSendArray[1] = new Date();
                tempSendArray[2] = action;
                tempSendArray[3] = obj;
                     
                parent.parent.onsharedMessage.sendEvent(tempSendArray);
            </method>
            
            <handler name="onopenWhiteBoard" >
                //parent.parent.getRoomItems.doCall();
            </handler>
            
            <!-- clientid  = streamid of the user -->
            <method name="oninitUser" args="clientid,objectList">
                this.parent.parent.sendObjectToClientID = clientid;
                this.parent.parent.sendObject = objectList;
                this.parent.parent.sendMessageWithClientById.doCall();
            </method>
            
            <handler name="onboundingIsActive" args="b">
                if ($debug) Debug.write("boundingIsActive: ",b);
                if (b){
                    var boundingDoUpdateOnInit = true;
                    if (this.ObjectByName instanceof lz.swfResourceView){
                        //Debug.write("is swf Presentation");
                        boundingDoUpdateOnInit=false;
                    }
                    if (!boundingDoUpdateOnInit) {
                        parent.parent._propertyPanel.setObjectBounds(
                            this.ObjectByName.x,this.ObjectByName.y,
                            this.ObjectByName._swfView.width,this.ObjectByName._swfView.height);
                    } else {
                        parent.parent._propertyPanel.setObjectBounds(
                            this.ObjectByName.x,this.ObjectByName.y,
                            this.ObjectByName.width,this.ObjectByName.height);
                    }
                }
            </handler>
            
            <!--  bounding Box (selection Box) -->
            <handler name="onBoundingBox" args="boundingBoxRef">
                var boundingDoUpdateOnInit = true;
                if (boundingBoxRef.objRef instanceof lz.swfResourceView){
                //Debug.write("is swf Presentation");
                    boundingDoUpdateOnInit=false;
                }
                if (!boundingDoUpdateOnInit) {
                    parent.parent._propertyPanel.setObjectBounds(
                    boundingBoxRef.objRef.x,boundingBoxRef.objRef.y,
                    boundingBoxRef.objRef._swfView.width,boundingBoxRef.objRef._swfView.height);
                } else {
                    parent.parent._propertyPanel.setObjectBounds(
                    boundingBoxRef.objRef.x,boundingBoxRef.objRef.y,
                    boundingBoxRef.objRef.width,boundingBoxRef.objRef.height);
                }
            </handler>
            
            <method name="getDocumentToolBar">
                return parent.parent.panelArea.getDocumentsToolbar();
            </method>
            
            <method name="getPaintToolBar">
                return parent.parent.panelArea._mainToolsPanel;
            </method>
            
            <view name="_grid" x="-2" y="-2" height="${parent.height}" width="${parent.height}" 
                  visibility="${ (parent.showGrid) ? 'visible' : 'hidden'}"/>
        </remoteWhiteboard>   
    	
    </view>
    
    
    <view name="scrollContainer" width="${ parent.parent.width-2 }" 
          visible="${ ((canvas.ismoderator) ? true : ((canvas.isAllowedToDraw) ? true : false )) }"
          height="${ (canvas.ismoderator) ? (parent.parent.height-42-parent._propertyPanel.height) : ((canvas.isAllowedToDraw) ? (parent.parent.height-33-parent._propertyPanel.height) : (parent.parent.height-33)) }" >
        
        <attribute name="sendUpdate" value="true" type="boolean"/>
        
        <method name="calcScrollContent">
            var rHeight = Math.round(parent._drawareaMask._drawarea.height * (parent._drawareaMask._drawarea.getDisplayObject()._xscale / 100));
            var rWidth = Math.round(parent._drawareaMask._drawarea.width * (parent._drawareaMask._drawarea.getDisplayObject()._yscale / 100));
            this.sendUpdate = false;
            this.scrollview.setAttribute("x",parent._drawareaMask._drawarea.x);
            this.scrollview.setAttribute("y",parent._drawareaMask._drawarea.y);
            this.scrollview.setAttribute("height", Math.max(rHeight, parent._drawareaMask._drawarea.getDisplayObject()._height));
            this.scrollview.setAttribute("width", Math.max(rWidth, parent._drawareaMask._drawarea.getDisplayObject()._width));
            this.sendUpdate = true;
        </method>
        
        <view name="scrollview">
            
            <attribute name="timeisInited" value="false" type="boolean" />
            <attribute name="sendObjectDel" value="null" />
            
            <handler name="oninit">
                this.sendObjectDel = new LzDelegate( this, "sendObject" );
            </handler>
            
            <handler name="onx" args="x">
                if (parent.sendUpdate) {
                    if ($debug) Debug.write("# scrollview x",x);
                    parent.parent._drawareaMask._drawarea.setAttribute("x",x);
                    
                    if (!this.timeisInited){
                        this.timeisInited=true;
                        lz.Timer.addTimer( this.sendObjectDel, 250 );
                    } else {
                        lz.Timer.resetTimer( this.sendObjectDel, 250 );
                    }
                }
            </handler>
            <handler name="ony" args="y">
                if (parent.sendUpdate) {
                    if ($debug) Debug.write("# scrollview y",y);
                    parent.parent._drawareaMask._drawarea.setAttribute("y",y);
                    
                    if (!this.timeisInited){
                        this.timeisInited=true;
                        lz.Timer.addTimer( this.sendObjectDel, 250 );
                    } else {
                        lz.Timer.resetTimer( this.sendObjectDel, 250 );
                    }
                }
            </handler>
            
            <method name="sendObject" args="itemRef">
                if ($debug) Debug.info("sendObject :: scrollview");
                
                var tArray = new Array();
                tArray[0] = "moveMap";
                tArray[1] = Math.round(this.x);
                tArray[2] = Math.round(this.y);
                
                this.parent.parent._drawareaMask._drawarea.onsharedMessage('moveMap',tArray);
                this.timeisInited=false;
            </method>
        </view>
    
        <om_vscrollbar name="_scrollstv"/> 
        <om_hscrollbar name="_scrollsth" /> 
    
    </view>    
    
    
        <netRemoteCallHib name="sendMessageWithClientById" funcname="sendMessageWithClientById"
            remotecontext="$once{ canvas.thishib }" >
            <netparam><method name="getValue">return parent.parent.sendObject;</method></netparam>
            <netparam><method name="getValue">return parent.parent.sendObjectToClientID;</method></netparam>
            <handler name="ondata" args="value">
                <![CDATA[
                    //The onResult-Handler will be called be the rtmpconnection
                    //Debug.write("sendMessageWithClientById : ",value);
                ]]>
            </handler>   
        </netRemoteCallHib>     
    
    <view name="panelArea" width="${ parent.parent.width }" 
          height="${ parent.parent.height-42-parent._propertyPanel.height }">
        
        <attribute name="objectRef" value="null" />
        
        <!--- @deprecated -->
        <method name="_setSelection" args="obj">
            parent._drawareaMask._drawarea.removeObjectBounds();
            if (obj.setSelectionToItem){            
                if (this.objectRef!=null){
                    this.objectRef._isselected = false;
                    this.objectRef._area.setAttribute('bgcolor',0xFFFFFF);
                }
                this.objectRef = obj;
                this.objectRef._isselected = true;
                this.objectRef._area.setAttribute('bgcolor',canvas.getThemeColor('basebgcolorizer'));
                parent._drawareaMask._drawarea.setModus(this.objectRef.modi);
            }
        </method>
        
        <method name="setSelection" args="obj">
            if ($debug) Debug.write("setSelection ",obj);
            parent._drawareaMask._drawarea.removeObjectBounds();
            if (obj.setSelectionToItem){            
                if (this.objectRef!=null){
                    this.objectRef._isselected = false;
                    this.objectRef.setAttribute('enabled',true);
                }
                this.objectRef = obj;
                this.objectRef._isselected = true;
                this.objectRef.setAttribute('enabled',false);
            }
            if (obj.modi=="saveobj"){
                parent._drawareaMask._drawarea.doAction(obj.modi);
            } else {
                parent._drawareaMask._drawarea.setModus(obj.modi);
            }
        </method>
        
        <method name="setSelectionWithoutEvent" args="obj">
            if (obj.setSelectionToItem){         
                if (this.objectRef!=null){
                    this.objectRef._isselected = false;
                    this.objectRef.setAttribute('enabled',true);
                }
                this.objectRef = obj;
                this.objectRef._isselected = true;
                this.objectRef.setAttribute('enabled',false);
            }
        </method>
        
        <!--
                                
         -->
         
        <method name="sendNewPropertyHeight" args="objRef">
            <![CDATA[
                for (var i=0;i<this.subviews.length;i++) {
                    if (this.subviews[i].y != 0) {
                        if (this.subviews[i] instanceof lz.mainToolsTopPanel) {
                            if (objRef.height<=22){
                                if (this.subviews[i].y+this.subviews[i].height+5>=parent.parent.height-objRef.initheight-21){
                                    if ($debug) Debug.write("mainToolsTopPanel");
                                    this.subviews[i].setAttribute('y',objRef.y-this.subviews[i].height);
                                }
                            } else {
                                if (this.subviews[i].y+this.subviews[i].height+5>=objRef.y){
                                    if ($debug) Debug.write("mainToolsTopPanel");
                                    this.subviews[i].setAttribute('y',objRef.y-this.subviews[i].height);
                                }
                            }
                        }   
                    }
                }
            ]]>
        </method>
        
        <method name="getDocumentsToolbar">
            return parent._propertyPanel._content._documentsPanel;
        </method>
        
        <mainToolsTopPanel x="100" y="0" name="_mainToolsPanel" 
             visible="${ ((canvas.ismoderator) ? true : ((canvas.isAllowedToDraw) ? true : false )) }"/>
        
        <mainToolsLeftPanelPointer y="20" name="_mainToolsLeftPanelPointer" 
             visible="${ (parent.parent.restricted) ? false : (((canvas.ismoderator) ? false : ((canvas.isAllowedToDraw) ? false : true ))) }"/>
    </view> 
    
    <view name="zoombox" y="0" x="${ parent.parent.width-this.width-14 }" layout="axis:x;spacing:2">
        
        <attribute name="ignoreUpdates" value="false" type="boolean" />
        
        <handler name="onx" args="x">
        	if (this._fullFit.getValue()) {
        		if ($debug) Debug.write("on x ",x);
        		lz.Timer.addTimer( new LzDelegate( this, "sendUpdate" ), 100 );
        	}
        </handler>
        
        <method name="sendUpdate" args="refObj">
        	parent._drawareaMask._drawarea.doFullFit(true);
        </method>
        
        <method name="setWhiteboardValues" args="fullFit,zoom">
            if ($debug) Debug.write("setWhiteboardValues -1- ",fullFit,zoom);
            this.ignoreUpdates = true;
			if ('_zoom' in this) {
	            this._zoom.setSliderValue(zoom);
			}
            this._fullFit.setValue(fullFit);
            this.ignoreUpdates = false;
        </method>
        
        <method name="setCurrentScaleByFullFit" args="tScale">
            if ($debug) Debug.write("setCurrentScaleByFullFit -2- ",tScale);
            this.ignoreUpdates = true;
			if ('_zoom' in this) {
	            this._zoom.setSliderValue(tScale);
			}
            this.ignoreUpdates = false;
        </method>
        
        <labelCheckbox x="344" name="_fullFit" labelid="847" y="4" fontstyle="bold" bgcolor="0xFFFFFF" 
        		visible="${ ((canvas.becomemoderator) ? true : false ) }">
            <handler name="onvalue" args="v">
                if (parent.ignoreUpdates) {
                    return;
                }
                if ($debug) Debug.warn("onvalue Full Fit ",v);
                
				if ('_zoom' in parent) {
                	parent.parent._drawareaMask._drawarea.doUpdateFullFit(v,parent._zoom.initialNumber);
				}
            </handler>
            <labelTooltip labelid="1212" multiline="true" />
        </labelCheckbox>
        
        <changeWidthSlider name="_zoom" initialNumberInit="50" 
              boxPosition="down" initialNumber="50" maximum="200">
            <handler name="oninitialNumber" args="i">
                if (parent.ignoreUpdates) {
                    return;
                }
                
                if ($debug) Debug.warn("onvalue Zoom Fit ",this.initialNumber);
                
                parent._fullFit.setValue(false);
				parent.parent._drawareaMask._drawarea.doUpdateZoom(parent._fullFit.getValue(),this.initialNumber);
            </handler>
        </changeWidthSlider>
        
        <view width="2" />
        
    </view>    
    
    <propertyPanel name="_propertyPanel" x="0" y="${ parent.parent.height-this.height-42 }" 
                    visible="${ ((canvas.ismoderator) ? true : ((canvas.isAllowedToDraw) ? true : false )) }">
        <handler name="onheight" args="h">
            this.height = h;
            if ($debug) Debug.write("onheight: ",h);
            parent.panelArea.sendNewPropertyHeight(this);
        </handler>
    </propertyPanel>
</class>

</library>
