// start info
if(typeof jsReport != 'undefined'){
	jsVersion = new Array(
	/*Name			=*/ 'Unordered List Events Manager.',
	/*Version 		=*/ '0.54',
	/*Date 			=*/ 20040422,
	/*Author		=*/ 'Maurice van Creij',
	/*ProjectCode	=*/ 'list_events',
	/*Summary		=*/ 'Manages mouse and keyboard interactions in unordered lists, to facilitate their operation as an interactive menu.',
	/*Dependencies	=*/ new Array('list_events.js','list_events.css','list_events_pre.js'),
	/*Browsers		=*/ new Array('MO','IE','OP'),
	/*Changes		=*/ new Array(
						'0.54: The toggle images can now have optional dynamic "_link","_hover" and "_active" substrings.',
						'0.53: Peers can be closed upon opening a node. Form "select" elements are hidden when folding out in MSIE.',
						'0.52: Empty menus don\'t give errors anymore.',
						'0.51: Void links now toggle the node between opened and closed',
						'0.5: Added "booSetNodesRecursive" to allow just the deepest link to be classed "active" manualy',
						'0.4: Added the switch "booHandleFocus" to disable the keyboard controls.',
						'0.3: A pre-loading sub include was created to hide the menu priot to DOM parsing',
						'0.2: Added booHidePeers to hide the peers of open items',
					  	'0.1: Basic functionality'
					  	),
	/*Usage			=*/ new Array(
						'<link rel="StyleSheet" href="resources/list_events.css" type="text/css">',
						'<script type="text/javascript" src="resources/list_events_pre.js"></script>',
						'<ul id="listmenu0">',
						'	<li>',
						'		<img border="0" alt="" src="images/app_menu_drop_terminated.gif">',
						'		<a href="index.htm?id=100">item 10</a>',
						'		<span>description 10</span>',
						'	</li>',
						'	<li>',
						'		<img border="0" alt="" src="images/app_menu_drop_terminated.gif">',
						'		<a href="index.htm?id=200">item 20</a>',
						'		<span>description 20</span>',
						'		<ul class="foldout">',
						'			<li>',
						'				<img border="0" alt="" src="images/app_menu_drop_terminated.gif">',
						'				<a href="index.htm?id=210">item 21</a>',
						'				<span>description 21</span>',
						'				<ul class="foldout">',
						'					<li>',
						'						<img border="0" alt="" src="images/app_menu_fold_terminated.gif">',
						'						<a href="index.htm?id=211">item 211</a>',
						'						<span>description 211</span>',
						'					</li>',
						'					<li>',
						'						<img border="0" alt="" src="images/app_menu_fold_terminated.gif">',
						'						<a href="index.htm?id=212">item 212</a>',
						'						<span>description 212</span>',
						'					</li>',
						'					<li>',
						'						<img border="0" alt="" src="images/app_menu_fold_terminated.gif">',
						'						<a href="index.htm?id=213">item 213</a>',
						'						<span>description 213</span>',
						'					</li>',
						'				</ul>',
						'			</li>',
						'			<li>',
						'				<img border="0" alt="" src="images/app_menu_drop_terminated.gif">',
						'				<a href="index.htm?id=220">item 22</a>',
						'				<span>description 22</span>',
						'			</li>',
						'			<li>',
						'				<img border="0" alt="" src="images/app_menu_drop_terminated.gif">',
						'				<a href="index.htm?id=230">item 23</a>',
						'				<span>description 23</span>',
						'			</li>',
						'		</ul>',
						'	</li>',
						'</ul>',
						'<script src="resources/list_events.js" type="text/javascript"></script>'
					  	)
	)
}else{
// end info

	// configuration
		if(typeof(arrMenuIds)=='undefined') 			var arrMenuIds = new Array('listweblab0','listmenu0');	// List with IDs of unordered lists to manage.
		/* operating settings */
		if(typeof(booParseMenuLinks)=='undefined') 		var booParseMenuLinks 		= true;		// Compare node links to the document url and mark matches as 'active'.
		if(typeof(booSetNodesOpened)=='undefined') 		var booSetNodesOpened 		= true;		// Open nodes marked as 'active'.
		if(typeof(booSetNodesRecursive)=='undefined') 	var booSetNodesRecursive	= true;		// Recurse to mark the parents of 'active' nodes also 'active'.
		if(typeof(booHidePeers)=='undefined') 			var booHidePeers			= false;	// hides peers to the 'active items.
		if(typeof(booClosePeers)=='undefined')			var booClosePeers			= true;		// closes peers to the 'active' items.
		if(typeof(booHandleFocus)=='undefined') 		var booHandleFocus			= true;		// handles the onfocus events of links, for keyboard control.
		if(typeof(booHideFormSelects)=='undefined')		var booHideFormSelects		= true;		// hides 'select' form elements (for foldout menus)
		if(typeof(fltMinScore)=='undefined') 			var fltMinScore 			= 0.8; 		// Minimum fraction of similarities between the active link's href and the document url.
		if(typeof(strPathId)=='undefined') 				var strPathId 				= 'path0';	// The ID of the elements where the path, from the active node to the root, should be written.
		if(typeof(strPathRoot)=='undefined') 			var strPathRoot 			= '<a href="/">Home</a>&nbsp;&gt;&nbsp;';	// root entry of the path.
		/* behaviour indicator classes */
		var strFoldOutClass 	= ' foldout';		// Nodes with this sub-classname will be treated as a foldout menu.
		var strPreParsedClass 	= ' parsed';		// Nodes with this sub-classname will be assumed to have been parsed before and skipped.
		/* highlight states */
		var strLinkClass 		= ' link';			// Passive nodes will get this sub-classname.
		var strHoverClass 		= ' hover';			// Mouse-interacted nodes will get this sub-classname.
		var strActiveClass 		= ' active';		// Nodes with links matching the document URL will get this sub-classname.
		/* highligh image substrings */
		var strLinkSrc			= strLinkClass.replace(' ','_');
		var strHoverSrc			= strHoverClass.replace(' ','_');
		var strActiveSrc		= strActiveClass.replace(' ','_');
		/* node states */
		var strTerminatedClass 	= ' terminated'; 	// End-nodes will get this sub-classname.
		var strClosedClass 		= ' closed'; 		// Branch-nodes with hidden sub-nodes will get this sub-classname.
		var strOpenedClass 		= ' opened'; 		// Branch-nodes with visible sub-nodes will get this sub-classname.
	// constants
		var arrNodesToRoot = new Array();
	// primary functions - functionality
		// compares url's and returns a match score
		function compareUrls(strUrlA,strUrlB){
			var intCurScore = 0;
			var intPotScore = 0;
			var intMaxScore = 0;
			var intA,intB;
			// make sure both paths have domains (because MSIE likes to add it to the "href" in the DOM)
	strUrlA=strUrlA.replace("slist","");
	strUrlB=strUrlB.replace("slist","");
	strUrlA=strUrlA.toLowerCase();
	strUrlB=strUrlB.toLowerCase();

			if(strUrlA.indexOf('http://')==-1) strUrlA = document.location.protocol + '//' + document.location.hostname + '/' + strUrlA;
			if(strUrlB.indexOf('http://')==-1) strUrlB = document.location.protocol + '//' + document.location.hostname + '/' + strUrlB;
			// split the urls into manageable strings
			var arrUrlA = strUrlA.split(/[?&\/]/i);
			var arrUrlB = strUrlB.split(/[?&\/]/i);	
			// for every string of UrlA
			for(intA=0; intA<arrUrlA.length; intA++){
				// is the string in the substrings of UrlB
				intB = 0; while(intB<arrUrlB.length && arrUrlA[intA]!=arrUrlB[intB]) intB += 1;
				// if a match was found, add length of string A to current score
				if(intB<arrUrlB.length) intCurScore += arrUrlA[intA].length;
				// add length of string A to potential score
				intPotScore += arrUrlA[intA].length;
			}
			// calcultate maximum score possible
			intMaxScore = strUrlB.length - arrUrlB.length + 1;
			// return the compare-score
			return intCurScore/intPotScore;
			
		}
		// hides 'select' form elements (for foldout menus)
		function hideSelects(booHide){
			// is this function needed and wanted in his browser
			if(booHideFormSelects && document.all){
				// get all select elements
				var objSelects = document.getElementsByTagName("SELECT");
				// for all select elements
				for(var intA=0; intA<objSelects.length; intA++){
					// hide or show
					objSelects[intA].style.visibility = (booHide) ? 'hidden' : 'visible' ;
				}
			}
		}
		
	// secondary function - constructors
		// adjust peers
		function setPeers(objPeer,strChange){
			var objPeers = objPeer.parentNode.childNodes;
			for(var intA=0; intA<objPeers.length; intA++){
				if(objPeers[intA].nodeName.indexOf('text')<0 && objPeer.innerHTML!=objPeers[intA].innerHTML){
					switch(strChange){
						case "hide" : 
							objPeers[intA].style.display = 'none'; 
							break;
						case "show" : 
							objPeers[intA].style.display = 'block';
							break;
						case "close" : 
							remOpened(objPeers[intA]); 
							break;
						default : ;
					}
				}
			}
			objPeer.style.display = 'block';
		}
		// construct a path from the nodesToRoot collection
		function setPathToRoot(strPathId,arrNodesToRoot){
			var objLinks;
			var strPath = strPathRoot;			
			var objPath = document.getElementById(strPathId);
			// reverse the list of stored nodes
			arrNodesToRoot = arrNodesToRoot.reverse();
			// if the path's container exists
			if(document.getElementById(strPathId)!=null){
				// for all stored nodes
				for(var intA=0; intA<arrNodesToRoot.length; intA++){
					objLinks = arrNodesToRoot[intA].getElementsByTagName('A');
					// if there are any links
					if(objLinks.length>0){
						// add the link to the end of the path
						strPath += (intA<arrNodesToRoot.length-1 || (objPath.innerHTML!="" && objPath.innerHTML!="&nbsp;")) ? 
							'<a href="'+objLinks[0].getAttribute('href')+'">'+objLinks[0].innerHTML+'</a>&nbsp;&gt;&nbsp;' : 
							objLinks[0].innerHTML ;
					}
				}
				// paste any existing content from the container to the path
				strPath += (objPath.innerHTML!="") ? objPath.innerHTML : "" ;
				// write the path to the container
				objPath.innerHTML = strPath;
			}
		}
		// class all parents of a node 'active'
		function setActiveToRoot(objNode){
			// store the node for reference
			arrNodesToRoot[arrNodesToRoot.length] = objNode;
			// class the node 'active'
			addActive(objNode);
			// recurse if parent is a node
			if(objNode.parentNode.parentNode.nodeName==objNode.nodeName) setActiveToRoot(objNode.parentNode.parentNode);
		}
		// recurse nodes classed 'active'
		function setNodesActive(objNode,objMenu){
			// get all nodes
			var objNodes = objMenu.getElementsByTagName(objNode.nodeName.replace('html:',''));
			// open all active node
			for(var intA=0; intA<objNodes.length; intA++){
				// if the node is marked 'active', mark all of it's parents 'active' too
				if(objNodes[intA].className.indexOf(strActiveClass.substr(1))>-1) setActiveToRoot(objNodes[intA]);
			}
		}
		// open nodes classed 'active'
		function setNodesOpened(objNode,objMenu){
			// get all nodes
			var objNodes = objMenu.getElementsByTagName(objNode.nodeName.replace('html:',''));
			// open all active node
			for(var intA=0; intA<objNodes.length; intA++){
				// if the node is marked 'active'
				if(objNodes[intA].className.indexOf(strActiveClass.substr(1))>-1){
					// if the node is not a foldout menu, add the 'opened' property
					if(objNodes[intA].parentNode.className.indexOf(strFoldOutClass.substr(1))<0) addOpened(objNodes[intA]);
				}
			}
		}
	// secondary function - parsers
		// parse the list for active links
		function parseMenuLinks(objMenu){
			var strHref, strUrl, fltScore, objLinks;
			var arrCompareScores = new Array();
			// get all links
			objLinks = objMenu.getElementsByTagName('A');
			// if there are links
			if(objLinks.length>0){
				// for all links
				for(var intA=0; intA<objLinks.length; intA++){
					// compare link to url
					strHref = objLinks[intA].getAttribute('href');
					strUrl = document.location.href;
					fltScore = compareUrls(strHref,strUrl) * compareUrls(strUrl,strHref);
					// store score and node
					arrCompareScores[arrCompareScores.length] = new Array(fltScore,objLinks[intA].parentNode);
				}
				// sort scores
				arrCompareScores = arrCompareScores.sort().reverse();
	//alert(arrCompareScores)			
				// mark the most like match as 'active'
				if(arrCompareScores[0][0]>=fltMinScore) addActive(arrCompareScores[0][1]);
				// recurse all 'active' nodes
				if(booSetNodesRecursive) setNodesActive(arrCompareScores[0][1],objMenu);
				// set the node visibility
				if(booSetNodesOpened) setNodesOpened(arrCompareScores[0][1],objMenu);
			}
		}
		// parse the list for events
		function parseMenuEvents(objMenu){
			var objNodes, objNode, objSubNodes, objLinks, objImgs;
			// check if the menu has been parsed before
			if(objMenu.className.indexOf(strPreParsedClass.substr(1))<0){
				// mark the menu as parsed
				objMenu.className += strPreParsedClass;
				// get the items from the menu
				objNodes = objMenu.childNodes;
				// for all menu items
				for(var intA=0; intA<objNodes.length; intA++){
					// node properties
					if(objNodes[intA].nodeName!='#text' && objNodes[intA].nodeName!='SCRIPT' && objNodes[intA].nodeName!='#comment'){
						// node events
						objNode = objNodes[intA];
						objNode.onmouseover = addHover;
						objNode.onmouseout = remHover;
						// node class
						objSubNodes = objNode.getElementsByTagName(objMenu.nodeName.replace('html:',''));
						objNode.className += (objSubNodes.length>0) ? strClosedClass : strTerminatedClass ;
						objNode.className += (objNode.className.indexOf(strActiveClass.substr(1))<0) ? strLinkClass : '' ;
						// subnode properties
						if(objSubNodes.length>0){
							// subnodes style (only for Opera)
							objSubNodes[0].style.display = 'none';
						}
						// link properties
						objLinks = objNode.getElementsByTagName('A');
						if(objLinks.length>0){
							// link events
							objLinks[0].onmouseover = unfocusNodeLink;
							objLinks[0].onfocus = focusNodeLink;
							if(
								objLinks[0].getAttribute('href')=='javascript:{}' || 
								objLinks[0].getAttribute('href').substr(objLinks[0].getAttribute('href').length-1,1)=='#' || 
								objLinks[0].getAttribute('href')==''
							
							){
								objLinks[0].onclick = toggleOpened;
								objLinks[0].setAttribute('href','javascript:{}');
							}
						}
						// image properties
						objImgs = objNode.getElementsByTagName('IMG');
						if(objImgs.length>0){
							// image events
							objImgs[0].onclick = (objSubNodes.length>0) ? toggleOpened : openNodeLink;
							// image source
							objImgs[0].src = (objSubNodes.length>0) ? objImgs[0].src.replace(strTerminatedClass.substr(1),strClosedClass.substr(1)) : objImgs[0].src ;
						}
					}
				}
			}
		}
	// ternary function - event handlers
		// replace the node's closed class with the opened class
		function addOpened(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			// validate node for keyboard events
			if(objNode.nodeName.replace('html:','')=='A') objNode = objNode.parentNode;
			// node class
			objNode.className = objNode.className.replace(strClosedClass,strOpenedClass);
			// image source
			var objImgs = objNode.getElementsByTagName('IMG');
			if(objImgs.length>0) objImgs[0].src = objImgs[0].src.replace(strClosedClass.substr(1),strOpenedClass.substr(1));
			// subnode pre-process
			var objSubNodes = objNode.getElementsByTagName(objNode.parentNode.nodeName.replace('html:',''));
			if(objSubNodes.length>0){
				// hide peers
				if(booHidePeers) setPeers(objNode,'hide');
				// close peers
				if(booClosePeers) setPeers(objNode,'close');
				// apply event handlers
				parseMenuEvents(objSubNodes[0]);
				// forcefully show the subnodes (only for Opera)
				objSubNodes[0].style.display = 'block';
			}
		}
		// replace the node's opened class with the closed class
		function remOpened(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			// node class
			objNode.className = objNode.className.replace(strOpenedClass,strClosedClass);
			// image source
			var objImgs = objNode.getElementsByTagName('IMG');
			if(objImgs.length>0) objImgs[0].src = objImgs[0].src.replace(strOpenedClass.substr(1),strClosedClass.substr(1));
			// subnode pre-process
			var objSubNodes = objNode.getElementsByTagName(objNode.parentNode.nodeName.replace('html:',''));
			if(objSubNodes.length>0){
				// hide peers
				if(booHidePeers) setPeers(objNode,'show');
				// apply event handlers
					//parseMenuEvents(objSubNodes[0]);
				// forcefully hide the subnodes (only for Opera)
				objSubNodes[0].style.display = 'none'; 
			}
		}
		// toggle between the node's opened and closed class
		function toggleOpened(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that.parentNode : this.parentNode ;
			(objNode.className.indexOf(strClosedClass)>-1) ? addOpened(objNode) : remOpened(objNode) ;
		}
		// add the hover class to the (container) node
		function addHover(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			if(document.all) objNode.className = objNode.className.replace(strLinkClass,strHoverClass);
			// toggle icon
			if(objNode.getElementsByTagName('IMG').length>0) 
				if(objNode.getElementsByTagName('IMG')[0].src.indexOf(strLinkSrc)>-1) 
					objNode.getElementsByTagName('IMG')[0].src = objNode.getElementsByTagName('IMG')[0].src.replace(strLinkSrc,strHoverSrc);
			// extra change for foldouts
			if(typeof(strFoldOutClass)!='undefined') if(objNode.parentNode.className.indexOf(strFoldOutClass.substr(1))>-1){
				addOpened(objNode);
				hideSelects(true);
			}
		}
		// remove the hover class from the node
		function remHover(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			if(document.all) objNode.className = objNode.className.replace(strHoverClass,strLinkClass);
			// toggle icon
			if(objNode.getElementsByTagName('IMG').length>0) 
				if(objNode.getElementsByTagName('IMG')[0].src.indexOf(strHoverSrc)>-1) 
					objNode.getElementsByTagName('IMG')[0].src = objNode.getElementsByTagName('IMG')[0].src.replace(strHoverSrc,strLinkSrc);
			// extra change for foldouts
			if(typeof(strFoldOutClass)!='undefined') if(objNode.parentNode.className.indexOf(strFoldOutClass.substr(1))>-1){
				remOpened(objNode);
				hideSelects(false);
			}
		}
		// add the active class to a node
		function addActive(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			// node class			
			objNode.className = (objNode.className.indexOf(strLinkClass.substr(1))<0) ? objNode.className+strActiveClass : objNode.className.replace(strLinkClass,strActiveClass);
			// toggle icon
			if(objNode.getElementsByTagName('IMG').length>0) 
				if(objNode.getElementsByTagName('IMG')[0].src.indexOf(strLinkSrc)>-1) 
					objNode.getElementsByTagName('IMG')[0].src = objNode.getElementsByTagName('IMG')[0].src.replace(strLinkSrc,strActiveSrc);
		}
		// remove the active class from a node
		function remActive(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			// node class
			objNode.className = objNode.className.replace(strActiveClass,'');
			// toggle icon
			if(objNode.getElementsByTagName('IMG').length>0) 
				if(objNode.getElementsByTagName('IMG')[0].src.indexOf(strActiveSrc)>-1) 
					objNode.getElementsByTagName('IMG')[0].src = objNode.getElementsByTagName('IMG')[0].src.replace(strActiveSrc,strLinkSrc);
		}
		// opens the link embedded in the node
		function openNodeLink(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that.parentNode : this.parentNode ;
			document.location.href = objNode.getElementsByTagName('A')[0].getAttribute('href');
		}
		// handles the onfocus event of the link within a node
		function focusNodeLink(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			if(booHandleFocus) addOpened(objNode)
		}
		// cancel the onFocus event of the link after a mouse was used to click it
		function unfocusNodeLink(){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			objNode.onFocus = null;
			booHandleFocus = false;
		}
		// startup sequence
		function getthapicture(objNode){
			if(objNode!=null){
				var objNodeList = objNode.parentNode;
				var intA=0;
				while(objNodeList.childNodes[intA].innerHTML!=objNode.innerHTML && intA<20){
					intA++
				}
				document.getElementById("decoImage").src="/images/deco_"+(intA+1)+".jpg"
			}
		}		
		
		function startMenu(){
			if(navigator.appVersion.indexOf('MSIE')>-1 && navigator.appVersion.indexOf('Macintosh')>-1){
				// MSIE on the macintosh... why god, why
			}else if(typeof(document.getElementById)!='undefined'){
				// root pre-process
				for(var intA=0; intA<arrMenuIds.length; intA++){
					if(document.getElementById(arrMenuIds[intA])!=null){
						var objMenu = document.getElementById(arrMenuIds[intA]);
						parseMenuEvents(objMenu);
						if(booParseMenuLinks) parseMenuLinks(objMenu);
						objMenu.style.display='block';
					}
				}
				// write active nodes path
				setPathToRoot(strPathId,arrNodesToRoot);
				
				getthapicture(arrNodesToRoot[0]);		
				
			}
		}
	// events
		//onload = startMenu;
		startMenu();

}
