/*
# $Id$
#
# UlMenu
# James Gauld (james@thundermonkey.net)
*/

//-------------------------------
// UlMenu()
//--
// Containing function.
//-------------------------------
function UlMenu() {
}

//-------------------------------
// VOID UlMenu.build( [UlNode], [structureType] )
//--
// HTMLElement UlNode	= UlNode to be built
// INT structureType	= How to render the menus (0 = Vertical (default), 1 = Horizontal)
//--
// Prepares the specified menu for use as a DHTML menu.
// Leave UlMenu unspecified to automatically build all <UL> elements
// that contain a 'class="ulmenu"' attribute.
//-------------------------------
UlMenu.build = function(UlNode, structureType) {

	// Vars
	if(structureType==null) structureType = 0;

	// Find all <UL> nodes with the 'class="ulmenu"' attribute
	if(UlNode==null) {
		var allUlNodes = document.getElementsByTagName('ul');
		var UlNodes = new Array();
		for(var i=0; i<allUlNodes.length; i++) {
			var cssClass = allUlNodes[i].className;
			if(cssClass=='ulmenu') UlNodes[UlNodes.length] = allUlNodes[i];
		}
		delete allUlNodes;
		if(UlNodes.length<1) return;
	}
	else {
		var UlNodes = new Array();
		UlNodes[0] = UlNode;
	}

	// Convert each of the discovered nodes to a dynamic menu
	for(var m=0; m<UlNodes.length; m++) {

		// Create some properties for this menu
		UlNodes[m].activeMenuBtnIndex = null;						// Holds index button (LI) that has opened a submenu
		UlNodes[m].isFirstLevel = UlNodes[m].className=='ulmenu' ? true : false;	// Used when determining where to position submenus

		// Add some styles depending on the structural type required
		UlNodes[m].structureType = structureType;
		if(UlNodes[m].isFirstLevel) {
			var ulClass = structureType==1 ? 'ulmenu_h' : 'ulmenu_v';
			UlNodes[m].className += ' '+ulClass;
		}

		// Get menu buttons (LI nodes)
		// Filter out all text nodes (read by FF and OP)
		var allLiNodes = UlNodes[m].childNodes;
		var LiNodes = new Array();
		for(var n=0; n<allLiNodes.length; n++) {
			if(allLiNodes[n].nodeName=='LI') LiNodes[LiNodes.length] = allLiNodes[n];
		}
		delete allLiNodes;

		// Prepare each button in the menu
		var minWidth = 0;
		for(var n=0; n<LiNodes.length; n++) {

			// Determine the width taken up by the button
			if(LiNodes[n].offsetWidth>minWidth) minWidth = LiNodes[n].offsetWidth;

			// If this button contains a submenu (UL node), then build them
			// and attach some event handlers to the LI node to control the
			// opening/closing of that submenu.
			for(var sm=0; sm<LiNodes[n].childNodes.length; sm++) {
				if(LiNodes[n].childNodes[sm].nodeName=='UL') {

					// Store a reference to the submenu's childNode index
					// in the menu button, and add event handlers.
					LiNodes[n].childMenuIndex = sm;
					LiNodes[n].selfIndex = n;
					LiNodes[n].onmouseover = function() { UlMenu.hover(this); };
					LiNodes[n].onmouseout = function() { UlMenu.leave(this); };

					// Build the submenu
					UlMenu.build(LiNodes[n].childNodes[sm], structureType);
				}
			}
		}

		// Set min-width style to menu and all buttons
		// This is ignored by IE6-, which is a good thing because it works fine without this fix in IE.
		if(minWidth>0 && !UlNodes[m].isFirstLevel) {
			UlNodes[m].style.minWidth = minWidth+"px";
			for(var n=0; n<LiNodes.length; n++) {
				LiNodes[n].style.minWidth = LiNodes[n].style.maxWidth = minWidth+"px";
			}
		}
	}
}

//-------------------------------
// VOID UlMenu.hover( menuBtn )
//--
// HTMLElement menuBtn	= The <LI> node that is being hovered over
//--
// Open the specified menuBtn's sub-menu.
// This function is only called if an LI node actually contains a sub-menu.
//-------------------------------
UlMenu.hover = function(menuBtn) {

	// Get the child menu and containing menu objects
	var menu = menuBtn.parentNode;
	var subMenu = menuBtn.childNodes[menuBtn.childMenuIndex];

	// Display the submenu at the end of the specified menu (the actual position
	// is dependant on whether we want a vertical or horizontal menu).
	var posType = menu.isFirstLevel==0 ? 0 : menu.structureType;
	var pos = posType==0 ? {x:menuBtn.offsetWidth, y:0} : (posType==1 ? {x:0, y:menuBtn.offsetHeight} : {x:0, y:0});
	subMenu.style.top = pos.y+"px";
	subMenu.style.left = pos.x+"px";
	subMenu.style.visibility = 'visible';

	// Store this menuBtn in the containing menu's "activeMenuBtnIndex" flag
	menu.activeMenuBtnIndex = menuBtn.selfIndex;
}

//-------------------------------
// VOID UlMenu.leave( menuBtn )
//--
// HTMLElement menuBtn	= The <LI> node being left
//--
// Initiates a call to close the specified menuBtn's submenu.
//-------------------------------
UlMenu.leave = function(menuBtn) {

	// Get parent menu
	//var menu = menuBtn.parentNode;

	// If a sub-menu is currently active on the containing menu, close it
	if(menuBtn.childMenuIndex!=null) {
		UlMenu.close(menuBtn);
	}
}

//-------------------------------
// VOID UlMenu.close( menuBtn )
//--
// HTMLElement menuBtn	= The <LI> whose submenu will be closed
//--
// Closes the specified menuBtn's submenu.
//-------------------------------
UlMenu.close = function(menuBtn) {

	// Close the submenu
	menuBtn.childNodes[menuBtn.childMenuIndex].style.visibility = 'hidden';
}