/*
 * NavTree class
 *
 * requirements:
 * - the menu should be a UL element with submenus also being UL elements placed within LI elements
 * - list items being a submenu (and thus containing a submenu) should have at least the classname 'cat'.
 * - list items being a item should have at least the classname 'item'.
 * - the list item that should be shown on page-load should contain the classname 'selected'
 */
function NavTree(strUberUlId)
{
	this.strNavTopId = strUberUlId;
	this.nodNavTop = '';
	
	this.intMaxLevelVisibleOnReset = 0; // level 1 houdt in: de top lists + de lists daaronder met hun items
	
	this.blnAutoFoldNeighbours = true;
	
	this.blnActive = true;

	
	
	/*
	 * constructor
	 *
	 * @access public
	 */	
	NavTree.prototype.init = function()
	{
			// determine the top-node
			
		if (!this.strNavTopId)
		{
			this.blnActive = false;
		}
		else
		{
			this.nodNavTop = document.getElementById(this.strNavTopId);
			if (this.nodNavTop==null) this.blnActive=false;
		}

			// indien active niet false dan verder gaan
		if (this.blnActive)
		{
			this.reset();
			this.addEventHandlers();
			this.showSelectedItem();
				// menu tonen
			this.nodNavTop.style.display = 'block';
		}
	}
	

	
	/*
	 * reset, toont alle menu's met diepte <= intMaxLevelVisibleOnReset
   *
   * @access public
   */	
	NavTree.prototype.reset = function()
	{
		arrNodes = this.nodNavTop.getElementsByTagName('ul');
		
		for (var i=0;i<arrNodes.length;i++)
		{
			nodThisNode = arrNodes[i];
			intLevel = this.getUlLevel(nodThisNode);
			nodThisNode.style.display = (intLevel<=this.intMaxLevelVisibleOnReset) ? 'block':'none';
		}
	}


	
	
	/*
	 * zet click handlers op items
   *
   * @access private
   */	
	NavTree.prototype.addEventHandlers = function()
	{
			// list items zoeken
		arrLiNodes = this.nodNavTop.getElementsByTagName('li');
		
		for (var i=0;i<arrLiNodes.length;i++)
		{
			nodCurrentNode = arrLiNodes[i];
			
			nodCurrentNode.pointer = this;

			nodCurrentNode.onmouseover = function() { this.pointer.doLiMouseOver(this); };
			nodCurrentNode.onmouseout = function() { this.pointer.doLiMouseOut(this); };
			nodCurrentNode.onclick = function() { this.pointer.doLiClick(this) };
			
			if (window.attachEvent)
			{
				nodCurrentNode.attachEvent('onclick',this.cancelBubble);
				nodCurrentNode.attachEvent('onmouseover',this.cancelBubble);
				nodCurrentNode.attachEvent('onmouseout',this.cancelBubble);
			}
			else
			{
				nodCurrentNode.addEventListener('click',this.cancelBubble,false);
				nodCurrentNode.addEventListener('mouseover',this.cancelBubble,false);
				nodCurrentNode.addEventListener('mouseout',this.cancelBubble,false);
			}
		}
		arrUlNodes = this.nodNavTop.getElementsByTagName('ul');
		arrUlNodes[arrUlNodes.length] = this.arrUlNodes;
		
		for (var i=0;i<arrUlNodes.length;i++)
		{
			nodCurrentNode = arrUlNodes[i];
			if (window.attachEvent)
			{
				nodCurrentNode.attachEvent('onmouseover',this.cancelBubble);
				nodCurrentNode.attachEvent('onmouseout',this.cancelBubble);
			}
			else
			{
				nodCurrentNode.addEventListener('mouseover',this.cancelBubble,false);
				nodCurrentNode.addEventListener('mouseout',this.cancelBubble,false);
			}
		}
	}


	
	/*
	 * zoekt het eerst li-item dat in de className 'selected' heeft en zorgt dat die zichtbaar is.
   *
   * @access private
   */	
	NavTree.prototype.showSelectedItem = function()
	{
		var blnSelectedFound = false;
		var nodSelectedLiItem = '';
		
		arrLiItems = this.nodNavTop.getElementsByTagName('li');
		for (var i=0;i<arrLiItems.length;i++)
		{
			nodThisNode = arrLiItems[i];
			if 	(nodThisNode.className.indexOf('selected')>=0)
			{
				blnSelectedFound = true;
				nodSelectedLiItem = nodThisNode;
			}
		}
						
		if (blnSelectedFound==true)
		{
				// li found, eerste ul ophalen, dat is het startpunt van 'onze reis' ;)
				// indien geen ul onder het item dan de parentNode-ul pakken
			var nodSelectedUlItem = nodSelectedLiItem.parentNode;
			var arrUlChildNodes = nodSelectedLiItem.getElementsByTagName('ul');
			if (arrUlChildNodes.length>0)
			{
				nodSelectedUlItem = arrUlChildNodes[0];
			}	
			
			var arrUls = new Array();
			var blnContinue = true;
			var nodWorking = nodSelectedUlItem;
			var intCount = 0;
			
			arrUls[arrUls.length] = nodSelectedUlItem;
						
			while (blnContinue && intCount<20)
			{
					// hier alvast om te voorkomen dat loop buiten ul terecht komt
				if (nodWorking==this.nodNavTop) blnContinue = false;
				nodWorking = nodWorking.parentNode;
				if (nodWorking.nodeName.toLowerCase()=='ul') arrUls[arrUls.length] = nodWorking;
				
				if (nodWorking==this.nodNavTop || !nodWorking.parentNode) blnContinue = false;
				intCount++;
			}
			
				// array met uls gebouwd, reversen en zichtbaar maken
			arrUls = arrUls.reverse();
			for (var i=0;i<arrUls.length;i++)
			{
				this.showSubMenu(arrUls[i]);
			}
		}
	}
	
	
	
	/*
	 * bepaalt de afstand tot de navTop node, of (indien parentNode ook gegeven) tot de parentNode
   *
   * @access private
   */	
	NavTree.prototype.getUlLevel = function(nodSource,nodParent)
	{
			// indien parentNode niet opgegeven dan is parentNode de topNode van de list
		if (!nodParent) nodParent = this.nodNavTop;
		
		intLevel = 0;
		intCount = 0;
		intSafetyCatch = 20;
		blnContinue = true;
		
		if (nodSource && nodSource.nodeName.toLowerCase()=='ul')
		{
			nodWorking =nodSource;
			while (blnContinue && intCount<intSafetyCatch)
			{
				if (nodWorking.parentNode) nodWorking = nodWorking.parentNode;

					// level 1 ophogen
				if (nodWorking.nodeName.toLowerCase()=='ul') intLevel++;
					// check if exit
				if (nodWorking.nodeName.toLowerCase()!='ul' && nodWorking.nodeName.toLowerCase()!='li') 
				{
					blnContinue=false;
					intLevel = -1;
				}
				if (nodWorking == nodParent) blnContinue=false;
				
					// counter ophogen
				intCount++;
			}
		}
		return intLevel;
	}



	/*
	 * wisselt de zichtbaarheid van het submenu
   *
   * @param HTMLLiNode nodSource
   * @access private
   */		
	NavTree.prototype.toggleSubMenu = function(nodSource)
	{
			// ul's ophalen
		arrUlNodes = nodSource.getElementsByTagName('ul');

		if (arrUlNodes.length>0)
		{
			nodTheSubMenu = arrUlNodes[0];
			
			if (nodTheSubMenu.style.display=='none') 
			{
				this.showSubMenu(nodTheSubMenu);
				if (this.blnAutoFoldNeighbours) this.hideNeighbours(nodTheSubMenu);
			}
			else if (nodTheSubMenu.style.display=='block') 
			{
				this.hideSubMenu(nodTheSubMenu);
			}
		}	
	}	



	/*
	 * maakt het betreffende menu zichtbaar. zet classname 'visible' op het parent-li-element
   *
   * @param HTMLUlNode nodSource
   * @access private
   */			
	NavTree.prototype.showSubMenu = function(nodSourceUl)
	{
		this.setUlParentLiVisibleClassName(nodSourceUl);
		nodSourceUl.style.display = 'block';
	}



	/*
	 * maakt het betreffende menu onzichtbaar, en alle submenu's daaronder
   *
   * @param HTMLUlNode nodSource
   * @access private
   */
	NavTree.prototype.hideSubMenu = function(nodSourceUl)
	{
		this.removeUlParentLiVisibleClassName(nodSourceUl);		
		nodSourceUl.style.display = 'none';
		
		arrNodesUl = nodSourceUl.getElementsByTagName('ul');
		for (var i=0;i<arrNodesUl.length;i++)
		{
			this.removeUlParentLiVisibleClassName(arrNodesUl[i]);
			arrNodesUl[i].style.display = 'none';
		}
	}


	
	/*
	 * zoekt de parent-li (if any) en voegt daar aan de classname 'visible' toe
   *
   * @param HTMLUlNode nodSource
   * @access private
   */
	NavTree.prototype.setUlParentLiVisibleClassName = function(nodSourceUl)
	{
		if (nodParent=nodSourceUl.parentNode)
		{
			if(nodParent.nodeName.toLowerCase() == 'li') 
			{
				nodParent.className = nodParent.className + ' visible';
			}
		}
	}
	
	

	/*
	 * zoekt de parent-li (if any) en voegt daar aan de classname 'visible' toe
   *
   * @param HTMLUlNode nodSource
   * @access private
   */
	NavTree.prototype.removeUlParentLiVisibleClassName = function(nodSourceUl)
	{
		if (nodParent=nodSourceUl.parentNode)
		{
			if(nodParent.nodeName.toLowerCase() == 'li') 
			{
				nodParent.className = nodParent.className.replace('visible','');
			}
		}	
	}

	

	/*
	 * maakt alle
   *
   * @param HTMLUlNode nodSource
   * @access private
   */
	NavTree.prototype.hideNeighbours = function(nodSourceUl)
	{
			// parent ul zoeken.
			// 1st parent LI zoeken
		var intSafety = 20;
		var intCount = 0;
		var blnContinue = true;
		var nodWorking = nodSourceUl;
		var nodParent;
		while (blnContinue && intCount<intSafety)
		{
			nodWorking = nodWorking.parentNode;
			if (nodWorking.nodeName.toLowerCase()=='ul')
			{
				nodParent = nodWorking;
				blnContinue = false;
			}
			intCount++;
		}

		arrUlNodes = nodParent.getElementsByTagName('ul');
		for (var i=0;i<arrUlNodes.length;i++)
		{
			nodCurrent = arrUlNodes[i];
			intDistance = this.getUlLevel(nodCurrent,nodParent);
			
			if (intDistance==1 && nodCurrent!=nodSourceUl) this.hideSubMenu(nodCurrent);
		}
	}	
	


	/*
	 * dingen doen als op een listitem geklikt wordt
   *
   * @access private
   */	
	NavTree.prototype.doLiClick = function(nodSource)
	{
			// here used to be more code but the IE event-registration model does a good imitation of a vacuum cleaner...
		nodTarget = nodSource;
		
			// 1st parent LI zoeken
		var intSafety = 20;
		var intCount = 0;
		var blnContinue = true;
		var nodWorking = nodTarget;
		while (blnContinue && intCount<intSafety)
		{
			if (nodWorking.nodeName.toLowerCase()=='li')
			{
				nodTarget = nodWorking;
				blnContinue = false;
			}
			else
			{
				nodWorking = nodWorking.parentNode;
			}
			intCount++;
		}

		if (nodTarget.className.indexOf('cat')>=0) nodTarget.pointer.toggleSubMenu(nodTarget);
		
		return false;
	}



	/*
	 * dingen doen als over een listitem heen gehoverd wordt
   *
   * @access private
   */	
	NavTree.prototype.doLiMouseOver = function(nodSource)
	{
		var strClassNameToBeAdded = '';
		if (nodSource.className.indexOf('cat')>=0) 
		{
//			strClassNameToBeAdded = (nodSource.className.indexOf('visible')>=0) ? ' hover cat_hover_v' : ' hover cat_hover';
			strClassNameToBeAdded = ' hover cat_hover';
		}
		if (nodSource.className.indexOf('item')>=0) strClassNameToBeAdded = ' hover item_hover';
				
		nodSource.className = nodSource.className + strClassNameToBeAdded;
		
		return false;
	}

	

	/*
	 * dingen doen als over een listitem heen gehoverd wordt
   *
   * @access private
   */	
	NavTree.prototype.doLiMouseOut = function(nodSource)
	{
		if (nodSource.className.indexOf('hover cat_hover')>=0) strClassNameToBeRemoved = ' hover cat_hover';
		if (nodSource.className.indexOf('hover item_hover')>=0) strClassNameToBeRemoved = ' hover item_hover';
		
		nodSource.className = nodSource.className.replace(strClassNameToBeRemoved,'');
		
		return false;
	}



	/*
	 * zorgen dat het bij 1 gehoverd item blijft
   *
   * @access private
   */	
	NavTree.prototype.cancelBubble = function(e)
	{
		if (!e) var e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
		
//		e.cancelBubble = true;
//		if (e.stopPropagation) e.stopPropagation();
	}
}

