/************************************************************************************************************
Drag and drop for blocks
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 JSDataFormObj;
		
	/* Constructor */
	function JSDragDropBlock()
	{
		var idOfBlockList;
		//var menuKey='';
		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 additionalRenameRequestParameters = {};
		var additionalDeleteRequestParameters = {};

		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;
		
		this.EvntFunction = "SetNewBlockOrder";
		this.AjaxFunction = "changeMenuSelection";
		
	}
	
	
	/* JSDragDropTree class */
	JSDragDropBlock.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;	
		}
		,		
		setBlockListId : function(idOfBlockList)
		{
			this.idOfBlockList = idOfBlockList;			
		}	
		,
		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(JSBlockObj.dragDropTimer<10)	return true;
			return false;	
		}
		,highlightItem : function(inputObj,e)
		{
			if(JSBlockObj.currentlyActiveItem)JSBlockObj.currentlyActiveItem.className = '';
			this.className = 'highlightedNodeItem';
			JSBlockObj.currentlyActiveItem = this;
		}
		,
		removeHighlight : function()
		{
			if(JSBlockObj.currentlyActiveItem)JSBlockObj.currentlyActiveItem.className = '';
			JSBlockObj.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);
		}
		,
		initBlockList : function()
		{
			JSBlockObj = this;
			JSBlockObj.createDropIndicator();
			document.documentElement.onselectstart = JSBlockObj.cancelSelectionEvent;
			document.documentElement.ondragstart = JSBlockObj.cancelEvent;
			document.documentElement.onmousedown = JSBlockObj.removeHighlight;

			var theBlockList = $('#'+JSBlockObj.idOfBlockList);
			//** Initialisation des blocks de la version publiée:
			$('tr[@id^=row]', theBlockList).filter('[idblock]').each(
				function()
				{
					var IdBlock = this.getAttribute('idblock');
					currentRow = this;
					$("img", currentRow).filter("[arrow]").each(
							
							function(){
								arrowSens = this.getAttribute('arrow');
								if(arrowSens!='')
								{
									switch (arrowSens)
									{
										case 'Down': this.setAttribute('id',"IMGUP#"+IdBlock) ; break;
										case 'UP':	 this.setAttribute('id',"IMGDOWN#"+IdBlock) ;  break; 
										default: break;
									} 
									this.style.cursor = 'move'; 
									this.onmousedown = JSBlockObj.initDrag; 
									this.onmousemove = JSBlockObj.moveDragableNodes;
									/*if( $(this).attr('id').beginsWith("IMG", true) == true ) {
										alert('Id = '+$(this).attr('id'));
									    // do something with this <div> that starts with "Item 1"
									} */
								}
							}
					 );
				}
			);
			
			//** Les sous blocks de la version publiée:
			$('td[@id*=Col_]', theBlockList).each(
				function()
				{
					 $('img[@id^=SUBIMGUP#]', this).each(
						function(){
							this.style.cursor = 'move'; 
							this.onmousedown = JSBlockObj.initDrag ; 
							this.onmousemove = JSBlockObj.moveDragableNodes ;
						}
					 );	 
					 
					 $('img[@id^=SUBIMGDOWN#]', this).each(
						function(){
							this.style.cursor = 'move'; 
							this.onmousedown = JSBlockObj.initDrag; 
							this.onmousemove = JSBlockObj.moveDragableNodes;
						}
					 );
					 
					 //** Les lignes des champs de la fiche invitée
					 $('img[@id^=FieldUp_]', this).filter('[arrow]').each(
							
							function()
							{
								this.style.cursor = 'move'; 
								this.onmousedown = JSBlockObj.initDrag; 
								this.onmousemove = JSBlockObj.moveDragableNodes;
							/*	var parent = this;
								while(parent.tagName!='TR' && parent.parentNode){
										parent = parent.parentNode;
								}
								parent.onmousedown = JSBlockObj.initDrag; 
								parent.onmousemove = JSBlockObj.moveDragableNodes;

							*/
							}
					 );
					
					$('img[@id^=FieldDown_]', this).filter('[arrow]').each(
							function()
							{
								this.style.cursor = 'move'; 
								this.onmousedown = JSBlockObj.initDrag; 
								this.onmousemove = JSBlockObj.moveDragableNodes;
							}
					 );
					 
					
				}
			);
			
			//** Liste des champs pour les formulaires:
			$('tr[@id^=Row_]', theBlockList).each(
				function()
				{
					
					
					$('img[@id^=IMGUP#]', this).filter('[arrow]').each(
							
							function()
							{
								this.style.cursor = 'move'; 
								this.onmousedown = JSBlockObj.initDrag; 
								this.onmousemove = JSBlockObj.moveDragableNodes;
							}
					 );
					
					$('img[@id^=IMGDOWN#]', this).each(
							function()
							{
								this.style.cursor = 'move'; 
								this.onmousedown = JSBlockObj.initDrag; 
								this.onmousemove = JSBlockObj.moveDragableNodes;
							}
					 );
					 
				}
			);
			
			theBlockList.mousemove(JSBlockObj.moveDragableNodes);
			theBlockList.mouseup(JSBlockObj.dropDragableNodes);
			
		}
		
		,
		/* Initialize drag */
		initDrag : function(e)
		{
			if(document.all)  e = event;	
	
			sourceId = this.id;	
			var DragType = sourceId.substring(0, sourceId.indexOf("#"));
			
			switch (DragType)
			{
				case 'IMGUP': 
				case 'IMGDOWN':   JSBlockObj.EvntFunction = "SetNewBlockOrder";
								  //JSBlockObj.AjaxFunction = "changeMenuSelection"; 
								  break;
								  
				case 'SUBIMGUP':	 
				case 'SUBIMGDOWN':	JSBlockObj.EvntFunction = "SetNewSubBlockList";
								  	//JSBlockObj.AjaxFunction = "changeMenuSelection";  
									break;
				case 'FieldUp': 
				case 'FieldDown': JSBlockObj.EvntFunction = "setNewInvitationFieldList";
								  JSBlockObj.AjaxFunction = "setNewFieldDataList"; 
								  break;					
				default: break;
			} 
			
			JSBlockObj.dragNode_source = document.getElementById(sourceId);
			JSBlockObj.dragNode_parent = JSBlockObj.dragNode_source.parentNode;
			JSBlockObj.dragNode_sourceNextSib = false;
	
			JSBlockObj.dragNode_destination = false;
			JSBlockObj.dragDropTimer = 0;
			JSBlockObj.timerDrag();
			return false;
		}
		
		,
		timerDrag : function()
		{	
			if(this.dragDropTimer>=0 && this.dragDropTimer<10){
				this.dragDropTimer = this.dragDropTimer + 1;
				setTimeout('JSBlockObj.timerDrag()',20);
				return;
			}
			if(this.dragDropTimer==10)
			{
				JSBlockObj.floatingContainer.style.display='block';
				JSBlockObj.floatingContainer.appendChild(JSBlockObj.dragNode_source);
				JSBlockObj.floatingContainer.style.opacity=0.4;
			}
		}
		,
		moveDragableNodes : function(e)
		{
			if(JSBlockObj.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;	
			
			JSBlockObj.floatingContainer.style.left = dragDrop_x + 'px';
			JSBlockObj.floatingContainer.style.top = dragDrop_y + 'px';
			
			var thisObj = this;
			while(thisObj.tagName!='IMG' && thisObj.id.indexOf('IMG')==-1){
				return;
			}
						
			JSBlockObj.dragNode_noSiblings = false;
				
			if(thisObj && thisObj.id) {
				
				JSBlockObj.dragNode_destination = thisObj;
				var tmpObj= JSBlockObj.dropTargetIndicator;
				tmpObj.style.display='block';
				
				var eventSourceObj = this;
				if(JSBlockObj.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' || JSBlockObj.dragNode_noSiblings){
					tmpImg.src = tmpImg.src.replace('ind1','ind2');
					JSBlockObj.insertAsSub = true;
					tmpObj.style.left = (JSBlockObj.getLeftPos(eventSourceObj) + JSBlockObj.indicator_offsetX_sub) + 'px';
				}
				else{
					tmpImg.src = tmpImg.src.replace('ind2','ind1');
					JSBlockObj.insertAsSub = false;
					tmpObj.style.left = (JSBlockObj.getLeftPos(eventSourceObj) + JSBlockObj.indicator_offsetX) + 'px';
				}
				
				tmpObj.style.top = (JSBlockObj.getTopPos(thisObj) + JSBlockObj.indicator_offsetY) + 'px';
			
			}
			return false;
		}
		,
		
		dropDragableNodes:function()
		{
			if(JSBlockObj.dragDropTimer<10){				
				JSBlockObj.dragDropTimer = -1;
				return;
			}
		
			if(JSBlockObj.dragNode_destination){	
				
				if(JSBlockObj.dragNode_destination.parentNode){
						JSBlockObj.dragNode_destination.parentNode.insertBefore(JSBlockObj.dragNode_source,JSBlockObj.dragNode_destination);
				}	
				
				if(document.getElementById(JSBlockObj.idOfBlockList)!=null)
				{
					element = document.getElementById(JSBlockObj.idOfBlockList);
					AjaxFunction = element.getAttribute("AjaxFunction");
					EvntFunction = element.getAttribute("EvntFunction");
				}
				if(!AjaxFunction)
					AjaxFunction = JSBlockObj.AjaxFunction;
				
				if(!EvntFunction)
					EvntFunction = JSBlockObj.EvntFunction;
				
				//** *****Traitement spécifique pour le contenu transversal
				name     = document.getElementById(JSBlockObj.dragNode_source.id).getAttribute('name');
				totalRow = document.getElementById(JSBlockObj.dragNode_source.id).getAttribute('totalrow');
				sourceRowNum = document.getElementById(JSBlockObj.dragNode_source.id).getAttribute('rownum');
				destRowNum = document.getElementById(JSBlockObj.dragNode_destination.id).getAttribute('rownum');
				
				JSBlockObj.dropTargetIndicator.style.display='none';
				
				if(name && totalRow)
				{
					SQ_FormGeneric(Data,'Event',EvntFunction,'_SQ','Y',
										'DivId',JSBlockObj.idOfBlockList,	
										'IsClick','N',
										'Name',name,
										'TotalRow',totalRow,
									    'SourceRowNum',sourceRowNum,
									    'DestRowNum',destRowNum,
							 		    'AjaxFunction',AjaxFunction,
									    'SourceNodeId', JSBlockObj.dragNode_source.id,
									    'DestNodeId', JSBlockObj.dragNode_destination.id);
				}
				//** Traitement de base:
				else
				{
					SQ_FormGeneric(Data,'Event',EvntFunction,'_SQ','Y',
										'DivId',JSBlockObj.idOfBlockList,	
										'IsClick','N',
								 		'AjaxFunction',AjaxFunction,
										'SourceNodeId', JSBlockObj.dragNode_source.id,
										'DestNodeId', JSBlockObj.dragNode_destination.id);
				}
				
				var ProcessInit = true;
			}
			else{
				// Putting the item back to it's original location
				if(JSBlockObj.dragNode_sourceNextSib){
					JSBlockObj.dragNode_parent.insertBefore(JSBlockObj.dragNode_source,JSBlockObj.dragNode_sourceNextSib);
				}
				else{
					JSBlockObj.dragNode_parent.appendChild(JSBlockObj.dragNode_source);
				}			
			}
			
			JSBlockObj.dropTargetIndicator.style.display='none';
			JSBlockObj.floatingContainer.style.display='none';
			JSBlockObj.dragNode_parent.appendChild(JSBlockObj.dragNode_source);
			JSBlockObj.dragDropTimer = -1;	
			//** Réinitialisation de la liste des blocks:
			if(ProcessInit==true)
				JSBlockObj.initBlockList();
			
		}
		,__addAdditionalRequestParameters : function(ajax, parameters)
		{
			for (var parameter in parameters) {
				ajax.setVar(parameter, parameters[parameter]);
			}
		}
	}
