<?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="baseFileExplorerItem" extends="view">
	
	<attribute name="refObjListRoot" value="null"/>
	
	<attribute name="isRoot" value="false" type="boolean" />
	
	<attribute name="fileIcon" type="string" value="string" />
	
	<attribute name="open" value="false" type="boolean" />
	
	<attribute name="fileExplorerItemId" value="0" type="number" />
	<attribute name="isOwner" value="false" type="boolean" />
	
	<attribute name="isFolder" value="true" type="boolean" />
	<attribute name="isImage" value="false" type="boolean" />
	<attribute name="isPresentation" value="false" type="boolean" />
	<attribute name="isVideo" value="false" type="boolean" />
	
	<attribute name="fileName" value="" type="string" />
	<attribute name="fileHash" value="" type="string" />
	
	<attribute name="selected" value="false" type="boolean"/>
	
	<attribute name="singleClickDelegate" value="null" />
	<attribute name="singleClickStarted" value="false" type="boolean" />
	
	<attribute name="isMouseDownDragAction" value="false" type="boolean"/>
	
	<!-- If this is true, then this item has been drag-n-droped and it makes no 
	       sense to handle any single or double click event -->
	<attribute name="mouseDownClickUsed" value="false" type="boolean" />
	<attribute name="mouseDownClickDelegate" value="null" />
	
	<attribute name="isTrashCan" value="false" type="boolean" />
	
	<handler name="oninit">
		this.singleClickDelegate = new LzDelegate( this, "doSingleClick" );
		this.resetClickDelegate = new LzDelegate( this, "doResetSingleClick" );
		this.mouseDownClickDelegate = new LzDelegate( this, "doMouseDownClick" );
		if (this.isFolder) {
		    lz.Track.register(this._fileName, canvas.currentImagesListdraw.currentTrackGroupName);
		}
	</handler>
	
	<method name="doOpen">
		this.open = true;
		if (this.isFolder) {
    		this.icon_folder_pre.setAttribute("frame",2);
    		this.content.setAttribute("visibility","visible");
			this._folderIcon.setAttribute("frame",2);
		    this.loadFiles();
		}
	</method>
	
	<method name="doClose">
		this.open = false;
		if (this.isFolder) {
            this.icon_folder_pre.setAttribute("frame",1);
            this.content.setAttribute("visibility","hidden");
            this._folderIcon.setAttribute("frame",1);
		}
	</method>
	
    <method name="doMouseDownClick" args="itemObj">
    	<![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
	    	this.mouseDownClickUsed = true;
	    	if ($debug) Debug.write("mouseDown CLICK Start Drag And Drop");
	    	new lz.dragItemFileExplorer(canvas,{
	    		        dragItemResource:this.fileIcon,
	            	    refObj:this,
	                    x:canvas.getMouse('x'),
	                    y:canvas.getMouse('y')
	            	});
        ]]>
    </method>
    
    <!--
    	Check if this is the Owner
     -->
    <method name="checkForIsOwner">
    	if (this.isRoot) {
    		return this.isOwner;
    	} else {
    		return parent.parent.checkForIsOwner();
    	}
    </method>
    
    <!--
    	Check if the user tries to move a file in its own tree,
    	see moveFile
     -->
    <method name="checkForIsChild" args="compareFileExplorerItemId">
    	if (this.isRoot) {
    		return false;
    	} else {
    		if (this.fileExplorerItemId == compareFileExplorerItemId) {
    			return true;
    		} else {
    			return parent.parent.checkForIsChild(compareFileExplorerItemId);
    		}
    	}
    </method>
    
    <method name="deleteFile" args="labelid">
    	<![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
	    	new lz.confirmationSingle(canvas,{
	                           refObj:this,
	                           labelid:labelid,
	                           labeliderror:713,
	                           showCheckBox:false
	                        });
    	]]>
    </method>
    
    <method name="sendConfirmation" args="bool,askAgain">
        if (bool) {
            this.deleteFileOrFolder();
        }
    </method>
    
    <method name="deleteFileOrFolder">
        <![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
	    	
            if ($debug) Debug.write("deleteFileOrFolder HTTP 1: ");
            //this.getFileExplorerByRoom.doCall();
            var downloadurl = canvas.protocol + '://'+canvas.rtmphostlocal+':'+canvas.red5httpport
                            +canvas.httpRootKey+'services/FileService/deleteFileOrFolderSelf?'
                            +'SID='+canvas.sessionId
                            +'&fileExplorerItemId='+this.fileExplorerItemId;
            
            this.deleteFileOrFolderSelf.setAttribute("src",downloadurl);
            if ($debug) Debug.write("deleteFileOrFolderSelf doRequest ",downloadurl);
            this.deleteFileOrFolderSelf.doRequest();
        ]]>
    </method>
    
    <dataset name="deleteFileOrFolderSelf" type="http" >
        <handler name="ondata" args="d">
            <![CDATA[
                //if ($debug) Debug.write("ondata ",d);
                if ($debug) Debug.write("deleteFileOrFolder: ",d);
                parent.parent.parent.doOpen();
                parent.refObjListRoot._selected = null;
                parent.refObjListRoot.parentFolderId = -2;
            ]]>
        </handler>
    </dataset>
    
    <!--
    <netRemoteCallHib name="deleteFileOrFolder" funcname="fileservice.deleteFileOrFolder" 
        remotecontext="$once{ canvas.thishib }" > 
        <netparam><method name="getValue">return canvas.sessionId;</method></netparam>
        <netparam><method name="getValue">return parent.parent.fileExplorerItemId;</method></netparam>
        <handler name="ondata" args="value">    
            if ($debug) Debug.write("deleteFileOrFolder: ",value);
            parent.parent.parent.doOpen();
            parent.refObjListRoot._selected = null;
            parent.refObjListRoot.parentFolderId = -2;
        </handler>
    </netRemoteCallHib> 
     -->
    
	<method name="doSingleClick" args="itemObj">
		this.singleClickStarted = false;
		//Cannot change name for Root Icons
		if (this.isRoot) {
            return;
        }
		this.addOrUpdateFolderName(this.fileExplorerItemId,false);
	</method>
	
	<method name="doResetSingleClick" args="itmeObj">
		this.singleClickStarted = false;
	</method>
	
	<method name="addFile">
		this.refObjListRoot.selectItem(this);
		this.refObjListRoot.addFile();
	</method>
	
	<method name="addFolder">
		<![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
	
			if (this.isFolder) {
				if ($debug) Debug.write("NEW this.fileExplorerItemId INTO ",this);
				if ($debug) Debug.write("NEW this.fileExplorerItemId ",this.fileExplorerItemId);
				if (this["icon_folder_pre"]) {
	    			this.icon_folder_pre.setAttribute("frame",2);
	                this.content.setAttribute("visibility","visible");
	                this._folderIcon.setAttribute("frame",2);
	        		var t = new lz.folderFileExplorerItem(this.content,{
	        			            isOwner:this.isOwner,
	        			            isFolder:true,
	                    		    fileIcon:'icon_folder_rsc',
	                                refObjListRoot:this.refObjListRoot,
	                    		    fileName:canvas.getLabelName(712)
	                    		});
	                t.addOrUpdateFolderName(this.fileExplorerItemId,true);
				}
			}
		]]>
	</method>
	
	<method name="refresh">
		this.doOpen();
	</method>
	
	<method name="playVideo">
		this.refObjListRoot.playVideo(this);
	</method>
	
	<method name="editFolderName">
		<![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
			this.addOrUpdateFolderName(this.fileExplorerItemId,false);
		]]>
	</method>
	
	<method name="loadDocument">
		this.refObjListRoot.loadDocument(this);
	</method>
	
	<method name="loadWmlFile">
		this.refObjListRoot.loadWmlFile(this);
	</method>

	<method name="loadChart">
		this.refObjListRoot.loadChart(this);
	</method>
	
	<method name="addOrUpdateFolderName" args="fileExplorerItemId,isNew">
		<![CDATA[
			if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
	    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
	    		return;
	    	}
		
    		if ($debug) Debug.write("addOrUpdateFolderName ",fileExplorerItemId);
    		var tWidth = this._fileName.width;
    		if (tWidth < 160) {
    			tWidth = 160;
    		}
    		
    		var t = new lz.dynamicFileName(canvas,{
    			        parentFileExplorerItemId:fileExplorerItemId,
    			        fileExplorerItemId:this.fileExplorerItemId, //Only used at update Name
    			        isOwner:this.isOwner,
    			        text:this.fileName,
    			        isNew:isNew, //false means its a renaming
    			        refObj:this,width:tWidth+10,
            		    x:this._fileName.getAttributeRelative("x",canvas),
            		    y:this._fileName.getAttributeRelative("y",canvas)
            		});
            		
            lz.Focus.setFocus(t,true);
            lz.ModeManager.makeModal(t);
            
        ]]>
	</method>
	
	<method name="toggleOpen" args="setSelection">
		<![CDATA[
			if (this.mouseDownClickUsed) {
				if ($debug) Debug.write("mouseDownClickUsed RESET TO DEFAULT BUT DO NO ACTION Cause its a Drag and Drop Event");
				this.mouseDownClickUsed = false;
				return;
			}
			
			if (this.singleClickStarted) {
	            if ($debug) Debug.write("Is this selected => Double Click !!!");
	            this.singleClickStarted = false;
	            lz.Timer.removeTimer( this.singleClickDelegate );
	            
	            if (!canvas.isAllowedToDraw && !canvas.ismoderator) {
		    		new lz.labelerrorPopup(canvas,{errorlabelid:1462});
		    		return;
		    	}
	            
	            if (this.isVideo) {
	            	this.playVideo();
	            } else if (this.isWmlFile){
					this.loadWmlFile();
				} else if (this.isFolder) {
	                this.doSingleClick(null);
	            } else if (this.isPresentation) {
	                this.loadDocument();
	            }
	        } else {
	        	
	        	if (this.isFolder){
	        		if (!this.open) {
	        			this.doOpen();
	        		} else {
	        			if (setSelection) {
	            			if (this.selected) {
	            				if ($debug) Debug.write("Is this selected => Do Edit !!!");
	            				this.singleClickStarted = true;
	            			    lz.Timer.addTimer( this.singleClickDelegate, 300 );
	            			} else {
	            				
	            				this.singleClickStarted = true;
	            				lz.Timer.addTimer( this.resetClickDelegate, 300 );
	            			}
	        			} else {
	        				this.doClose();
	        			}
	        		}
	        	} else {
	        		if (setSelection) {
	                    if (this.selected) {
	                        if ($debug) Debug.write("Is this selected => Do Edit !!!");
	                        this.singleClickStarted = true;
	                        lz.Timer.addTimer( this.singleClickDelegate, 300 );
	                    } else {
	                        this.singleClickStarted = true;
	                        lz.Timer.addTimer( this.resetClickDelegate, 300 );
	                    }
	                }
	        	}
			}
			
			if (setSelection) this.refObjListRoot.selectItem(this);
		]]>
	</method>
	
	<method name="selectItem">
		this.selected = true;
		this._fileName.setAttribute("bgcolor",canvas.getThemeColor('baseMousecolorizer'));
	</method>
	
	<method name="deselectItem">
		this.selected = false;
		if (this["_fileName"]) {
            this._fileName.setAttribute("bgcolor",canvas.getThemeColor('mainBackgroundColor'));
        } else {
            if ($debug) Debug.warn("deselectItem:: _fileName is NULL ",this);
        }
    </method>
	
	<method name="clearContent">
        <![CDATA[
            for (var eg in this.content.subviews) {
                this.content.subviews[eg].destroy();
            }
        ]]>
    </method>
    
    <method name="loadFiles">
    	<![CDATA[
            //this.getFileExplorerByRoom.doCall();
            var downloadurl = canvas.protocol + '://'+canvas.rtmphostlocal+':'+canvas.red5httpport
                            +canvas.httpRootKey+'services/FileService/getFileExplorerByParentSelfInternal?'
                            +'SID='+canvas.sessionId
                            +'&parentFileExplorerItemId='+this.fileExplorerItemId
                            +'&roomId='+hib.currentroomid
                            +'&isOwner='+this.isOwner;
            
            this.getFileExplorerByParentSelf.setAttribute("src",downloadurl);
            if ($debug) Debug.write("getFileExplorerByParentSelf doRequest ",downloadurl);
            this.getFileExplorerByParentSelf.doRequest();
        ]]>
    </method>
    
    <dataset name="getFileExplorerByParentSelf" type="http" >
        <handler name="ondata" args="d">
            <![CDATA[
                //if ($debug) Debug.write("ondata ",d);
                parent.renderFilesAndFolders(canvas.currentFileExplorer.parseParentToRoomObject(d));
            ]]>
        </handler>
    </dataset>
    
    <!--
        parent.parseRootItems(canvas.currentFileExplorer.parseToRoomObject(d));
	 -->
	<!--
	   public List<FileExplorerItem> getFileExplorerByParent(String SID, Long parentFileExplorerItemId, 
	               Long room_id, Boolean isOwner) {
	<netRemoteCallHib name="getFileExplorerByParent" funcname="fileservice.getFileExplorerByParent" 
        remotecontext="$once{ canvas.thishib }" >   
        <netparam><method name="getValue">return canvas.sessionId;</method></netparam>
        <netparam><method name="getValue">return parent.parent.fileExplorerItemId;</method></netparam>  
        <netparam><method name="getValue">return hib.currentroomid;</method></netparam>  
        <netparam><method name="getValue">return parent.parent.isOwner;</method></netparam>         
        <handler name="ondata" args="value">    
            if ($debug) Debug.write("getFileExplorerByParent: ",value);
            parent.renderFilesAndFolders(value);
        </handler>
    </netRemoteCallHib> 
     --> 
    
    <method name="renderFilesAndFolders" args="roomHome">
        <![CDATA[
            this.clearContent();
            
            // Folder area
            for (var i=0; i<roomHome.length; i++) {
                var fileExplorerItem = roomHome[i];
                if (fileExplorerItem.isFolder) {
                    new lz.folderFileExplorerItem(this.content,{
                                            fileName:fileExplorerItem.fileName,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileIcon:'icon_folder_rsc',
                                            refObjListRoot:this.refObjListRoot
                                        });
                } else if (fileExplorerItem.isImage) {
                    new lz.imageFileExplorerItem(this.content,{
                                            isFolder:false,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileName:fileExplorerItem.fileName,
                                            fileHash:fileExplorerItem.fileHash,
                                            isFolder:false,isImage:true,
                                            fileIcon:'file_explorer_image_rsc',
                                            refObjListRoot:this.refObjListRoot
                                        });
                } else if (fileExplorerItem.isPresentation) {
                    new lz.documentFileExplorerItem(this.content,{
                                            isFolder:false,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileName:fileExplorerItem.fileName,
                                            fileHash:fileExplorerItem.fileHash,
                                            isFolder:false,isPresentation:true,
                                            fileIcon:'file_explorer_document_rsc',
                                            refObjListRoot:this.refObjListRoot
                                        });
                } else if (fileExplorerItem.isVideo) {
                    new lz.videoFileExplorerItem(this.content,{
                                            isFolder:false,
                                            isVideo:true,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileName:fileExplorerItem.fileName,
                                            fileHash:fileExplorerItem.fileHash,
                                            isFolder:false,isImage:true,
                                            fileIcon:'file_explorer_video_rsc',
                                            flvHeight:fileExplorerItem.flvHeight,
                                            flvWidth:fileExplorerItem.flvWidth,
                                            refObjListRoot:this.refObjListRoot
                                        });
                } else if (fileExplorerItem.isStoredWmlFile) { 
                	new lz.wmlFileExplorerItem(this.content,{
                                            isFolder:false,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileName:fileExplorerItem.fileName,
                                            fileIcon:'file_explorer_wml_rsc',
                                            isWmlFile: true,
                                            refObjListRoot:this.refObjListRoot                	
            							});
                } else if (fileExplorerItem.isChart) { 
                	new lz.chartFileExplorerItem(this.content,{
                                            isFolder:false,
                                            fileExplorerItemId:fileExplorerItem.fileExplorerItemId,
                                            fileName:fileExplorerItem.fileName,
                                            fileIcon:'file_explorer_chart_rsc',
                                            refObjListRoot:this.refObjListRoot                	
            							});

            	}
            }
        ]]>
    </method>
    
	
	<view name="icon_folder_pre" 
		  visibility="$once{ (parent.isFolder) ? 'visible' : 'hidden' }"
		  resource="icon_folder_pre_rsc" frame="1" >
		<handler name="onclick">
			parent.toggleOpen(false);
		</handler>
	</view>
	
	<view name="_folderIcon" resource="$once{ parent.fileIcon }" x="16" y="2" >
		<handler name="onmousedown">
			if (parent.isRoot) {
                return;
            }
            lz.Timer.addTimer( parent.mouseDownClickDelegate, 300 );
        </handler>
        <handler name="onmouseup">
        	if (parent.isRoot) {
                return;
            }
            lz.Timer.removeTimer( parent.mouseDownClickDelegate );
        </handler>
		<handler name="onclick">
			parent.toggleOpen(false);
		</handler>
	</view>
	
</class>


</library>
