/* 
	This file enhances the navigation, that is normaly build as a CSS hover menu (suckerfish).
	For the case, that JS is turned on, the :hovers will be removed and replaces by a more usable behaviour
*/

function teco_menu()
{
	var isIE=((navigator.userAgent.toLowerCase().indexOf('msie')>-1)?true:false);
	var isIE6=((navigator.userAgent.toLowerCase().indexOf('msie 6')>-1)?true:false);
	var isIE7=((navigator.userAgent.toLowerCase().indexOf('msie 7')>-1)?true:false);
	
	var debugOutput=null;
	var debug=false;
	
	var menuIsOut=false;
	
	function init()
	{
		log2debug("init");
 		removeHovers();
		prepareMenu();
	}
	this.init=init;
	
	var log2debug=function(str)
	{
		if(debug)
		{
			if(debugOutput===null)
			{
				debugOutput=document.getElementById("debug");
				if(debugOutput===null)
				{
					debugOutput=document.createElement("div");
					debugOutput.id="debug";
					debugOutput.style.border="1px solid #000";
					debugOutput.style.backgroundColor="#FFF";
					debugOutput.style.width="300px";
					debugOutput.style.position="absolute";
					debugOutput.style.zIndex="999";
					debugOutput.style.top="0px";
					debugOutput.style.right="10px";
					debugOutput.style.padding="4px";
					debugOutput.style.minHeight="10px";
					document.getElementsByTagName("body")[0].appendChild(debugOutput);
				}
			}
			var d=new Date();
			var timeStr=d.getHours()+":"+d.getMinutes()+"."+d.getSeconds()+":"+d.getMilliseconds();
			debugOutput.appendChild(document.createElement("br"));
			debugOutput.appendChild(document.createTextNode(timeStr+": "+str));
		}
	}
	this.log2debug=log2debug;
	
	function removeHovers()
	{
		log2debug("removehovers");
		if(document.styleSheets && !isIE) //in IE7 it works without removing the rules
		{
			var styles=document.styleSheets[0].cssRules[2].styleSheet;
			styles.disabled=true;
// 			for(var i=0; i<styles.cssRules.length; i++)
// 			{
// 				alert(styles.deleteRule(i));
// 			}
		}
	}
	
	function prepareMenu()
	{
		log2debug("preparemenu");
		var menus=new Array("mainnav","nav2");
		for(var m in menus)
		{
			var menu=document.getElementById(menus[m]);
			var lis=menu.getElementsByTagName("li");
			for(var li in lis)
			{
				addEvent(lis[li],"mouseover",function () { showMenuPoint(this.id); });
				//addEvent(lis[li],"mouseout",function () { hideAllMenusInThisLevel(this.id); });
			}
		}
	}
	
	var showMenuPoint=function(menuPointId)
	{
		log2debug("showmenupoint("+menuPointId+")");
		if(menuIsOut)
		{
			disableAllLinks();
		}
		else
		{
			menuIsOut=true;
		}
		
		document.onclick=foo;
		var menuPoint=document.getElementById(menuPointId);
		
		//if second level should be fold out (first level hovers), remove hover class from all other list points, that are not in this leaf
		//this part was originally written for the root level only. But it's necessary for all levels, so please excuse the variable names
		if(1 || menuPoint.parentNode.id=="mainnav" || menuPoint.parentNode.id=="nav2")
		{
			for(var i=0; i<menuPoint.parentNode.childNodes.length; i++)
			{
				var rootChild=menuPoint.parentNode.childNodes[i];
				if(rootChild.nodeType===1 && rootChild.id!==menuPointId)
				{
					var elements=getElementsByClass("hover",rootChild,"li");
					for(var z=0; z<elements.length; z++)
					{
						elements[z].className=elements[z].className.replace(/hover/g,"");
					}
				}
			}
		}
		
		if(menuPoint.className.indexOf("haschilds")>=0)
		{
			//alert(menuPointId);
			menuPoint.className="haschilds hover";
			/*
			var submenu=menuPoint.getElementsByTagName("ul")[0];
			for(var i=0; i<submenu.childNodes.length; i++)
			{
				if(submenu.childNodes[i].nodeType===1 && submenu.childNodes[i].nodeName==="li" && submenu.childNodes[i].className.indexOf("hover")>=0)
				{
					submenu.childNodes[i].className=submenu.childNodes[i].className.replace(/hover/g,"");
				}
			}
			*/
		}
		
		hideAllMenusInThisLevel(menuPointId);
		
		if(isAncestor(menuPoint,document.getElementById("mainnav")))
		{
			hideAllMenus("nav2");
		}
		else if(isAncestor(menuPoint,document.getElementById("nav2")))
		{
			hideAllMenus("mainnav");
		}
	}
	
	var foo=function()
	{
		log2debug("foo");
		hideAllMenus(null,true);
	}
	
	var hideAllMenus=function(targetNav,remove)
	{
		log2debug("hideAllMenus");
		var t1=new Date();
		if(targetNav!==null && targetNav.length>0)
		{
			log2debug("hideAllMenus("+targetNav+")");
			var menus=new Array(targetNav);
		}
		else
		{
			log2debug("hideAllMenus(both)");
			var menus=new Array("mainnav","nav2");
		}
		
		if(remove)
		{
			//removeEvent(document,"click",foo);
			document.onclick=null;
		}
		
		for(var m in menus)
		{
			var menu=document.getElementById(menus[m]);
			var lis=menu.getElementsByTagName("li");
			for(var i=0; i<lis.length; i++)
			{
				var obj=document.getElementById(lis[i].id); //20
				if(obj.className.indexOf("hover")>=0) //this if is due to performance reasons.
				{
					obj.className=obj.className.replace(/hover/g,""); //40
				}
				
				//obj.className=obj.className.replace(/hover/g,""); //150
			}
		}
		
		if(typeof targetNav!=="string")
		{
			enableAllLinks();
			menuIsOut=false;
		}
		
		var t2=new Date();
	}
	
	var hideAllMenusInThisLevel=function(itemId)
	{
		log2debug("hideAllMenusInThisLevel("+itemId+")");
		var item=document.getElementById(itemId);
		var parent=item.parentNode;
		for(var i=0; i<parent.childNodes.length; i++)
		{
			if(parent.childNodes[i]===item)
			{
				continue;
			}
			var obj=parent.childNodes[i];
			
			if(obj.nodeType===1)
			{
				//console.log(obj.id + "=" + obj.className);
				var oldClass=obj.className;
				obj.className=obj.className.replace(/hover/g,"");
			}
		}
	}
	
	
	
	var disableAllLinks=function()
	{
		log2debug("disableAllLinks");
		var links=document.getElementsByTagName("a");
		var count=0;
		
		var mainnav=document.getElementById("mainnav");
		var nav2=document.getElementById("nav2");
		
		for(var i=0; i<links.length; i++)
		{
			if(!(isAncestor(links[i],mainnav) || isAncestor(links[i],nav2)))
			{
				var oldAttribute=links[i].getAttribute("onclick");
				if(typeof oldAttribute!=="string")
				{
					links[i].setAttribute("onclick","return false; ");
					count++;
				}
				else
				{
					if(oldAttribute.substr(0,14)!=="return false; ")
					{
						links[i].setAttribute("onclick","return false; "+oldAttribute);
						count++;
					}
				}
			}
		}
		//alert(count);
	}
	
	var enableAllLinks=function()
	{
		log2debug("enableAllLinks");
		var links=document.getElementsByTagName("a");
		for(var i=0; i<links.length; i++)
		{
			var oldAttribute=links[i].getAttribute("onclick");
			if(typeof oldAttribute==="string" && oldAttribute.substr(0,14)==="return false; ")
			{
				if(oldAttribute.length<=14)
				{
					links[i].removeAttribute("onclick");
				}
				else
				{
					links[i].setAttribute("onclick",oldAttribute.substr(14));
				}
			}
		}
	}
}

function isAncestor(child,element2check)
{
	if(!(typeof(child)==="object" && child.parentNode))
	{
		throw new TypeError("isAncestor: First argument must be a DOM Node.");
	}
	
	if(!(typeof(element2check)==="object" && element2check.parentNode))
	{
		//console.log(child+" "+element2check);
		throw new TypeError("isAncestor: Second argument must be a DOM Node.");
	}
	
	menu.log2debug("isancestor("+child.id+","+element2check.id+")");
	
	var result=false;
	
	var i=0;
	while(i<1000) //just an emergency break
	{
		if(child.parentNode===document)
		{
			break;
		}
		
		if(child.parentNode===element2check)
		{
			result=true;
			break;
		}
		
		child=child.parentNode;
		i++;
	}
	
	return result;
}



/**
 * This method adds an event in a crossbrowser way. It was written by John Resig and improved by me.
 *
 * For more information have a look at http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html or http://ejohn.org/projects/flexible-javascript-events/
 *
 * @param DOMObject A reference to a DOM object.
 * @param mixed The event type (string or array)
 * @param string The function that should be called
 *
 * <samp>
 * addEvent( document.getElementById('foo'), 'click', doSomething );
 * addEvent( obj, 'mouseover', function(){ alert('hello!'); } );
 * addEvent( obj, new Array('keypress','click'), function(){ alert('hello!'); } );
 * </samp>
 */
function addEvent( obj, type, fn )
{
	if (obj.addEventListener)
	{
		if(typeof(type)==="string")
		{
			obj.addEventListener( type, fn, false );
		}
		else if(typeof(type)==="object" && type[0]!==undefined)
		{
			for(var key in type)
			{
				obj.addEventListener(type[key],fn,false);
			}
		}
	}
	else if (obj.attachEvent)
	{
		if(typeof(type)==="string")
		{
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
		}
		else if(typeof(type)==="object" && type[0]!==undefined)
		{
			for(var key in type)
			{
				obj["e"+type[key]+fn] = fn;
				obj[type[key]+fn] = function() { obj["e"+type[key]+fn]( window.event ); }
				obj.attachEvent( "on"+type[key], obj[type[key]+fn] );
			}
		}
	}
}

/**
 * This method removes an event from an element in a crossbrowser way. It was written by John Resig.
 *
 * For more information have a look at look at http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html or http://ejohn.org/projects/flexible-javascript-events/
 *
 * @param DOMObject A reference to a DOM object.
 * @param string The event type
 * @param string The function that should be called
 *
 * <samp>
 * removeEvent( object, eventType, function );
 * removeEvent( document.getElementById('menupoint'),'onmouseover', foo );
 * </samp>
 */
function removeEvent( obj, type, fn )
{
	if (obj.removeEventListener)
	{
		obj.removeEventListener( type, fn, false );
	}
	else if (obj.detachEvent)
	{
		obj.detachEvent( "on"+type, obj[type+fn] );
		obj[type+fn] = null;
		obj["e"+type+fn] = null;
	}
}


var menu=new teco_menu();
addEvent(window,"load",menu.init);