/******************************************************************************************************************************************
* ---------------------------------------------------------jsTreeClasses [filetree.js]-----------------------------------------------------
*				    			!! COPYRIGHT lars bagamery 2004 [lsblsb@gmx.de] !!    
*******************************************************************************************************************************************/

/***benoetigt tree-class!***/

//erweitere Tree-Klasse um Klassenvariablen////////////////////////////////////////////////////////////////////////////////////////////////

	Tree.prototype.idPrefix = "ftid_";
	Tree.prototype.idPrefixSwitch = "switch_";
	Tree.prototype.idPrefixFolder = "folder_";
	Tree.prototype.idPrefixImages = "";
	Tree.prototype.imagesDir = "img/";
	Tree.prototype.sensitiveSymbols = true;
	Tree.prototype.reverseDisplayUserFunc = null; //funktion, die nach aufruf von reverseDisplay() aufgerufen wird.
	Tree.prototype.reverseDisplayUserFuncArgs = new Array(); //zugehoerige parameter-werte
	Tree.prototype.targetNode = null;

//erweitere Tree-Klasse um getFileTree-Funktion////////////////////////////////////////////////////////////////////////////////////////////

	Tree.prototype.getFileTree = function(pStartNode, pArrKeypairs, pMaxDepth, pActNode, pChildNum, pDepth)
	{
		if(!pStartNode || pStartNode == "")
		{
			pStartNode = this.rootNode;
		}
		if(!pMaxDepth)
		{
			pMaxDepth = -1;
		}
		if(!pActNode)
		{
			var pActNode = pStartNode;
			var pDepth = 0;
			//output-->
			output = "";
			//<--output
		}
		var parentNode = pActNode.getParent();
		var rightNeighbour = pActNode.getRightNeighbour();
		var leftNeighbour = pActNode.getLeftNeighbour();
		var children = pActNode.getChildren();
		var childrenLen = children.length;
		//lege Eigenschaften active u. opened an fuer aktuelle node
		pActNode.addProperty("active", false);
		pActNode.addProperty("opened", false);
		//wenn pStartNode nicht root war, dann setzte fuer  erste Node parentNode u. leftNeighbour auf null
		if(pActNode == pStartNode)
		{
			parentNode = null;
			leftNeighbour = null;
		}
		
		var actId = pActNode.getId();
			
		//set menu_empty or v_line - list
		var pStartNodeNeighbours = new Array();
		var actRightNeighbour = pStartNode;
		while(actRightNeighbour != null)
		{	
			pStartNodeNeighbours[pStartNodeNeighbours.length] = actRightNeighbour;
			actRightNeighbour = actRightNeighbour.getRightNeighbour();
		}
		var fillerImgList = new Array();
		var actParentNode = pActNode;
		while(actParentNode.getParent() != null && !(inArray(actParentNode, pStartNodeNeighbours)))
		{
			actParentNode = actParentNode.getParent();
			if(actParentNode.getRightNeighbour() == null)
				fillerImgList[fillerImgList.length] = this.imagesDir + this.idPrefixImages + "menu_empty.gif";
			else
				fillerImgList[fillerImgList.length] = this.imagesDir + this.idPrefixImages + "menu_v_line.gif";
		}
		fillerImgList.reverse();
		
		var actStyle = "style=\"display:none;\"";
		if(pActNode == pStartNode || (inArray(pActNode, pStartNodeNeighbours)))
		{
			actStyle = "";
		}
		//output-->
		output += "<div id=\"" +actId+ "\" " +actStyle+ ">\n";
		
		for(i=0; i<=pDepth; i++)
		{
			if(pActNode != this.rootNode || childrenLen != 0)
			{
				if(i == (pDepth))
				{
					var num1 = 0;
					var num3 = 0;
					(leftNeighbour != null || parentNode != null) ? num1 = 1 : num1 = 0;
					(rightNeighbour != null) ? num3 = 1 : num3 = 0;
		
					output += "<a href=\"javascript:" +this.getName()+ ".reverseDisplay('" +actId+ "');\"><img src=\"";
					if(childrenLen != 0)
					{
						output += this.imagesDir + this.idPrefixImages + "menu_plus_" +num1+ "1" +num3+ ".gif";
					}
					else
					{
						if(pActNode == this.rootNode)
							output += this.imagesDir + this.idPrefixImages + "menu_empty.gif";
						else
							output += this.imagesDir + this.idPrefixImages + "menu_nosub_" +num1+ "1" +num3+ ".gif";
					}
					output += "\" id=\"" +this.idPrefixSwitch + actId+ "\" style=\"border:0;margin:0;vertical-align:top;\" /></a>";
				}
				else
				{
					output += "<img src=\"";
					output += fillerImgList[i];
					output += "\" style=\"border:0;margin:0;vertical-align:top;\" />";
				}
			}
		}
		
		var itemNum3 = 0;
		//(childrenLen > 0) ? itemNum3 = 1 : itemNum3 = 0;
	
		if(this.sensitiveSymbols == true)
			output += "<a href=\"javascript:" +this.getName()+ ".activateItem('" +actId+ "');\">";
		output += "<img src=\"";
		output += this.imagesDir + this.idPrefixImages+ "menu_item_";
		if(pActNode == this.rootNode && childrenLen == 0) output += "root_";
		output += "00" +itemNum3+".gif\"";
		output += " id=\"" +this.idPrefixFolder+ "" +actId+ "\" style=\"border:0;margin:0;vertical-align:top;\" />";
		if(this.sensitiveSymbols == true)
			output += "</a>";
		output += "<span id=\"" +this.idPrefix + actId+ "\">";
		
		if(!pArrKeypairs[actId])
			output += "<span style=\"font-size:11px;font-family:arial;color:#FF0000;\">["+actId+"]</span>";
		else
			output += "<span style=\"vertical-align:middle;margin-left:3px;\">"+pArrKeypairs[actId]+"</span>";

		output += "</span>";
		output += "</div>\n";
		//<--output
		
		
		var firstChild = children[0];
		if((childrenLen > 0) && ((pDepth < pMaxDepth) || (pMaxDepth == -1)))
		{
			pDepth++;
			pActNode = firstChild;
			this.getFileTree(pStartNode, pArrKeypairs, pMaxDepth, pActNode, pChildNum, pDepth);
			pDepth--;
		}
		if(rightNeighbour != null)
		{
			pActNode = rightNeighbour;
			
			this.getFileTree(pStartNode, pArrKeypairs, pMaxDepth, pActNode, pChildNum, pDepth);
		}
		return output;
	}
	
	/**
	 * haenge baum in dokument ein
	 * @param Object targetNode
	 * @param Array nodeHtml (structure: \[<id>:<html>,[<id>:<html>, ...]\])
	 * @param Array hiddenULPositions (list of positions in sub-dom-tree of ul's that should not be displayed
	 */
	Tree.prototype.hookTree = function(targetNode, /*optional*/nodeHtml, hiddenULPositions)
	{
		if(typeof targetNode == "object")
			this.targetNode = targetNode;
		else
			return false;
		
		this.reset();
		var node = this.getCurrent();
		
		var li = null;
		var html = null;
		var uls = [];
		
		var treeInteractivity = function()
		{
			var obj = this;
			// if the element is not na <a>, return
			if (obj.tagName != 'A'
				|| obj.className == 'leaf') return;
			// change class
			obj.className = obj.className == 'plus' ? 'minus' : 'plus';
			// get associated <li>
			var liObj = obj.parentNode;
			var ulObjs = liObj.getElementsByTagName('ul');
			// if there is no internal <ul>, return
			if(!ulObjs.length) return;
			// hide/show internal <ul>
			ulObjs[0].style.display = ulObjs[0].style.display == 'none' ? 'block' : 'none';
			//reset display values of <li>'s for IE-display-bug.
			if (document.all && !navigator.userAgent.match(/Opera/))
			{
				var firstUL = obj;
				while(firstUL.parentNode.tagName == 'LI' || firstUL.parentNode.tagName == 'UL')
					firstUL = firstUL.parentNode;
				var firstULChildren = firstUL.getElementsByTagName('ul');
				for(var i=0;i<firstULChildren.length;i++)
				{	
					var prevDisplay = firstULChildren[i].style ? firstULChildren[i].style.display : 'block';
					firstULChildren[i].style.display = (prevDisplay == 'none') ? 'block' : 'none'; 
					firstULChildren[i].style.display = prevDisplay;
				}
			}
		};
		
		var i_ul = 0;
		while(this.hasNext())
		{
			var status = "minus";
			var depth = node.getProperty("depth");
			
			if(!node.getLeftNeighbour())
			{
				uls[depth] = document.createElement("ul");
				for(var i in hiddenULPositions)
					if(hiddenULPositions[i] == i_ul)
						uls[depth].style.display = 'none';
					else if(hiddenULPositions[i] == i_ul+1)
						status = 'plus';
				if(node.isRootNode())
				{
					uls[depth].className = "tree";
					targetNode.appendChild(uls[depth]);
				}
				else
					li.appendChild(uls[depth]);
				i_ul++;
			}
			
			li = document.createElement("li");
			if(!node.getRightNeighbour())
				li.className = "last";
			if(!node.hasChildren())
				status = 'leaf';
			html = '<a class="'+status+'"></a>';
			html+= nodeHtml[node.getId()] ? nodeHtml[node.getId()] : node.getId();
			li.innerHTML = html;
			li.firstChild.onclick = treeInteractivity;
			uls[depth].appendChild(li);
			
			node = this.getNext();
		}
	}
	
	Tree.prototype.getHiddenULPositions = function()
	{
		var result = [];
		if(typeof this.targetNode == "object")
		{
			var targets = this.targetNode.getElementsByTagName('ul');
			for(var i=0;i<targets.length;i++)
				if(targets[i].style.display == 'none')
					result[result.length] = i;
		}
		return result;
	}
	
	Tree.prototype.openTree = function()
	{
		var result = [];
		if(typeof this.targetNode == "object")
		{
			var aTargets = this.getElementsByClass('(plus|minus)', this.targetNode, 'a');
			var ulTargets = this.targetNode.getElementsByTagName('ul');
			for(var i=0;i<aTargets.length;i++)
				aTargets[i].className = 'minus';
			for(var i=1;i<ulTargets.length;i++)
				ulTargets[i].style.display = 'block';
		}
		return result;
	}
	
	Tree.prototype.closeTree = function()
	{
		var result = [];
		if(typeof this.targetNode == "object")
		{
			var aTargets = this.getElementsByClass('(plus|minus)', this.targetNode, 'a');
			var ulTargets = this.targetNode.getElementsByTagName('ul');
			for(var i=0;i<aTargets.length;i++)
				aTargets[i].className = 'plus';
			for(var i=1;i<ulTargets.length;i++)
				ulTargets[i].style.display = 'none';
		}
		return result;
	}
	
//erweitere Tree-Klasse um getsubtreeObjects-Funktion (alle unterobjekte einer Node zurueckgeben)///////////////////////////////////////////

	Tree.prototype.getSubtreeObjects = function(pStartNode, pMaxDepth, pActNode, pChildNum, pDepth)
	{
		if(!pStartNode)
		{
			pStartNode = this.rootNode;
		}
		if(!pMaxDepth)
		{
			pMaxDepth = -1;
		}
		if(!pActNode)
		{
			subtreeObjects = new Array();
			pActNodeChildren = pStartNode.getChildren();
			pActNode = null;
			if(pActNodeChildren[0])
			{
				pActNode = pActNodeChildren[0];
			}
			pDepth = 0;
		}
		if(pActNode != null)
		{
		var rightNeighbour = pActNode.getRightNeighbour();
			
			//save return value in variable
			subtreeObjects[subtreeObjects.length] = pActNode;
			//end save
			
			var children = pActNode.getChildren();
			var firstChild = children[0];
			if((children.length > 0) && ((pDepth < pMaxDepth) || (pMaxDepth == -1)))
			{
				pDepth++;
				pActNode = firstChild;
				this.getSubtreeObjects(pStartNode, pMaxDepth, pActNode, pChildNum, pDepth);
				pDepth--;
			}
			if(rightNeighbour != null)
			{
				pActNode = rightNeighbour;
				this.getSubtreeObjects(pStartNode, pMaxDepth, pActNode, pChildNum, pDepth);
			}
		}
		return subtreeObjects;
	}
	
//erweitere Tree-Klasse um reverseDisplay-Funktion (subtree oeffnen/schliessen)/////////////////////////////////////////////////////////////

	Tree.prototype.reverseDisplay = function(pId, /*optional*/neverClose)
	{
		var actNode = this.getNodeById(pId);
		if(!actNode) return;
		var actNodeChildren = actNode.getChildren();
		var actNodeSubtreeObjects = this.getSubtreeObjects(actNode);
		//1. alle childs von pId u. deren childs ausblenden oder einblenden
		var actNodeFirstChildDisplay = "";
		
		if(actNodeChildren[0] != null)
		{
			var actNodeFirstChildDisplay = document.getElementById(actNodeChildren[0].getId()).style.display;
		}
		
		if(neverClose == true && actNodeFirstChildDisplay == "")
		{
			//nothing
		}
		else
		{
			if(actNodeChildren.length > 0)
			{
				///////////////////////////////////////////////
				//set act button to '-'
				var objPath = document.getElementById(this.idPrefixSwitch + pId);
				var oldSrc = objPath.src;
				var oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
				var oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
				var newImg = "";
				
				if(oldImg.indexOf("plus") != -1)
				{
					var s = oldImg.split("plus");
					newImg = s[0] +"minus"+ s[1];
					actNode.setProperty("opened", true);
				}
				else if(oldImg.indexOf("minus") != -1)
				{
					var s = oldImg.split("minus");
					newImg = s[0] +"plus"+ s[1];
					actNode.setProperty("opened", false);
				}
				else
				{
					newImg = oldImg;
				}
				objPath.src = oldPath + newImg;
				
				///////////////////////////////////////////////
				//set act menu_item image to '001' or '000'
				objPath = document.getElementById(this.idPrefixFolder + pId);
				oldSrc = objPath.src;
				oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
				oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
				newImg = "";
				if(oldImg.indexOf("001") != -1)
				{
					var s = oldImg.split("001");
					newImg = s[0] +"000"+ s[1];
				}
				else if(oldImg.indexOf("000") != -1)
				{
					var s = oldImg.split("000");
					newImg = s[0] +"001"+ s[1];
				}
				else
				{
					newImg = oldImg;
				}
	
				objPath.src = oldPath + newImg;
	
				///////////////////////////////////////////////
		
				if(actNodeFirstChildDisplay  == "none")
				{
					///////////////////////////////////////////////
					//show all sub-buttons of next level
					for(var i=0; i<actNodeChildren.length; i++)
						document.getElementById(actNodeChildren[i].getId()).style.display = "";
				}
				else
				{
					for(var i=0; i<actNodeSubtreeObjects.length; i++)
					{
						///////////////////////////////////////////////
						//hide all sub-buttons
						var actId = actNodeSubtreeObjects[i].getId();
						document.getElementById(actId).style.display = "none";
						actNodeSubtreeObjects[i].setProperty("opened", false);
						///////////////////////////////////////////////
						//set all sub-buttons to '+'
						objPath = document.getElementById(this.idPrefixSwitch + actId);
						oldSrc = objPath.src;
						oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
						oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
						newImg = "";
						if(oldImg.indexOf("minus") != -1)
						{
							var s = oldImg.split("minus");
							newImg = s[0] +"plus"+ s[1];
						}
						else
						{
							newImg = oldImg;
						}
						objPath.src = oldPath + newImg;
						
						///////////////////////////////////////////////
						//set all sub-menu_item images to '000'
						objPath = document.getElementById(this.idPrefixFolder + actId);
						oldSrc = objPath.src;
						oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
						oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
						newImg = "";
						if(oldImg.indexOf("001") != -1)
						{
							var s = oldImg.split("001");
							newImg = s[0] +"000"+ s[1];
						}
						else
						{
							newImg = oldImg;
						}
						objPath.src = oldPath + newImg;
					}
				}
			}
		}
		
		//call user-func
		if (typeof this.reverseDisplayUserFunc == "function")
			if(this.reverseDisplayUserFuncArgs.length > 0)
				this.reverseDisplayUserFunc(this.reverseDisplayUserFuncArgs);
			else
				this.reverseDisplayUserFunc();
	}

	/**
	 * @param Function func
	 * @param optional Array args
	 */
	
	Tree.prototype.setReverseDisplayUserFunc = function(func, args)
	{
		if (typeof func == "function")
		{
			this.reverseDisplayUserFunc = func;
			this.reverseDisplayUserFuncArgs = args;
		}
	}
	
	/**
	 * erweitere Tree-Klasse um activateItem-Funktion (einen folder aktivieren (img tausch))
	 *
	 * @param string pId
	 * @param optional Function func : Funktion, die nach Ablauf dieser Funktion aufgerufen werden soll
	 * [@param optional param, ...] beliebige Parameter f�r func 
	 */	
	Tree.prototype.activateItem = function(pId)
	{
		var actNode = this.getNodeById(pId);
		var treeNodes = this.getNodes();
			
		//switch act menu_item image to active and deactivate all others
		//and activate current
		var objPath = document.getElementById(this.idPrefixFolder + pId);
		
		var oldSrc = objPath.src;
		var oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
		var oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
		var newImg = "";
		
		if(oldImg.indexOf("active") == -1)
		{
			oldImgFilename = oldImg.substring(0, oldImg.lastIndexOf("."));
			oldImgExt = oldImg.substr(oldImg.lastIndexOf("."));
			newImg = oldImgFilename + "_active" + oldImgExt;
			objPath.src = oldPath + newImg;
			actNode.setProperty("active", true);
		}
		//deactivate all others
		var treeNodes = this.getNodes();
		for(i=0; i<treeNodes.length; i++)
		{
			if(treeNodes[i] != actNode)
			{
				objPath = document.getElementById(this.idPrefixFolder + treeNodes[i].getId());
				oldSrc = objPath.src;
				oldImg = oldSrc.substr(oldSrc.lastIndexOf("/")+1);
				oldPath = oldSrc.substring(0,oldSrc.lastIndexOf("/")+1);
				newImg = "";
				if(oldImg.indexOf("active") != -1)
				{
					var s = oldImg.split("_active");
					newImg = s[0] + s[1];
					objPath.src = oldPath + newImg;
					treeNodes[i].setProperty("active", false);
				}
			}
		}
	}
	
	/**
	 * oeffne alle subtrees oder alle subtrees derjenigen node-ids die uebergeben wurden
	 * @param optional Array ids
	 */
	 
	Tree.prototype.open = function(/*optional*/ids)
	{	//array wurde uebergeben?
		if(!(typeof ids == "object" && ids instanceof Array))
		{
			ids = new Array();
			for(var i in this.nodes)
				if(this.nodes[i].getChildren().length > 0)
					ids[ids.length] = this.nodes[i].getId();
		}
		for(var i in ids)
			this.reverseDisplay(ids[i], true);
	}
	 
	/**
	 * schliesse alle subtrees alle subtrees derjenigen node-ids die uebergeben wurden
	 * @param optional Array ids
	 */
	  
	Tree.prototype.close = function(/*optional*/ids)
	{	//array wurde uebergeben?
		if(!(typeof ids == "object" && ids instanceof Array))
			ids = new Array(this.getRootNode().getId());
		for(var i in ids)
			this.reverseDisplay(ids[i]);
	}
	
	/**
	 * gebe geoeffnete nodes zurueck
	 */
	
	Tree.prototype.getOpenedNodes = function()
	{
		var result = new Array();
		for(var i in this.nodes)
			if(this.nodes[i].getProperty("opened"))
				result[result.length] = this.nodes[i];
		return result;
	}

	/**
	 * gebe aktive node (als objekt) zurueck
	 */
	Tree.prototype.getActiveNode = function()
	{
		var nodes = this.getNodes();
		var activeObject = false;
		for(i=0; i<nodes.length; i++)
			if(nodes[i] && nodes[i].getProperty("active") == true)
				activeObject = nodes[i];
		return activeObject;
	}

	/**
	 * gebe aktive node-id zurueck
	 */
	Tree.prototype.getActiveNodeId = function()
	{
		var activeObject = this.getActiveNode();
		var nodeId = null;
		if(activeObject)
			return activeObject.getId();
	}
