// start info
if(typeof jsReport != 'undefined'){
	jsVersion = new Array(
	/*Name			=*/ 'Unordered List Dropdown/Foldout Menu.',
	/*Version 		=*/ '1.0',
	/*Date 			=*/ 20031216,
	/*Author		=*/ 'Maurice van Creij',
	/*ProjectCode	=*/ 'list_menu',
	/*Summary		=*/ 'An event driven dropdown- and foldout-menu based on an unordered list (or any other nested tag, like tables).',
	/*Dependencies	=*/ new Array('list_menu.js','list_menu_dropdown.css','list_menu_foldout.css','lib_images.js'),
	/*Browsers		=*/ new Array('MO','IE','OP'),
	/*Changes		=*/ new Array(
						'This script is deprecated in favour of list_events.js',
						'1.0: Unused features were removed. Configuration was simplified. Feature complete.',
						'0.998: Added "booListPath" to disable the breadcrums or limit the breadcrums to the first dropdown',
						'0.997: Elusive pre-load mouseevents bug solved',
						'0.996: Empty lists don\'t cause errors anymore. "booHideForms" Will hide form elements that interfere with the menu (MSIE)',
						'0.995: Fixed a bug when "intPeerHandling>0". Toggling childless nodes would cause an error',
						'0.994: Added "intChildHandling" to reset sub-items when a node is opened',
						'0.993: Alt-attributes and keyboard-controls for the menu',
						'0.992: Void links are replaced by menu togglers',
						'0.991: Foldout menu\'s can now also use "booUrlSense"',
						'0.99: Added "setListPeers()" to close peers before opening a node.',
						'0.98: Small bug in the default list "arrLists[0]", last element was left out.',
						'0.97: Images without a numeric suffix are now ignored',
						'0.96: Onclick events can still change the image even when "imageevents.js" integration isn\'t used.',
						'0.95: Mouseover effects on the images is now optional (booUseImageCache)',
						'0.94: Optimizes "resetList()", to do less redundant work.',
						'0.93: Optimized "suggestListNode()", for faster performance no complete redraw is issued after a new node id opened',
						'0.92: Added some pre-programmed lists. Fixed a bug in the "breadcrum"-path when multiple lists are used.',
						'0.91: Fixed a bug in the handling of fold-out menus. As a by-product a "breadcrum"-path is constructed on start-up, this can be written to a DIV.',
						'0.9: The "booUrlSense"-feature now compares fragmented URLs for greater accuracy.',
						'0.8: Improved automatic node opener so it won\'t mess up the classes for the parent items as much.',
						'0.7: Added support for manualy setting (open/close) node states through it\'s class.',
						'0.6: Moved event-handling from the HTML to the javascript',
						'0.5: Added optional support for mouseover-icons from "image_events.js"',
						'0.4: Combined functionality for dropdowns and foldouts.',
						'0.3: Url sensing, can open nodes related to the document\'s URL.',
						'0.2: Functional prototype (adjust style).',
					  	'0.1: Basic event handling (open/close nodes).'
					  	),
	/*Usage			=*/ new Array(
							'<div id="listmenu0">',
							'	<ul>',
							'		<li class="listmenu0st0">',
							'			<img border="0" alt="" src="/~wmittensrd/images/spacing.gif">',
							'			<a href="index.htm?id=200" >item 20</a>',
							'			<span>description 20</span>',
							'			<ul>',
							'				<li class="listmenu0st0">',
							'					<img border="0" alt="" src="/~wmittensrd/images/spacing.gif">',
							'					<a href="index.htm?id=210">item 21</a>',
							'					<span>description 21</span>',
							'				</li>',
							'				<li class="listmenu0st0">',
							'					<img border="0" alt="" src="/~wmittensrd/images/spacing.gif">',
							'					<a href="index.htm?id=220">item 22</a>',
							'					<span>description 22</span>',
							'				</li>',
							'				<li class="listmenu0st0">',
							'					<img border="0" alt="" src="/~wmittensrd/images/spacing.gif">',
							'					<a href="index.htm?id=230">item 23</a>',
							'					<span>description 23</span>',
							'				</li>',
							'			</ul>',
							'		</li>',
							'	</ul>',
							'</div>',
							'<link rel="StyleSheet" href="list_foldout.css" type="text/css">',
							'<script language="javascript" src="list_menu.js"></script>'
					  	)
	)
}else if(typeof(document.getElementsByTagName)!='undefined'){
// end info


	// constants/configuration
		// startup
		if(typeof(arrLists)=='undefined')			var arrLists			= 	new Array(					// index of multiple menu's
																					new Array(
																						'listmenu0',		// name of the list's container
																						0,					// type of menu: 0=dropdown, 1=foldout
																						true,				// compare list-item's HREF with the document URL (slow)
																						1.0				// minimum compare score for compared URLs
																					)
																				);
		if(typeof(strListType)=='undefined')		var strListType			= 'UL';			// type of list used valid: UL | OL | DL | TABLE
		if(typeof(strListItem)=='undefined')		var strListItem			= 'LI';			// type of list item used valid: LI | LI | DT,DD | TR,TD
		if(typeof(booSetClassNames)=='undefined')	var booSetClassNames	= true ;		// change classnames for decorative purposes
		if(typeof(strListPathId)=='undefined')		var strListPathId		= 'path0';		// optional path to write a breadcrumspath to
		// operation
		if(typeof(booHideForms)=='undefined')		var booHideForms		= true;			// hide form elements that could interfere with the menu	
		if(typeof(intPeerHandling)=='undefined')	var intPeerHandling		= 0;			// leave(0), close(1) or hide(2) the peers upon opening a new node
		if(typeof(intChildHandling)=='undefined')	var intChildHandling	= 0;			// leave(0) or close(1) the child items upon opening a new node (slow)
		if(typeof(intRootOffset)=='undefined')		var intRootOffset		= 1;			// recursion after which nodes should be hidden
		if(typeof(intListTimer)=='undefined')		var intListTimer		= 1024			// time to wait before (re)setting a list node
		// "imageevents.js" integration (offers caching and fading)
		if(typeof(booUseImageEvents)=='undefined')	var booUseImageEvents	= (typeof(setImgSrcSuffix)=='function') ? true : false ;		// use imageevents.js to manage list icons (slow)
		if(typeof(booUseImageCache)=='undefined')	var booUseImageCache	= false;		// pre-cache images (slow)
		// constants
		var objListTimer, objListTimerTgt;
		var arrUrlSensePath	= 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)
			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 ma maximum score possible
			intMaxScore = strUrlB.length - arrUrlB.length + 1;
			// return the compare-score
			return intCurScore/intPotScore;
		}
		// hides form elements that interfere with the menu
		function hideForms(booListState){
			if(document.all){
				// determine form state
				strFormState = (booListState) ? 'hidden' : 'visible' ;
				// get all for elements
				booFormSelects = document.getElementsByTagName('SELECT');
				// for all form elements
				for(var intA=0; intA<booFormSelects.length; intA++){
					// apply the state
					booFormSelects[intA].style.visibility = strFormState;
				}
			}
		}
		// change the src-suffix of a list icon
		function setIconClass(objTarget,intState){
			// get the icon object
			var objImg = objTarget.parentNode.getElementsByTagName('IMG');
			if(objImg.length>0){
				// set the image suffix using "imageevents.js" integration
				if(booUseImageEvents){
					if(objImg[0].id!='') setImgSrcSuffix(objImg[0].id,intState);
				// or set the (even) image suffix manually
				}else if(intState%2==0){
					// get the picture source name
					var strImgUrl = objImg[0].src;
					// split the url
					var arrImgUrl		= strImgUrl.split('.');
					var strImgUrlSuffix = '.' + arrImgUrl[arrImgUrl.length-1];
					var strImgUrlPrefix = strImgUrl.substr(0,strImgUrl.length-(strImgUrlSuffix.length)-1);
					var intImgUrlDigit	= parseInt(strImgUrl.substr(strImgUrlPrefix.length,1));
					if(!isNaN(intImgUrlDigit)){
						// construct a new url
						strImgUrl = strImgUrlPrefix + intState + strImgUrlSuffix;
						// give the picture a new source name, if it's not the same as the old one
						if(objImg[0].src != strImgUrl) objImg[0].src = strImgUrl;
					}
				}
				// set the alt attribute
				switch(intState){
					case 4 :	objImg[0].setAttribute('alt','open...');	break;
					case 6 :	objImg[0].setAttribute('alt','close...');	break;
					default : 	objImg[0].setAttribute('alt','');
				}
			}
		}
		// change the class-suffix of a list node
		function setListClass(objTarget,intOffset,booNoOffset){
			var strLIclass, intLIsuffix;
			// get the class name
			strLIclass		= objTarget.parentNode.className;
			// is there a classname?
			if(strLIclass!=null && strLIclass!=''){
				// get the class suffix
				intLIsuffix	= parseInt(strLIclass.substr(strLIclass.length-1,1));
				// add the offset to the suffix or take the offset as an absolute value
				intLIsuffix	= (booNoOffset) ? intOffset : intLIsuffix+intOffset;
				// get the class prefix
				strLIclass	= strLIclass.substr(0,strLIclass.length-1);
				// validate the result. Allow offset+1 on even suffixes, offset-1 on odd suffixes and absolute changes on both.
				if((intOffset==1 && intLIsuffix%2!=0) || (intOffset==-1 && intLIsuffix%2==0) || booNoOffset){
					// change the target's class
					if(booSetClassNames) objTarget.parentNode.className = strLIclass + intLIsuffix;
					// change the icon's state if changeable icons are found
					setIconClass(objTarget,intLIsuffix);
				}
			}
		}
		// open/close a list node
		function setListNode(objTarget,booNodeState){
			var intLIclass;
			// get the children of the parent node
			var objULs = objTarget.parentNode.getElementsByTagName(strListType);
			// does the parent node have an UL child
			if(objULs.length>0){
				// if no node state if given, toggle
				if(typeof(booNodeState)=='undefined') booNodeState = (objULs[0].style.display=='none' || objULs[0].style.display=='');
				// reset the child UL's LIs, if desired
				if(intChildHandling>0 && booNodeState){
					// get the child UL's LIs
					objLIs = objULs[0].getElementsByTagName('LI');
					// reset every LI
					for(var intA=0; intA<objLIs.length; intA++) setListNode(objLIs[intA].firstChild,false);
				}
				// display or hide it
				objULs[0].style.display = (booNodeState) ? 'block' : 'none';
				// choose the parent class
				intLIclass = (booNodeState) ? 6 : 4 ;
			}else{
				// if no node state assume a value
				if(typeof(booNodeState)=='undefined') booNodeState = false;
				// choose the parent class
				intLIclass = (booNodeState) ? 2 : 0 ;
			}
			// change parent class
			setListClass(objTarget,intLIclass,true);
		}
		// open/close a list node after a delay
		function suggestListNode(objTarget,booNodeState){
			// clear the last running timeout
			clearTimeout(objListTimer);
			// if no node state if given, toggle
			if(typeof(booNodeState)=='undefined'){
				var objNode = objTarget.parentNode.getElementsByTagName(strListType)[0];
				booNodeState = (objNode.style.display=='none' || objNode.style.display=='');
			}
			// set a delayed node change
			if(booNodeState){
				// hide possible interfering form elements
				if(booHideForms) hideForms(booNodeState);
				// get the peers to the new list node
				var objTargetPeers = objTarget.parentNode.parentNode.childNodes;
				// for all peers
				for(var intA=0; intA<objTargetPeers.length; intA++){
					if(objTargetPeers[intA].nodeName.replace('html:','')==strListItem){
						// close the node
						setListNode(objTargetPeers[intA].firstChild,false);
					}
				}
				// open the new list node
				setListNode(objTarget,true);
			}else{
				// find the root Id of the item
				var objRoot = objTarget.parentNode;
				while(objRoot.nodeName.replace('html:','')==strListType || objRoot.nodeName.replace('html:','')==strListItem){
					objRoot = objRoot.parentNode;
				}
				var strRoot = objRoot.id;
				// set a timed close request
				objListTimerTgt = objTarget.parentNode;
				objListTimer = setTimeout("resetList(false,'"+strRoot+"',1);if(booHideForms)hideForms(false);",intListTimer);
			}
		}
		// closes a node's peers before opening a new one
		function setListPeers(objTarget,booNodeState){
			// check if the node has child-nodes
			var objTargetChildren = objTarget.parentNode.getElementsByTagName(strListType);
			// if no node state if given, toggle
			if(typeof(booNodeState)=='undefined'){
				if(objTargetChildren.length>0){
					// choose a toggle state
					var objNode = objTargetChildren[0];
					booNodeState = (objNode.style.display=='none' || objNode.style.display=='');
				}else{
					// assume closed by default
					booNodeState = false;
				}
			}
			// get the peers to the new list node
			var objTargetPeers = objTarget.parentNode.parentNode.childNodes;
			// for all peers
			for(var intA=0; intA<objTargetPeers.length; intA++){
				if(objTargetPeers[intA].nodeName.replace('html:','')==strListItem){
					// close the node
					setListNode(objTargetPeers[intA].firstChild,false); 
					// hide the node
					if(intPeerHandling==2 && objTargetChildren.length>0) objTargetPeers[intA].style.display = (booNodeState) ? 'none' : 'block' ;
				}
			}
			// get the children of the new list node
			if(objTargetChildren.length>0){
				var objTargetChildNodes = objTargetChildren[0].childNodes;
				// for all childnodes
				for(var intA=0; intA<objTargetChildNodes.length; intA++){
					if(objTargetChildNodes[intA].nodeName.replace('html:','')==strListItem){
						// close the node
						setListNode(objTargetChildNodes[intA].firstChild,false);
						// unhide it
						if(intPeerHandling==2) objTargetChildNodes[intA].style.display = 'block' ;
					}
				}
			}
			// open the new list node
			if(intPeerHandling==2) objTarget.parentNode.style.display = 'block';
			setListNode(objTarget,booNodeState);
		}
		// opens/closes all list nodes
		function resetList(booNodeState,strNodeId,intMenuType){
			// get all nodes
			var objULs = document.getElementById(strNodeId).getElementsByTagName(strListType);
			// for all nodes (except the root)
			for(var intA=intRootOffset; intA<objULs.length; intA++){
				// set the node to the given state
				objULs[intA].style.display = (booNodeState) ? 'block' : 'none';
			}
			// reset all node styles
			if(objListTimerTgt!=null){
				setListNode(objListTimerTgt.firstChild,false);
				cascadeList(objListTimerTgt,false,intMenuType);
			}
			// highlight the active item root
			if(arrUrlSensePath.length>0){
				// get the root item of the active item
				objNodeRoot = arrUrlSensePath[arrUrlSensePath.length-1];
				// check if the item has child items
				intNodeState = (objNodeRoot.getElementsByTagName(strListType).length>0) ? 6 : 2 ;
				// if the list id's matches
				if(objNodeRoot.parentNode.parentNode.id==strNodeId) setListClass(objNodeRoot.firstChild,intNodeState,true);
			}
		}
		// cascade back up the hierarchy to open all list nodes
		function cascadeList(objLI,booDisplay,intMenuType){
			// store the current node in a list
			if(booDisplay) arrUrlSensePath[arrUrlSensePath.length] = objLI;
			// change the class of the LI
			if(intPeerHandling>0){
				setListPeers(objLI.firstChild,booDisplay);
			}else{
				setListNode(objLI.firstChild,booDisplay);
			}
			// fetch the parent item
			var objParent = objLI.parentNode.parentNode;
			// recurse if the parent item of this LI is also a LI
			if(objParent.nodeName.replace('html:','')==strListItem) cascadeList(objParent,booDisplay,intMenuType);
		}
	// secondary function - construction
		// convert the stored path of nodes into a breadcrums trail
		function getListBranch(){
			var arrListBranch = arrUrlSensePath.reverse();
			var strListBranch = ''; //'<a href="/">home</a>&nbsp;&gt;&nbsp;';
			// for every LI in the list branch
			for(var intA=0; intA<arrListBranch.length; intA++){
				// get it's href
				objAs = arrListBranch[intA].getElementsByTagName('A');
				strListUrl = (objAs.length>0) ? objAs[0].getAttribute('href') : '#' ;
				// get it's title
				strListTitle = (objAs.length>0) ? objAs[0].firstChild.nodeValue : '' ;
				// make link
				strListBranch += '<a href="'+strListUrl+'">'+strListTitle+'</a>';
				// add path marker
				strListBranch += (intA<arrUrlSensePath.length-1) ? '&nbsp;&gt;&nbsp;' : '' ;
			}
			// make sure this is only used once, for multiple trees
			strListPathId = '';
			// return the breadcrums
			return strListBranch;
		}
		// go through the UL's, add the click events and modify styles where appropriate
		function evalList(objMenuRoot,intMenuType,booSenseUrl,fltSenseUrlMin){
			var strListUrl, strDocUrl, strListClass,intListClass,intListClassNew, objIMGs, objAs, objULs, objLIs;
			var arrUrl = new Array();
			// get all the LI's in this menu
			objLIs = objMenuRoot.getElementsByTagName(strListItem);
			// for every LI in this menu
			for(var intA=0; intA<objLIs.length; intA++){
				// is the node a list item
				if(objLIs[intA].nodeName.replace('html:','')==strListItem){
					// get the class of this LI
					strListClass = (objLIs[intA].className!=null) ? objLIs[intA].className : '' ;
					intListClass = parseInt(strListClass.substr(strListClass.length-1,1));
					// check for UL in this LI
					objULs = objLIs[intA].getElementsByTagName(strListType);
					intListClassNew = (objULs.length>0) ? 4 : 0 ;
					// for all IMG in this LI
					objIMGs = objLIs[intA].getElementsByTagName('IMG');
					if(objIMGs.length>0){
						// set the onclick event
						objIMGs[0].onclick = toggleListNode;
						// give the image an id if it hasn't got one
						if(objIMGs[0].id=='') objIMGs[0].id = 'listmenu' + Math.round(Math.random()*10000) + 'icon' + intA;
						// cache it's states
						if(booUseImageEvents && booUseImageCache) cacheImgSrcSuffix(objIMGs[0].id,0,1,2,3,4,5,6,7);
					}
					// for all A in this LI
					objAs = objLIs[intA].getElementsByTagName('A');
					if(objAs.length>0){
						// get the list item's href
						strListUrl = objAs[0].getAttribute('href');
						strDocUrl = document.location.href;
						// void links are replaced by menu togglers
						if(strListUrl=='javascript:{}' || strListUrl.indexOf('#')==strListUrl.length-1){
							objAs[0].setAttribute('href','javascript:{}');
							objAs[0].setAttribute('title','open/close');
							objAs[0].onclick = toggleListNode;
						}
						// compare the href to the url
						arrUrl[arrUrl.length] = (booSenseUrl) ? new Array(compareUrls(strListUrl,strDocUrl)*compareUrls(strDocUrl,strListUrl),objLIs[intA]) : 0 ;
						// set the events
						switch(intMenuType){
							case 1 :
								objAs[0].onmouseover = openListNode;
								objAs[0].onmouseout = closeListNode;
								objAs[0].onfocus = openListNode;
								break;
							default : 
								objAs[0].onmouseover = overListNode;
								objAs[0].onmouseout = outListNode;
								objAs[0].onkeypress = keyListNode;
						}
					}else{
						strListUrl = 'none'
					}
					// change the class of the node to parent or child
					setListClass(objLIs[intA].firstChild,intListClassNew,true);
					// open the node with an 'openened' class-suffix (2 or 6)
					if(intListClass==6 || intListClass==2) cascadeList(objLIs[intA],true,intMenuType);
				}
			}
			// open the node with the correct url (booUrlSense)
			if(booSenseUrl){
				arrUrlSensePath = new Array();
				arrUrl = arrUrl.sort().reverse();
				// if the most likely url's score is high enough
				if(arrUrl[0][0]>=fltSenseUrlMin){
					cascadeList(arrUrl[0][1],true,intMenuType);
					if(intMenuType==1) resetList(false,objMenuRoot.id,intMenuType);
				}
			}
		}
	// ternary function - operation 
		// use the keyboard to toggle focused nodes
		function keyListNode(e){
			ascVal = (document.all) ? event.keyCode : e.which ;
			if(ascVal!=0){
				if(intPeerHandling>0){
					setListPeers(this);
				}else{
					setListNode(this);
				}
			}
		}
		// toggle the object's node
		function toggleListNode(){
			if(intPeerHandling>0){
				setListPeers(this);
			}else{
				setListNode(this);
			}
		}
		// open the object's node
		function openListNode(){
			suggestListNode(this,true);
		}
		// close the object's node
		function closeListNode(){
			suggestListNode(this,false);
		}
		// highlight the list node
		function overListNode(){
			if(typeof(setListClass)!='undefined') setListClass(this,1);
		}
		// unlight the list node
		function outListNode(){
			if(typeof(setListClass)!='undefined') setListClass(this,-1);
		}
		// startup sequence
		function startList(){
			// if the browser supports the DOM
			if(typeof(document.getElementById)!='undefined'){
				// for all menu's listed
				for(var intA=0; intA<arrLists.length; intA++){
					// get the menu object
					objMenuId = document.getElementById(arrLists[intA][0]);
					// if the object exists
					if(objMenuId!=null && objMenuId.getElementsByTagName(strListItem).length>0){
						// get the menu type
						intMenuType = arrLists[intA][1];
						// get the URL sense option
						booSenseUrl =  arrLists[intA][2];
						fltSenseUrlMin =  arrLists[intA][3];
						// set all classes to default
						evalList(objMenuId,intMenuType,booSenseUrl,fltSenseUrlMin);
						// fill the optional list path
		// UITGEZET DOOR JACQUES	if(strListPathId!='') document.getElementById(strListPathId).innerHTML = getListBranch();
					}
				}
			}
		}
	// executed inline
		// preprogrammed lists
    	arrLists[arrLists.length] =	new Array('weblab0',0,true,1);
		// startup at load
		startList();

}
