/*
 * 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)
	{
		var strClassNameToBeRemoved = '';
		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();
	}
}
