/*
	===============================================================

	menu.js
	
	v 0.3.1 beta
	
	© 2004 Beau Scott | beau_scott@hotmail.com
	
	Feel free to redistribute this javascript at your leisure, just
	leave this header in and email me to let me know what site you're
	using it on.
	
	Usage:
	
	var myMenu = new Menu("myID", "parentID", [["classOver"], ["classOut"], ["parentClassOver"], ["parentClassOut"], ["classContainer"], [ExpandRate]]);
	
	Properties:
	
		--- Reqired ---
		myID 			= a unique HTML ID for this menu, cannot already exist in the document.
		parentID		= the ID of an existing HTML element that will serve as the starting point for this menu. (must be equal the name of the object)
	
		--- Optional ---
		classOver 		= the CSS class of the menu items when the mouse is over them.
		classOut 		= the CSS class of the menu items when the mouse IS NOT over them.
		parentClassOver = the CSS class of the parent element with the mouse over it;
		parentClassOut 	= the CSS class of the parent element with the mouse NOT over it.
		classContainer	= the CSS class of the menu container. You only need to specify width and whitespace parameters for this.
		ExpandRate 		= an integer representing the amount of time you want between each menu element 
						  being displayed, gives a scrolling effect. 0 = instataneous (default); 10-150 is a good scrolling speed.
	
	Methods:
		init()						= Initializes the object. This item must be called in the body tags onLoad event.
		add(label, url [, target])	= Adds menu items to the specified menu object.
										
										--- Required Properties ---
										label	= the menu item caption
										url		= the URL that the menu item links to
										
										--- Optional Properties ---
										target	= the target window of the URL. Leaving it blank will open the link in the current window.
												  Enter "_new" to have a new window open.
												  
										--- Usage ---
										myMenu.add("My Label", "http://myURL.com", "_self");
		
	
	Instructions:
		
		You must have an HTML element with the ID that you assign this objects parentID to. This parent item can be any type of HTML
		element (div, span, table cell, image, etc.).
		
		You must also give this menu object the ID of your parent HTML element.
		
		For hover effects, specify CSS classnames for when you instantiate it. There is no need to 
		specify mouse over events on the parent items, the script will do that for you, however, you will need to add the "onload" event to you body tag
	
	
	Example Page:
	
	<html>
		<head>
			<script language="javascript" src="menu.js"></script>
			<script language="javascript">
			<!-- 
			
				// Products Menu
				var menuProducts = new Menu("items", "menuProducts", "menuItemOver", "menuItemOut", "menuHeaderOver", "menuHeaderOut", "menuContainer", 10);
					menuProducts.add("Widget A", "WidgetA.htm");
					menuProducts.add("Widget B", "WidgetB.htm");
					menuProducts.add("Widget C", "WidgetC.htm");
					
				//	Links Menu
				var menuLinks = new Menu("items", "menuLinks", "menuItemOver", "menuItemOut", "menuHeaderOver", "menuHeaderOut", "menuContainer", 10);
					menuLinks.add("Yahoo!", "http://www.yahoo.com", "_new");
					menuLinks.add("Ebay", "http://www.yahoo.com", "_new");
					
			//-->
			</script>
			<style type="text/css">
				
				.menuContainer {width: 150px; white-space: nowrap;}
				
				.menuItemOver { border: 1px solid black; background: yellow; padding: 5px; }
				.menuItemOver a { color: blue; text-decoration: none; }
				
				.menuItemOut { border: 1px solid blue; background: blue; padding: 5px; }
				.menuItemOut a { color: white; text-decoration: none; }
				
				.menuHeaderOver { background: blue; padding: 5px; color: white;}
				.menuHeaderOut { background: gray; padding: 5px; color: black; }
				
			</style>
		</head>
		<body onload="menuProducts.init(); menuLinks.init();">
			<table>
				<tr>
					<td id="menuProducts" class="menuHeaderOut">Products</td>
					<td id="menuLinks" class="menuHeaderOut">Links</td>
				</tr>
			</table>
		</body>
	</html>
	
	===============================================================
*/


//-- Global properties, common for all menus --//
var mouse_x = 0;
var mouse_y = 0;
var globalCurrentFunction = null;
var topZIndex = 1000;
var netscape = document.all ? false : true;

//-- Capture the events for IE/Moz --//
if(window.captureEvents){
	window.captureEvents(Event.MOUSEMOVE, Event.CLICK);
}
window.onclick = clientHideMenus;
document.onclick = clientHideMenus;
window.onmousemove = clientGetMouseLoc;
document.onmousemove = clientGetMouseLoc;

//-- Record mouse movements --//
function clientGetMouseLoc(e){
	mouse_x = netscape ? e.clientX : window.event.x;
	mouse_y = netscape ? e.clientY : window.event.y;
}

//-- Hide the menus when the 
function clientHideMenus(){
	showSelects();
	if(globalCurrentFunction)
		if(! eval(globalCurrentFunction + ".isOver()"))
			eval(globalCurrentFunction + ".forceOff();");
}

//-- Menu Object --//
function Menu(myID, parentID, classOver, classOut, parentClassOver, parentClassOut, menuContainer, ExpandRate){
	
	//-- Specified Required Public Properties
	this.parentID = parentID;
	this.id = myID;
		
	//-- Specified Optional Public Properties
	this.classContainer = menuContainer || null;
	this.parentClassOver = parentClassOver || null;
	this.parentClassOut = parentClassOut || null;
	this.classOver = classOver || null;
	this.classOut = classOut || null;
	this.menuExpandRate = ExpandRate || 0;
	
	//-- Other Public Properties
	this.layer = null;
	this.positionLeft = 0;
	this.positionTop = 0;
	this.isOn = false;
	this.timer = [];
	this.timeOut = 500;
	this.menuItems = [];
	this.menuObjects = [];
	this.menuExpandDelay = 0;
	
	//-- Public Methods
	this.init = menuInit;
	this.add = menuAdd;
	
	//-- Other Methods
	this.show = menuShow;
	this.hide = menuHide;
	this.off = menuOff;
	this.forceOff = menuForceOff;
	this.isOver = menuIsOver;
	this.sort = menuSort;
	this.showItem = menuShowItem;
}

function menuInit(){
	var newLayer = document.createElement("div");
	newLayer.id = this.id;
	
	if(this.classContainer)
		newLayer.className = this.classContainer;
		
	newLayer.style.top = 0;
	newLayer.style.left = 0;
	newLayer.style.visibility = "hidden";
	newLayer.style.position = "absolute";
	this.layer = newLayer;
	this.parent = document.getElementById(this.parentID);
	
	if(!this.classContainer)
		newLayer.style.width = this.parent.offsetWidth + "px";
	
	this.parent.onmouseover = function(){eval(this.id + '.show();');};
	this.parent.onmouseout= function(){eval(this.id + '.hide();');};
	document.body.appendChild(this.layer);
}

function menuShow(){
	hideSelects();
	if(!this.isOn){
		if(globalCurrentFunction){
			if(globalCurrentFunction != this.parentID){
				eval(globalCurrentFunction + ".forceOff();");
				globalCurrentFunction = null;
			}
		}
		globalCurrentFunction = this.parentID;
		
		this.positionTop = 0;
		this.positionLeft = 40;
		
		var newObj = this.parent;
		while(newObj.tagName && newObj.tagName.toLowerCase() != "body"){
			this.positionLeft += newObj.offsetLeft;
			this.positionTop += newObj.offsetTop;
			if(newObj.offsetParent)
				newObj = newObj.offsetParent;
			else
				newObj = newObj.parentNode;
		}
		
		if(this.parentClassOver)
			this.parent.className = this.parentClassOver;
		
		this.layer.style.visibility = "visible";
		this.layer.style.top = (this.positionTop + this.parent.offsetHeight) + "px";
		this.layer.style.left = this.positionLeft + "px";
		this.layer.style.zIndex = (topZIndex += 1);
		
		for(var i = 0 ; i < this.menuItems.length; i++){
			var newMenuItem = document.createElement("div");		
			newMenuItem.id =  this.layer.id + "_" + this.menuItems[i][0];

			if(this.classOut)
				newMenuItem.className = this.classOut;
			
			if(netscape)
				newMenuItem.style.cursor = "pointer";
			else
				newMenuItem.style.cursor = "hand";
			
			if(this.classOver)
				newMenuItem.onmouseover = function() {this.className = eval(globalCurrentFunction + ".classOver");};
			if(this.classOut)
				newMenuItem.onmouseout = function() {this.className = eval(globalCurrentFunction + ".classOut"); eval(globalCurrentFunction + '.hide();');};
			
			if(!newMenuItem.style.width)
				newMenuItem.style.width = "100%";
			
			//--newMenuItem.onclick = function() { if(this.childNodes){ eval("window['" + (new String(this.childNodes[0].target).replace("_", "")) + "'].location.href = '" + this.childNodes[0].href + "';"); }};
			
			var innerLink = document.createElement("a");
			innerLink.href = this.menuItems[i][1];
			
			if(this.menuItems[i][2])
				innerLink.target = this.menuItems[i][2];
			
			innerLink.innerHTML = this.menuItems[i][0];
			newMenuItem.appendChild(innerLink);
			
			this.menuObjects.push(newMenuItem);
			this.timer.push(setTimeout(globalCurrentFunction + ".showItem(" + i + ");", (this.menuExpandDelay += this.menuExpandRate)));
		}
		this.isOn = true;
	}
}

function menuShowItem(objID){
	hideSelects();
	if(this.isOn){
		this.layer.appendChild(this.menuObjects[objID]);
	}
}

function menuHide(){
	showSelects();
	if(this.isOn){
		if(!this.isOver()){
			this.timer.push(setTimeout(this.parentID + ".off()", this.timeOut));
		} else {
			this.timer.push(setTimeout(this.parentID + ".hide()", this.timeOut));
		}
	}
}

function menuAdd(label, url, target){
	var sTarget = null;
	
	if(target)
		sTarget = target;
		
	this.menuItems.push(new Array(label,url, sTarget));
	this.menuItems.sort(this.sort);
}

function menuOff() {
	showSelects();
	if(this.isOn){
		if(!this.isOver()){
			this.forceOff();
		} else {
			this.timer.push(setTimeout(this.parentID + ".hide()", this.timeOut));
		}
	}
}

function menuForceOff() {
	showSelects();
	this.layer.innerHTML = "";
	this.layer.style.visibility = "hidden";
	this.layer.style.top = 0;
	this.layer.style.left = 0;
	this.isOn = false;
	
	if(this.parentClassOut)
		this.parent.className = this.parentClassOut;
		
	globalCurrentFunction = null;
	this.menuExpandDelay = 0;
	this.menuObjects = null;
	this.menuObjects = [];
	for(var i = 0; i < this.timer.length; i++){
		clearTimeout(this.timer[i]);
	}
	this.timer = null;
	this.timer = [];
}

function menuSort(a,b){
	if(a[0] > b[0])
		return 1;
	else
		return -1;
}

function menuIsOver(){
	hideSelects();
	var t = this.positionTop - document.body.scrollTop;
	var l = this.positionLeft - document.body.scrollLeft;
	var b = t + this.layer.offsetHeight + this.parent.offsetHeight;
	var r = l + this.layer.offsetWidth;	
	
	var overWidth = (mouse_x < l) ? false : (mouse_x > r) ? false : true;
	var overHeight = (mouse_y < t) ? false : (mouse_y > b) ? false : true;
	
	var overLayer = false;
	
	if(overWidth)
		if(overHeight)
			overLayer = true;
	
	if(overHeight)
		if(overWidth)
			overLayer = true;
	
	if(this.layer.style.zIndex < topZIndex)
		overLayer = false;
	
	return overLayer;
}




