/*
NOTE: this script assumes website.js has been loaded
*/

var isIE;
var menubar_ready;

// ---------------------------------------------------------
// show dom element; boolean result indicates success/fail
// ---------------------------------------------------------
function show(obj) {
	return !!(obj && obj.style && 
		(obj.style.visibility = "visible"));
}

// ---------------------------------------------------------
// hide dom element; boolean result indicates success/fail
// ---------------------------------------------------------
function hide(obj) {
	return !!(obj && obj.style && 
		(obj.style.visibility = "hidden"));
}

// ---------------------------------------------------------
// traverse menuitems in menubar and add event handlers
// private tid variable, separate from status bar tid
// ---------------------------------------------------------
function init_menubar() {
//	alert("init_menubar()");

	var tid, tobj;

	// placeholder functions, replaced by global versions
	// bugfix for Firefox: global functions not initially
	// visible in event handler chain, even after onload() !!!
	// see evalFn(name);
	
	function setStatus(msg, def) {
		return evalFn("setStatus")(msg, def);
	}
	
	function clearStatus(ms, def) {
		return evalFn("clearStatus")(ms, def);
	}
	
	function show(obj) {
		return evalFn("show")(obj);
	}
	
	function hide(obj) {
		return evalFn("hide")(obj);
	}

	// ---------------------------------------------------------
	// replace local function with window (global) function
	// when available.  return global function or a dummy
	// ---------------------------------------------------------
	// NOTE: to prevent errors in Firefox when event handlers
	// are ready before global functions... must be a bug....
	// this problem only occurs in event handlers, even when
	// assigned dynamically after global functions exist...odd.
	// does not affect local functions visible to closures, 
	// only global functions called from a nested closure.
	// ---------------------------------------------------------
	function evalFn(name) {
		return window[name] 
			? eval(name + " = window[name]") 
			: function() {};
	}
	
	// ---------------------------------------------------------
	// show the menu associated with a link element
	// ---------------------------------------------------------
	function showMenu(link) {
	//	if(link.node) show(link.node);
		show(link.node);
		return setStatus(link);
	}

	// ---------------------------------------------------------
	// hide menu and any parent menus for specified link element
	// ---------------------------------------------------------
	function hideMenu(link) {
	//	if(link.node) hide(link.node);
		hide(link.node);
		return link.uplink 
			? hideMenu(link.uplink) 
			: clearStatus(0);
	}

	// ---------------------------------------------------------
	// show menu hierarchy from obj up <= depth (or all)
	// ---------------------------------------------------------
	function showMenus(link, depth) {
		while(link) {
			if(link.menu && link.depth <= depth) {
				show(link.menu);
			}
			link = link.uplink;
		}
	}

	// ---------------------------------------------------------
	// hide menu hierarchy from obj up >= depth (or all)
	// ---------------------------------------------------------
	function hideMenus(link, depth) {
		depth = depth || 0;
		while(link && link.depth > depth) {
			if(link.menu) {
				hide(link.menu);
			}
			link = link.uplink;
		}
	}

	// ---------------------------------------------------------
	// mouse over submenu item; cancel hide submenu timeout
	// ---------------------------------------------------------
	function menuIn(link) {
		tid = clearTimeout(tid);
		if(link && tobj) {
			// different menubar item; hide now
			if(link.root != tobj.root) {
			//	tobj = hideMenu(tobj);
			//	tobj = void(hideMenu(tobj));
				hideMenu(tobj);
				tobj = null;
			} else if(link.depth <= tobj.depth && tobj.node) {
				// moused off submenu node, hide submenu
				hide(tobj.node);
			} else if(link.depth < tobj.depth && tobj.menu) {
				// moused up menu level, hide lower menu
				hide(tobj.menu);
			}
		}
		
		return showMenu(link);
	}

	// ---------------------------------------------------------
	// mouse left submenu item; start hide submenu timeout
	// ---------------------------------------------------------
	function menuOut(link) {
		tobj = link;
		tid = setTimeout(function onTimeout(e) { 
			hideMenu(link); 
		}, 500);
	}

	function onmouseover(e) {
		return menuIn(this);
	}
	
	function onmouseout(e) {
		return menuOut(this);
	}
	
	function onclick(e) {
		return !this.disabled && hideMenu(this) && 
			(!this.hash || hilite_anchor(this));
	}
	
	// ---------------------------------------------------------
	// recursively process menubar/menu/submenu items 
	// and add event handlers & properties to link objects
	// ---------------------------------------------------------
	// link: 					menubar/menu/submenu item
	// link.depth				container nesting level, 0=mbar
	// link.uplink			A	up to parent link
	// link.root			A	menubar item link (top of menus)
	// link.node;			UL	menu/submenu opened on mouseover
	// link.menu;			UL	menu 
	// link.className;			[disabled][-][submenu]
	//								|active|external
	// link.onmouseover(e);		show menu/submenu if present
	// link.onmouseout(e);		hide menu/submenu after delay
	// link.onclick(e);			hide menu or false if disabled
	// ---------------------------------------------------------
	function processMenu(node, type, link, depth) {
		type = node.className  
			= type || "menubar";
		subType = type == "menubar" 
			? "menu" : "submenu";
		depth = depth || 0;
		if(depth > 3) throw("up");
		var nodes = getNodes(node);
		for(var i = 0; i < nodes.length; i++) {
			if(nodes[i].tagName == "LI") {
				var items = getNodes(nodes[i]);
				for(var j = 0, a; j < items.length; j++) {
					if(items[j].tagName == "A") {
						a = items[j];
						a.depth = depth;
						a.root = ((a.menu = (a.uplink = link) && 
							a.uplink.node) && a.uplink.root) || a;
						
						var file = a.file || getfilename(a.href);
						if(file.charAt(0) == "-") {
							a.className = "disabled";
						}

						a.disabled = file == "#" || 
							a.className == "disabled" ||
							a.className == "submenu-disabled";
						
						a.onmouseover = onmouseover;
						a.onmouseout = onmouseout;
						a.onclick = onclick;
						
					} else if(items[j].tagName == "UL") {
						a.node = items[j];
						if(depth) a.className = "submenu" + 
							(a.className == "disabled" 
							? "-" + a.className : "");
						processMenu(items[j], subType, a, depth + 1);
					}
				}
			}
		}
	}

	processMenu(document.getElementById("menubar"));
	
	menubar_ready = true;
}

// ---------------------------------------------------------
// get element nodes (ELEMENT_NODE) from childNodes array
// ---------------------------------------------------------
function getNodes(node) {
	var nodes = node.childNodes;
	for(var i = 0, j = 0, arr = []; i < nodes.length; i++) {
		if(nodes[i].nodeType == 1) {
			arr[j++] = nodes[i];
		}
	}
	
	return arr;
}

// ---------------------------------------------------------
// set up the menubar
// ---------------------------------------------------------
init_menubar();
