/************************************************************************************************************
Copyright (C) 2006  DTHMLGoodies.com, Alf Magne Kalleland

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Dhtmlgoodies.com., hereby disclaims all copyright interest in this script
written by Alf Magne Kalleland.

Alf Magne Kalleland, 2006
Owner of DHTMLgoodies.com


************************************************************************************************************/	
		
	var JSNodeObj;
		
	/* Constructor */
	function JSDragDropNode()
	{
		var idOfNodesDiv;
		var imageFolder ="M/i/";
		var dragNode_source;
		var dragNode_parent;
		var dragNode_sourceNextSib;
		var dragNode_noSiblings;
		var dragNode_relatedBigNode;
		var ajaxObjects;
		
		var dragNode_destination;
		var floatingContainer;
		var dragDropTimer;
		var dropTargetIndicator;
		var insertAsSub;
		var indicator_offsetX;
		var indicator_offsetX_sub;
		var indicator_offsetY;
		
		this.imageFolder = 'M/i/';


		var currentlyActiveItem;
		var contextMenu;
		var currentItemToEdit;		// Reference to item currently being edited(example: renamed)
		var helpObj;
		
		this.contextMenu = false;
		this.floatingContainer = document.createElement('DIV');
		this.floatingContainer.style.position = 'absolute';
		this.floatingContainer.style.display='none';
		this.floatingContainer.id = 'floatingContainer';
		this.insertAsSub = false;
		document.body.appendChild(this.floatingContainer);
		this.dragDropTimer = -1;
		this.dragNode_noSiblings = false;
		this.currentItemToEdit = false;
		
		if(document.all){
			this.indicator_offsetX = 2;	// Offset position of small black lines indicating where nodes would be dropped.
			this.indicator_offsetX_sub = 4;
			this.indicator_offsetY = 2;
		}else{
			this.indicator_offsetX = 1;	// Offset position of small black lines indicating where nodes would be dropped.
			this.indicator_offsetX_sub = 3;
			this.indicator_offsetY = 2;			
		}
		if(navigator.userAgent.indexOf('Opera')>=0){
			this.indicator_offsetX = 2;	// Offset position of small black lines indicating where nodes would be dropped.
			this.indicator_offsetX_sub = 3;
			this.indicator_offsetY = -7;				
		}
		
		this.currentlyActiveItem = false;
		this.filePathRenameItem = 'folderTree_updateItem.php';
		this.filePathDeleteItem = 'folderTree_updateItem.php';
		this.ajaxObjects = new Array();
		this.helpObj = false;
		
		this.RENAME_STATE_BEGIN = 1;
		this.RENAME_STATE_CANCELED = 2;
		this.RENAME_STATE_REQUEST_SENDED = 3;
		this.renameState = null;
	}
	
	
	/* JSDragDropNode class */
	JSDragDropNode.prototype = {
		// {{{ addEvent()
	    /**
	     *
	     *  This function adds an event listener to an element on the page.
	     *
	     *	@param Object whichObject = Reference to HTML element(Which object to assigne the event)
	     *	@param String eventType = Which type of event, example "mousemove" or "mouseup"
	     *	@param functionName = Name of function to execute. 
	     * 
	     * @public
	     */	
		addEvent : function(whichObject,eventType,functionName)
		{ 
		  if(whichObject.attachEvent){ 
		    whichObject['e'+eventType+functionName] = functionName; 
		    whichObject[eventType+functionName] = function(){
				    	whichObject['e'+eventType+functionName]( window.event );
				    } 
		    whichObject.attachEvent( 'on'+eventType, whichObject[eventType+functionName] ); 
		  } else 
		    whichObject.addEventListener(eventType,functionName,false); 	    
		} 
		// }}}	
		,	
		// {{{ removeEvent()
	    /**
	     *
	     *  This function removes an event listener from an element on the page.
	     *
	     *	@param Object whichObject = Reference to HTML element(Which object to assigne the event)
	     *	@param String eventType = Which type of event, example "mousemove" or "mouseup"
	     *	@param functionName = Name of function to execute. 
	     * 
	     * @public
	     */		
		removeEvent : function(whichObject, eventType, functionName)
		{ 
		  if(whichObject.detachEvent){ 
		    whichObject.detachEvent('on'+eventType, whichObject[eventType+functionName]); 
		    whichObject[eventType+functionName] = null; 
		  } else 
		    whichObject.removeEventListener(eventType,functionName,false); 
		} 
		,	
		setImageFolder : function(path)
		{
			this.imageFolder = path;	
		}
		,		
		setNodeDivId : function(idOfNodesDiv)
		{
			this.idOfNodesDiv = idOfNodesDiv;			
		}	
		,
		getTopPos : function(obj){
			var top = obj.offsetTop/1;
			while((obj = obj.offsetParent) != null){
				if(obj.tagName!='HTML')top += obj.offsetTop;
			}			
			if(document.all)top = top/1 + 13; else top = top/1 + 4;		
			return top;
		}
		,	
		getLeftPos : function(obj){
			var left = obj.offsetLeft/1 + 1;
			while((obj = obj.offsetParent) != null){
				if(obj.tagName!='HTML')left += obj.offsetLeft;
			}
			if(document.all)left = left/1 - 2;
			return left;
		}	
		,
		cancelEvent : function()
		{
			return false;	
		}
		,
		cancelSelectionEvent : function()
		{
			if(JSNodeObj.dragDropTimer<10)return true;
			return false;	
		}
		,highlightItem : function(inputObj,e)
		{
			if(JSNodeObj.currentlyActiveItem)	JSNodeObj.currentlyActiveItem.className = '';
			this.className = 'highlightedNodeItem';
			JSNodeObj.currentlyActiveItem = this;
		}
		,
		removeHighlight : function()
		{
			if(JSNodeObj.currentlyActiveItem)	JSNodeObj.currentlyActiveItem.className = '';
			JSNodeObj.currentlyActiveItem = false;
		}
		,
		hasSubNodes : function(obj)
		{
			var subs = obj.getElementsByTagName('SPAN');
			if(subs.length>0)return true;
			return false;	
		}
		,
		__refreshDisplay : function(obj)
		{
			if(this.hasSubNodes(obj))	return;

			var img = obj.getElementsByTagName('IMG')[0];
			img.style.visibility = 'hidden';	
		}

		,
		createDropIndicator : function()
		{
			this.dropTargetIndicator = document.createElement('DIV');
			this.dropTargetIndicator.style.position = 'absolute';
			this.dropTargetIndicator.style.display='none';			
			var img = document.createElement('IMG');
			img.src = this.imageFolder + 'dragDrop_ind1.gif';
			img.id = 'dragDropIndicatorImage';
			this.dropTargetIndicator.appendChild(img);
			document.body.appendChild(this.dropTargetIndicator);
			
		}
		,
		initNodeList : function()
		{
			JSNodeObj = this;
			JSNodeObj.createDropIndicator();
			document.documentElement.onselectstart = JSNodeObj.cancelSelectionEvent;
			document.documentElement.ondragstart = JSNodeObj.cancelEvent;
			document.documentElement.onmousedown = JSNodeObj.removeHighlight;
			
			var theNodeList = $('#'+JSNodeObj.idOfNodesDiv);
			$('tr[@id*=row]', theNodeList).each(
				function()
				{
					//** Affectation des mouseDown et mousemove aux images:
					$('img[@id*=IMGUP#]', this).each(
							
							function(){
								this.style.cursor = 'move'; 
								this.onmousedown = JSNodeObj.initDrag; 
								this.onmousemove = JSNodeObj.moveDragableNodes;
							}
					 );
					
					$('img[@id*=IMGDOWN#]', this).each(
							function(){
								this.style.cursor = 'move'; 
								this.onmousedown = JSNodeObj.initDrag; 
								this.onmousemove = JSNodeObj.moveDragableNodes;
							}
					 );
				}
			);
			
			theNodeList.mousemove(JSNodeObj.moveDragableNodes);
			theNodeList.mouseup(JSNodeObj.dropDragableNodes);
		}
		
		,
		/* Initialize drag */
		initDrag : function(e)
		{

			if(document.all)  e = event;	
			
			sourceId = this.id;	
			JSNodeObj.dragNode_source = document.getElementById(sourceId);
			JSNodeObj.dragNode_parent = JSNodeObj.dragNode_source.parentNode;
			JSNodeObj.dragNode_sourceNextSib = false;

			JSNodeObj.dragNode_destination = false;
			JSNodeObj.dragDropTimer = 0;
			JSNodeObj.timerDrag();
			return false;
		}
		
		,
		timerDrag : function()
		{	
			if(this.dragDropTimer>=0 && this.dragDropTimer<10){
				this.dragDropTimer = this.dragDropTimer + 1;
				setTimeout('JSNodeObj.timerDrag()',20);
				return;
			}
			if(this.dragDropTimer==10)
			{
				JSNodeObj.floatingContainer.style.display='block';
				JSNodeObj.floatingContainer.appendChild(JSNodeObj.dragNode_source);
				JSNodeObj.floatingContainer.style.opacity=0.4;
			}
		}
		
		,
		moveDragableNodes : function(e)
		{
			if(JSNodeObj.dragDropTimer<10) return;
			
			if(document.all)e = event;
			dragDrop_x = e.clientX/1 + 2 + document.body.scrollLeft;
			dragDrop_y = e.clientY/1 + 2 + document.body.scrollTop;	
			
			JSNodeObj.floatingContainer.style.left = dragDrop_x + 'px';
			JSNodeObj.floatingContainer.style.top = dragDrop_y + 'px';
			
			var thisObj = this;
			while(thisObj.tagName!='IMG' && thisObj.id.indexOf('IMG')==-1){
				return;
			}
			
			JSNodeObj.dragNode_noSiblings = false;
				
			if(thisObj && thisObj.id)
			{
				JSNodeObj.dragNode_destination = thisObj;
				var tmpObj= JSNodeObj.dropTargetIndicator;
				tmpObj.style.display='block';
				
				var eventSourceObj = this;
				if(JSNodeObj.dragNode_noSiblings && eventSourceObj.tagName=='IMG')
					eventSourceObj = eventSourceObj.nextSibling;
				//** style pour l'indicateur tmpObj qui contient tmpImg(flèche):
				var tmpImg = tmpObj.getElementsByTagName('IMG')[0];
				if(this.tagName=='A' || JSNodeObj.dragNode_noSiblings)
				{
					tmpImg.src = tmpImg.src.replace('ind1','ind2');
					JSNodeObj.insertAsSub = true;
					tmpObj.style.left = (JSNodeObj.getLeftPos(eventSourceObj) + JSNodeObj.indicator_offsetX_sub) + 'px';
				}
				else{
					tmpImg.src = tmpImg.src.replace('ind2','ind1');
					JSNodeObj.insertAsSub = false;
					tmpObj.style.left = (JSNodeObj.getLeftPos(eventSourceObj) + JSNodeObj.indicator_offsetX) + 'px';
				}
				
				tmpObj.style.top = (JSNodeObj.getTopPos(thisObj) + JSNodeObj.indicator_offsetY) + 'px';
			
			}
			return false;
		}
		,
		
		dropDragableNodes:function()
		{
			if(JSNodeObj.dragDropTimer<10){				
				JSNodeObj.dragDropTimer = -1;
				return;
			}
		
			if(JSNodeObj.dragNode_destination){	
				
				if(JSNodeObj.dragNode_destination.parentNode)
				{
						JSNodeObj.dragNode_destination.parentNode.insertBefore(JSNodeObj.dragNode_source,JSNodeObj.dragNode_destination);
				}	
				if(document.getElementById(JSNodeObj.idOfNodesDiv)!=null)
				{
					element = document.getElementById(JSNodeObj.idOfNodesDiv);
					AjaxFunction = element.getAttribute("AjaxFunction");
					EvntFunction = element.getAttribute("EvntFunction");
				}
				
				// if(!AjaxFunction)	AjaxFunction = "setNewMediaListOrder";
				// if(!EvntFunction)	EvntFunction = "SetNewNodeListOrder";
				JSNodeObj.dropTargetIndicator.style.display='none';
				//alert(AjaxFunction)
				SQ_FormGeneric(Data,'Event',EvntFunction,'_SQ','Y',
									'DivId',JSNodeObj.idOfNodesDiv,
									'IsClick','N',
							 		'AjaxFunction',AjaxFunction,
									'SourceNodeId', JSNodeObj.dragNode_source.id,
									'DestNodeId', JSNodeObj.dragNode_destination.id);
													  
				//var ProcessInit = true;
			
			}
			else{
				// Putting the item back to it's original location:
				if(JSNodeObj.dragNode_sourceNextSib){
					JSNodeObj.dragNode_parent.insertBefore(JSNodeObj.dragNode_source,JSNodeObj.dragNode_sourceNextSib);
				}
				else{
					JSNodeObj.dragNode_parent.appendChild(JSNodeObj.dragNode_source);
				}			
			}
			JSNodeObj.dropTargetIndicator.style.display='none' ;		
			JSNodeObj.floatingContainer.style.display='none';
			JSNodeObj.dragNode_parent.appendChild(JSNodeObj.dragNode_source);
			JSNodeObj.dragDropTimer = -1 ;	
			//JSNodeObj.initNodeList() ;
		}
		
		,
		__addAdditionalRequestParameters : function(ajax, parameters)
		{
			for (var parameter in parameters) {
				ajax.setVar(parameter, parameters[parameter]);
			}
		}
	}
