<?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="dragItemFLVExplorer" extends="view">
	
	<attribute name="refObj" value="null"/>
	
	<attribute name="dragItemResource" value="" type="string"/>
	
	<attribute name="overItem" value="null"/>
	
	<attribute name="alreadySent" value="false" type="boolean" />
	
	<handler name="oninit">
		lz.Track.activate(canvas.currentImagesListdraw.currentTrackGroupName);
		canvas.currentImagesListdraw.currentDragItem = this;
		lz.Cursor.showHandCursor(false);
		lz.ModeManager.globalLockMouseEvents();
		this.dragger.apply();
	</handler>
	
	<method name="sendOverItem" args="itemRef">
		<![CDATA[
    		if (this.refObj != itemRef) {
    			
    			if (this.refObj.isFolder) {
    				if (!itemRef.isTrashCan && !itemRef.isFolder) {
    					//No Folders to the whiteboard please
    					return;
    				}
    			}
    			
        		this.overItem = itemRef;
        		this._dragIcon.setAttribute("frame",2);
    		}
		]]>
	</method>
	
	<method name="sendOutItem" args="itemRef">
        this.overItem = null;
        this._dragIcon.setAttribute("frame",1);
    </method>
	
	<handler name="onmouseup" reference="lz.GlobalMouse" args="who">
        this.close();
    </handler>
    
    <method name="close">
    	//This can happen when the confirmation pops up
    	if (this.alreadySent) {
    		return;
    	}
    	this.alreadySent = true;
    	if ($debug) Debug.write("close Drag Item");
    	lz.Cursor.showHandCursor(true);
    	lz.Track.deactivate(canvas.currentImagesListdraw.currentTrackGroupName);
    	lz.ModeManager.globalUnlockMouseEvents();
    	canvas.currentImagesListdraw.currentDragItem = null;
    	this.dragger.remove();
    	
    	if (this.overItem != null) {
    		
    		if ($debug) Debug.write("this.overItem ",this.overItem);
    		
    		if (this.overItem.isTrashCan) {
    			if ($debug) Debug.write("SEND TO GARBAGE");
    			this.deleteFLVOrFolder.fileExplorerItemId = this.refObj.fileExplorerItemId;
    			new lz.confirmationSingle(canvas,{
            			   refObj:this,
            			   labelid:710,
            			   labeliderror:713,
                           showCheckBox:false,
                           refReturnMethod:"sendConfirmation"
            			});
    		} else if (this.overItem.isFolder){
    			if ($debug) Debug.write("MOVE ITEM",this.refObj.fileExplorerItemId);
    			if ($debug) Debug.write("MOVE TO PARENT",this.overItem.fileExplorerItemId);
    			this.moveFile.fileExplorerItemId = this.refObj.fileExplorerItemId;
    			this.moveFile.newParentFileExplorerItemId = this.overItem.fileExplorerItemId;
    			if (this.overItem.fileExplorerItemId == 0) {
    			    this.moveFile.isOwner = this.overItem.isOwner;
    			}
    			
    			//check if this is a home folder or not
                var checkForOwer = this.overItem.checkForIsOwner();
                if ($debug) Debug.write("checkForOwer ::",checkForOwer);
                this.moveFile.moveToHome = checkForOwer;
                
                //check that the file is not moved inside itself
                if (this.overItem.checkForIsChild(this.refObj.fileExplorerItemId)) {
                    new lz.labelerrorPopup(canvas,{errorlabelid:922});
                    this.destroy();
                    return;
                }
                
    			this.moveFile.doCall();
    		} else {
    			if ($debug) Debug.warn("Drag to whiteboard !!! ");
    			if (this.refObj.isPresentation) {
    			    this.refObj.loadDocumentToWhiteboard();
    			} else if (this.refObj.isImage) {
    				this.refObj.loadImageToWhiteboard();
    			} else {
    				if ($debug) Debug.warn("Should never happen dragItemFileExplorer unhandled case");
    			}
    			this.destroy();
    		}
    	} else {
    		this.destroy();
    	}
    	
    </method>
    
    <method name="sendConfirmation" args="bool,askAgain">
    	if (bool) {
    		this.deleteFLVOrFolder.doCall();
    	} else {
    		this.destroy();
    	}
    </method>
    
    <netRemoteCallHib name="deleteFLVOrFolder" funcname="flvrecorderservice.deleteFLVOrFolder" 
        remotecontext="$once{ canvas.thishib }" > 
        
        <attribute name="fileExplorerItemId" value="0" type="number" />
        
        <netparam><method name="getValue">return canvas.sessionId;</method></netparam>
        <netparam><method name="getValue">return parent.fileExplorerItemId;</method></netparam>
        <handler name="ondata" args="value">    
            if ($debug) Debug.write("deleteFileOrFolder: ",value);
            parent.refObj.parent.parent.doOpen();
            parent.destroy();
        </handler>
    </netRemoteCallHib> 
    
    <netRemoteCallHib name="moveFile" funcname="flvrecorderservice.moveFile" 
        remotecontext="$once{ canvas.thishib }" > 
        
        <attribute name="fileExplorerItemId" value="0" type="number" />
        <attribute name="newParentFileExplorerItemId" value="0" type="number" />
        <attribute name="isOwner" value="false" type="boolean" />
        
        <netparam><method name="getValue">return canvas.sessionId;</method></netparam>
        <netparam><method name="getValue">return parent.fileExplorerItemId;</method></netparam>
        <netparam><method name="getValue">return parent.newParentFileExplorerItemId;</method></netparam>  
        <netparam><method name="getValue">return parent.isOwner;</method></netparam>  
        <netparam><method name="getValue">return parent.moveToHome;</method></netparam>
        
        <handler name="ondata" args="value">    
            if ($debug) Debug.write("moveFile: ",value);
            parent.overItem.doOpen();
            parent.refObj.parent.parent.doOpen();
            parent.destroy();
        </handler>
    </netRemoteCallHib>     
   
	<view name="_dragFileSymbol" x="10" y="10"
		resource="$once{ parent.dragItemResource }" />
	
	<view name="_dragIcon" x="18" y="14" 
		  resource="drag_n_drop_rsc" frame="1" />
	
	<dragstate name="dragger"/>
</class>

</library>
