	/************************************************************************************************************
	(C) www.dhtmlgoodies.com, July 2006
	
	Update log:
	
	
	This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.	
	
	Terms of use:
	You are free to use this script as long as the copyright message is kept intact. However, you may not
	redistribute, sell or repost it without our permission.
	
	Thank you!
	
	www.dhtmlgoodies.com
	Alf Magne Kalleland
	
	************************************************************************************************************/
		
	var JSTreeObj;
	var treeUlCounter = 0;
	var nodeId = 1;
		
	/* Constructor */
	function JSDragDropTree()
	{
		var idOfTree;
		var imageFolder;
		var folderImage;
		var plusImage;
		var minusImage;
		var maximumDepth;
		var dragNode_source;
		var dragNode_parent;
		var dragNode_sourceNextSib;
		var dragNode_noSiblings;
		
		var dragNode_destination;
		var floatingContainer;
		var dragDropTimer;
		var dropTargetIndicator;
		var insertAsSub;
		var indicator_offsetX;
		var indicator_offsetX_sub;
		var indicator_offsetY;
		
		this.imageFolder = 'images/templates_2005/tree/';
		this.folderImage = 'folder.gif';
		this.plusImage = 'plus.gif';
		this.minusImage = 'minus.gif';
		this.maximumDepth = 6;
		var messageMaximumDepthReached;
		var ajaxObjects;
		
		
		this.floatingContainer = document.createElement('UL');
		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;
		
		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.messageMaximumDepthReached = ''; // Use '' if you don't want to display a message 
		this.ajaxObjects = new Array();
	}
	
	
	/* JSDragDropTree class */
	JSDragDropTree.prototype = {
		
		Get_Cookie : function(name) { 
		   var start = document.cookie.indexOf(name+"="); 
		   var len = start+name.length+1; 
		   if ((!start) && (name != document.cookie.substring(0,name.length))) return null; 
		   if (start == -1) return null; 
		   var end = document.cookie.indexOf(";",len); 
		   if (end == -1) end = document.cookie.length; 
		   return unescape(document.cookie.substring(len,end)); 
		} 
		,
		// This function has been slightly modified
		Set_Cookie : function(name,value,expires,path,domain,secure) { 
			expires = expires * 60*60*24*1000;
			var today = new Date();
			var expires_date = new Date( today.getTime() + (expires) );
		    var cookieString = name + "=" +escape(value) + 
		       ( (expires) ? ";expires=" + expires_date.toGMTString() : "") + 
		       ( (path) ? ";path=" + path : "") + 
		       ( (domain) ? ";domain=" + domain : "") + 
		       ( (secure) ? ";secure" : ""); 
		    document.cookie = cookieString; 
		} 
		,setMaximumDepth : function(maxDepth)
		{
			this.maximumDepth = maxDepth;	
		}
		,setMessageMaximumDepthReached : function(newMessage)
		{
			this.messageMaximumDepthReached = newMessage;
		}
		,	
		setImageFolder : function(path)
		{
			this.imageFolder = path;	
		}
		,
		setFolderImage : function(imagePath)
		{
			this.folderImage = imagePath;			
		}
		,
		setPlusImage : function(imagePath)
		{
			this.plusImage = imagePath;				
		}
		,
		setMinusImage : function(imagePath)
		{
			this.minusImage = imagePath;			
		}
		,		
		setTreeId : function(idOfTree)
		{
			this.idOfTree = idOfTree;			
		}	
		,
		expandAll : function()
		{
			var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
			for(var no=0;no<menuItems.length;no++){
				var subItems = menuItems[no].getElementsByTagName('UL');
				if(subItems.length>0 && subItems[0].style.display!='block'){
					JSTreeObj.showHideNode(false,menuItems[no].id.replace(/[^0-9]/g,''));
				}			
			}
		}	
		,
		collapseAll : function(treeId)
		{
			var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
			for(var no=0;no<menuItems.length;no++){
				var subItems = menuItems[no].getElementsByTagName('UL');
				if(subItems.length>0 && subItems[0].style.display=='block'){
					JSTreeObj.showHideNode(false,menuItems[no].id.replace(/[^0-9]/g,''));
				}			
			}		
		}	
		,
		/*
		Find top pos of a tree node
		*/
		getTopPos : function(obj){
			var top = obj.offsetTop/1;
			if(document.all)top = top/1 + 13; else top = top/1 + 4;		
			return top;
		}
		,	
		/*
		Find left pos of a tree node
		*/
		getLeftPos : function(obj){
			var left = obj.offsetLeft/1 + 1;
			if(document.all)left = left/1 - 2;
			return left;
		}	
		,
		showHideNode : function(e,inputId)
		{
			if(inputId)
			{
				if(!document.getElementById('treeNode'+inputId))
					return;
				thisNode = document.getElementById('treeNode'+inputId).getElementsByTagName('IMG')[0]; 
			}
			else 
			{
				thisNode = this;
				if(this.tagName=='A')
					thisNode = this.parentNode.getElementsByTagName('IMG')[0];	
				
			}
			if(thisNode.style.visibility=='hidden')
				return;		
			var parentNode = thisNode.parentNode;
			while (parentNode.tagName != "LI")
				parentNode = parentNode.parentNode;
			
			inputId = parentNode.id.replace(/[^0-9]/g,'');
			if(thisNode.src.indexOf(JSTreeObj.plusImage)>=0)
			{
				//show subnodes
				thisNode.src = thisNode.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage);
				var ul = parentNode.getElementsByTagName('UL')[0];
				if(ul != null)
				{				
					ul.style.display='block';
					//if(!initExpandedNodes)
					//	initExpandedNodes = ',';
					//if(initExpandedNodes.indexOf(',' + inputId + ',')<0) 
					//	initExpandedNodes = initExpandedNodes + inputId + ',';
				}
				else
				{
					//The subnodes are not loaded yet. Get them with AJAX.
					
					var anchorteller = 1;
					var anchor = parentNode.getElementsByTagName('A')[anchorteller];	
					var noLink = true;
					while (noLink)
					{			
						// No link var set ?
						var tmpVar = anchor.getAttribute('noLink');
						if(!tmpVar)
							tmpVar = anchor.noLink;
						if(tmpVar=='true')
							noLink=true;
						else
							break;
						if (noLink)
							anchor = parentNode.getElementsByTagName('A')[++anchorteller];
					}
						
					var htmlobject = document.createElement('UL');
					anchor.parentNode.insertBefore(htmlobject,anchor);
					
					var ajaxObj = new sack();
					ajaxObj.requestFile = anchor.href;	
					htmlobject.parentNode.removeChild(anchor);
					ajaxObj.method = "GET";
					ajaxObj.elementObj = htmlobject;
					ajaxObj.onCompletion = function() { JSTreeObj.loadCompleted(htmlobject); } ;
					ajaxObj.runAJAX();		// Execute AJAX function	
				}
			}
			else
			{
				//hide subnodes.
				
				thisNode.src = thisNode.src.replace(JSTreeObj.minusImage,JSTreeObj.plusImage);
				parentNode.getElementsByTagName('UL')[0].style.display='none';
				//initExpandedNodes = initExpandedNodes.replace(',' + inputId,'');
			}	
			//JSTreeObj.Set_Cookie('expandedNodes',initExpandedNodes,500);			
			return false;						
		}
		,
		loadCompleted : function(htmlobject)
		{
			var menuItems = htmlobject.getElementsByTagName('LI');	// Get an array of all menu items
			if (menuItems.length == 0)
			{
				var img = htmlobject.parentNode.getElementsByTagName('IMG')[0];
				img.style.visibility='hidden';
				htmlobject.parentNode.removeChild(htmlobject);
			}
			else
				JSTreeObj.initNode(menuItems);
		}
		,
		
		/* Initialize drag */
		initDrag : function(e)
		{
			if(document.all)e = event;	
			
			var subs = JSTreeObj.floatingContainer.getElementsByTagName('LI');
			if(subs.length>0){
				if(JSTreeObj.dragNode_sourceNextSib){
					JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib);
				}else{
					JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source);
				}					
			}
			
			JSTreeObj.dragNode_source = this.parentNode;
			JSTreeObj.dragNode_parent = this.parentNode.parentNode;
			JSTreeObj.dragNode_sourceNextSib = false;

			
			if(JSTreeObj.dragNode_source.nextSibling)JSTreeObj.dragNode_sourceNextSib = JSTreeObj.dragNode_source.nextSibling;
			JSTreeObj.dragNode_destination = false;
			JSTreeObj.dragDropTimer = 0;
			JSTreeObj.timerDrag();
			return false;
		}
		,
		timerDrag : function()
		{	
			if(this.dragDropTimer>=0 && this.dragDropTimer<10){
				this.dragDropTimer = this.dragDropTimer + 1;
				setTimeout('JSTreeObj.timerDrag()',20);
				return;
			}
			if(this.dragDropTimer==10)
			{
				JSTreeObj.floatingContainer.style.display='block';
				JSTreeObj.floatingContainer.appendChild(JSTreeObj.dragNode_source);	
			}
		}
		,
		moveDragableNodes : function(e)
		{
			if(JSTreeObj.dragDropTimer<10)return;
			if(document.all)e = event;
			dragDrop_x = e.clientX/1 + 5 + document.body.scrollLeft;
			dragDrop_y = e.clientY/1 + 5 + document.documentElement.scrollTop;	
					
			JSTreeObj.floatingContainer.style.left = dragDrop_x + 'px';
			JSTreeObj.floatingContainer.style.top = dragDrop_y + 'px';
			
			var thisObj = this;
			if(thisObj.tagName=='A' || thisObj.tagName=='IMG')thisObj = thisObj.parentNode;

			JSTreeObj.dragNode_noSiblings = false;
			var tmpVar = thisObj.getAttribute('noSiblings');
			if(!tmpVar)tmpVar = thisObj.noSiblings;
			if(tmpVar=='true')JSTreeObj.dragNode_noSiblings=true;
					
			if(thisObj && thisObj.id)
			{
				JSTreeObj.dragNode_destination = thisObj;
				var img = thisObj.getElementsByTagName('IMG')[1];
				var tmpObj= JSTreeObj.dropTargetIndicator;
				tmpObj.style.display='block';
				
				var eventSourceObj = this;
				if(JSTreeObj.dragNode_noSiblings && eventSourceObj.tagName=='IMG')eventSourceObj = eventSourceObj.nextSibling;
				
				var tmpImg = tmpObj.getElementsByTagName('IMG')[0];
				if(this.tagName=='A' || JSTreeObj.dragNode_noSiblings){
					tmpImg.src = tmpImg.src.replace('ind1','ind2');	
					JSTreeObj.insertAsSub = true;
					tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX_sub) + 'px';
				}else{
					tmpImg.src = tmpImg.src.replace('ind2','ind1');
					JSTreeObj.insertAsSub = false;
					tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX) + 'px';
				}
				
				
				tmpObj.style.top = (JSTreeObj.getTopPos(thisObj) + JSTreeObj.indicator_offsetY) + 'px';
			}
			
			return false;
			
		}
		,
		dropDragableNodes:function()
		{
			if(JSTreeObj.dragDropTimer<10){				
				JSTreeObj.dragDropTimer = -1;
				return;
			}
			var showMessage = false;
			if(JSTreeObj.dragNode_destination){	// Check depth
				var countUp = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_destination,'up');
				var countDown = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_source,'down');
				var countLevels = countUp/1 + countDown/1 + (JSTreeObj.insertAsSub?1:0);		
				
				if(countLevels>JSTreeObj.maximumDepth){
					JSTreeObj.dragNode_destination = false;
					showMessage = true; 	// Used later down in this function
				}
			}
			
			
			if(JSTreeObj.dragNode_destination){			
				if(JSTreeObj.insertAsSub){
					var uls = JSTreeObj.dragNode_destination.getElementsByTagName('UL');
					if(uls.length>0){
						ul = uls[0];
						ul.style.display='block';
						
						var lis = ul.getElementsByTagName('LI');

						if(lis.length>0){	// Sub elements exists - drop dragable node before the first one
							ul.insertBefore(JSTreeObj.dragNode_source,lis[0]);	
						}else {	// No sub exists - use the appendChild method - This line should not be executed unless there's something wrong in the HTML, i.e empty <ul>
							ul.appendChild(JSTreeObj.dragNode_source);	
						}
					}else{
						var ul = document.createElement('UL');
						ul.style.display='block';
						JSTreeObj.dragNode_destination.appendChild(ul);
						ul.appendChild(JSTreeObj.dragNode_source);
					}
					var img = JSTreeObj.dragNode_destination.getElementsByTagName('IMG')[0];					
					img.style.visibility='visible';
					img.src = img.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage);					
					
					
				}else{
					if(JSTreeObj.dragNode_destination.nextSibling){
						var nextSib = JSTreeObj.dragNode_destination.nextSibling;
						nextSib.parentNode.insertBefore(JSTreeObj.dragNode_source,nextSib);
					}else{
						JSTreeObj.dragNode_destination.parentNode.appendChild(JSTreeObj.dragNode_source);
					}
				}	
				/* Clear parent object */
				var tmpObj = JSTreeObj.dragNode_parent;
				var lis = tmpObj.getElementsByTagName('LI');
				if(lis.length==0){
					var img = tmpObj.parentNode.getElementsByTagName('IMG')[0];
					img.style.visibility='hidden';	// Hide [+],[-] icon
					tmpObj.parentNode.removeChild(tmpObj);						
				}
				
			}else{
				// Putting the item back to it's original location
				
				if(JSTreeObj.dragNode_sourceNextSib){
					JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib);
				}else{
					JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source);
				}			
					
			}
			JSTreeObj.dropTargetIndicator.style.display='none';		
			JSTreeObj.dragDropTimer = -1;	
			if(showMessage && JSTreeObj.messageMaximumDepthReached)alert(JSTreeObj.messageMaximumDepthReached);
		}
		,
		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);
			
		}
		,
		dragDropCountLevels : function(obj,direction,stopAtObject){
			var countLevels = 0;
			if(direction=='up'){
				while(obj.parentNode && obj.parentNode!=stopAtObject){
					obj = obj.parentNode;
					if(obj.tagName=='UL')countLevels = countLevels/1 +1;
				}		
				return countLevels;
			}	
			
			if(direction=='down'){ 
				var subObjects = obj.getElementsByTagName('LI');
				for(var no=0;no<subObjects.length;no++){
					countLevels = Math.max(countLevels,JSTreeObj.dragDropCountLevels(subObjects[no],"up",obj));
				}
				return countLevels;
			}	
		}		
		,
		cancelEvent : function()
		{
			return false;	
		}
		,
		cancelSelectionEvent : function()
		{
			
			if(JSTreeObj.dragDropTimer<10)return true;
			return false;	
		}
		,saveTree : function(initObj,saveString)
		{
			
			if(!saveString)var saveString = '';
			if(!initObj){
				initObj = document.getElementById(this.idOfTree);

			}
			var lis = initObj.getElementsByTagName('LI');

			if(lis.length>0){
				var li = lis[0];
				while(li){
					if(li.id){
						if(saveString.length>0)saveString = saveString + ',';
	
						saveString = saveString + li.id.replace(/[^0-9]/gi,'');
						saveString = saveString + '-';
						if(li.parentNode.id!=this.idOfTree)saveString = saveString + li.parentNode.parentNode.id.replace(/[^0-9]/gi,''); else saveString = saveString + '0';
						
						var ul = li.getElementsByTagName('UL');
						if(ul.length>0){
							saveString = this.saveTree(ul[0],saveString);	
						}	
					}			
					li = li.nextSibling;
				}
			}

			if(initObj.id == this.idOfTree){

				var ajaxIndex = this.ajaxObjects.length;
				this.ajaxObjects[ajaxIndex] = new sack();
				var url = 'saveNodes.php?saveString=' + saveString;
				this.ajaxObjects[ajaxIndex].requestFile = url;	// Specifying which file to get
				this.ajaxObjects[ajaxIndex].onCompletion = function() { JSTreeObj.saveComplete(ajaxIndex); } ;	// Specify function that will be executed after file has been found
				this.ajaxObjects[ajaxIndex].runAJAX();		// Execute AJAX function	
							
			}
			// The nodes could be saved by submitting a form or by ajax
			/* Examples:
			
			1) By submitting a form:
			
			* Create form
			
			<form name="myForm" id="myForm" method="Post" action="aFile.php">
				<input type="hidden" name="hiddenNodes">
			</form>
			
			* Update the hidden form field from this function
			
			document.forms['myForm'].hiddenNodes.value = saveString
			
			* Submit the form
			
			document.forms['myForm'].submit;
			
			2) By ajax: 
			
			Simply use the ajax library you find in the ajax section
			
			var ajaxObj = new sack();
			var url = 'aFile.php?saveString=' + saveString;
			ajaxObj.requestFile = url;	// Specifying which file to get
			ajaxObj.onCompletion = aFunctionName;	// Specify function that will be executed after file has been found
			ajaxObj.runAJAX();		// Execute AJAX function	

			*/
			return saveString;
		}
		,
		saveComplete : function(index)
		{
			alert(this.ajaxObjects[index].response);
		}		
		,
		initTree : function()
		{
			JSTreeObj = this;
			JSTreeObj.createDropIndicator();
			document.documentElement.onselectstart = JSTreeObj.cancelSelectionEvent;
			document.documentElement.ondragstart = JSTreeObj.cancelEvent;
			var dhtmlgoodies_tree = document.getElementById(this.idOfTree);
			var menuItems = dhtmlgoodies_tree.getElementsByTagName('LI');	// Get an array of all menu items
			this.initNode(menuItems);

			//initExpandedNodes = this.Get_Cookie('expandedNodes');
			//if(initExpandedNodes)
			//{
			//	var nodes = initExpandedNodes.split(',');
			//	for(var no=0;no<nodes.length;no++)
			//	{
			//		if(nodes[no])this.showHideNode(false,nodes[no]);	
			//	}			
			//}			
			
			document.documentElement.onmousemove = JSTreeObj.moveDragableNodes;	
			document.documentElement.onmouseup = JSTreeObj.dropDragableNodes;
		}	
		,
		initNode : function(menuItems)
		{
			var nodeId = 0;
			for(var no=0;no<menuItems.length;no++)
			{
				// No children var set ?
				var noChildren = false;
				var tmpVar = menuItems[no].getAttribute('noChildren');
				if(!tmpVar)
					tmpVar = menuItems[no].noChildren;
				if(tmpVar=='true')
					noChildren=true;
					
				// No drag var set ?
				var noDrag = false;
				var tmpVar = menuItems[no].getAttribute('noDrag');
				if(!tmpVar)
					tmpVar = menuItems[no].noDrag;
				if(tmpVar=='true')
					noDrag=true;

				// No icon var set ?
				var noIcon = false;
				var tmpVar = menuItems[no].getAttribute('noIcon');
				if(!tmpVar)
					tmpVar = menuItems[no].noIcon;
				if(tmpVar=='true')
					noIcon=true;
							 
				nodeId++;
				var subItems = menuItems[no].getElementsByTagName('UL');
				var img = document.createElement('IMG');
				img.src = JSTreeObj.imageFolder + JSTreeObj.plusImage;
				img.onclick = JSTreeObj.showHideNode;
					
				if(nodeId==1)
					img.id = 'rootplus';
					
				if(subItems.length==0)
				{
					//don't set hidden yet.
					//img.style.visibility='hidden';
				}
				else
				{
					subItems[0].id = 'tree_ul_' + treeUlCounter;
					treeUlCounter++;
				}
				var aTag = menuItems[no].getElementsByTagName('A')[0];
				//aTag.onclick = JSTreeObj.showHideNode;
				if(!noDrag)
					aTag.onmousedown = JSTreeObj.initDrag;
				if(!noChildren)
					aTag.onmousemove = JSTreeObj.moveDragableNodes;
				if(!noChildren)
					aTag.parentNode.insertBefore(img,aTag);
				menuItems[no].id = 'treeNode' + nodeId;
				var folderImg = document.createElement('IMG');
				if(!noDrag)
					folderImg.onmousedown = JSTreeObj.initDrag;
				if(!noChildren)
					folderImg.onmousemove = JSTreeObj.moveDragableNodes;
				if(!noChildren)				
				{
					if(menuItems[no].className)
					{
						folderImg.src = JSTreeObj.imageFolder + menuItems[no].className;
					}
					else
					{
						folderImg.src = JSTreeObj.imageFolder + JSTreeObj.folderImage;
					}
					if (!noIcon)
						aTag.parentNode.insertBefore(folderImg,aTag);		
				}
			}
		}	
	}
