/*==========================================================================
	JavaScript Menus 
		written by Dion Campbell at Pyron Technologies...
		dion@pyrontechnologies.com
		
	Last Revision: 2-17-00

	Allows a developer to create Hierarchial menus trees of any length
	by simply creating them in the menuDEF.js and the script handles the
	rest... All properties and attributes for the menus are specified in 
	the menuDEF.js file...
  ==========================================================================*/

/*--------------------------------------------------------------------------
  Browser Detect...
  --------------------------------------------------------------------------*/
var isNav4, isIE4;
if(parseInt(navigator.appVersion) >= 4) {
	if(navigator.appName == "Netscape") {
		isNav4 = true;
	}
	else {
		isIE4 = true;
	}
}


/*--------------------------------------------------------------------------
  Global Variables
  --------------------------------------------------------------------------*/
var elementProperties = null; // This is assigned the properties for all elements
var menus = new Array(); // Serves as the storage for quasi-stack for open menus...
var globalMenuElements = new Array(); // Stores all menu element objects.
var activeElement = null; // Storage for the current active element...
var timer = null; // timer reference to close menus if mouse outside the menus...


/*--------------------------------------------------------------------------
  elementProps()
  Constructor for element properties...
  	Creates a global object that allows access to common element attributes 
  	anywhere in the script, is stored in global variable elementProperties...
  --------------------------------------------------------------------------*/
function elementProps(imageSrc, imageSize, childHOverlap, childVOverlap, bgcolor, styletype, menuCloseDelay) {

	this.classId = "classId";
	this.highlightcolor = null;
	this.imageSrc = imageSrc;
	this.imageSize = imageSize;
	this.childHOverlap = childHOverlap;
	this.childVOverlap = childVOverlap;
	//this.bgcolor = bgcolor;
	this.width = styletype['width'];
	this.borderwidth = styletype['border-width'];
	this.menuCloseDelay = menuCloseDelay;
	
	var styleStr = "\n<STYLE TYPE='text/css'>";
	styleStr += "<!--\n";
	styleStr += "." + this.classId + " {\n";
	for(var i in styletype) {
		styleStr += i + ": " + styletype[i] + ";\n";
	}
	styleStr += "}\n";
	styleStr += "// -->\n";
	styleStr += "</STYLE>\n";

	document.write(styleStr);
	
	elementProperties = this; // assigns the global element properties...
	
	return this;
} // end elementProps()


/*--------------------------------------------------------------------------
  menu()
  Constructor for menus
  	Creates a menu object with all needed storage and function references,
  	uses an array to store the menu elements for the menu...
  --------------------------------------------------------------------------*/
function menu() {
	this.menuElements = new Array();
	this.highlighted;
	this.isStatic = menu.arguments[0]; // isStatic
	this.props = menu.arguments[1]; // props
	this.menuName = menu.arguments[2]; // menuName
	this.activeElement = null;
	this.menuWidth = elementProperties.width;
			
	// Gather arguments from menu, construct each element and store them
	// in the menuElements array...
	var j = 0;
	for(var i = 0; i < menu.arguments.length - 2; i += 6) {
		this.menuElements[j] = new menuElement(	menu.arguments[i + 2], 
							menu.arguments[i + 3], 
							menu.arguments[i + 4], 
							menu.arguments[i + 5],
							menu.arguments[i + 6],
							this.props,
							menu.arguments[i + 7],
							this.menuElements,
							this);
		j++;
	} 
	
	this.menuHeight = getMenuHeight(this);
	this.adjust = adjustMenu; 
	return this;
} // end menu()


/*--------------------------------------------------------------------------
  getMenuHeight()
  	Returns menu height to menu constuctor to make sure
  	windows do not appear outside the window...
  --------------------------------------------------------------------------*/
function getMenuHeight(menu) {

	var tmpHeight = 0;
	for(var i = 0; i < menu.menuElements.length; i++) {
		tmpHeight += menu.menuElements[i].elementHeight;	
	}
	return tmpHeight;
}


/*--------------------------------------------------------------------------
  closeAll()
  	Used to Close ALL open menus
  --------------------------------------------------------------------------*/
function closeAll() {
	var staticFlag;
	for(var i = 0; i < menus.length; i++) {
		staticFlag = closeMenu();
		if(staticFlag){
			break;
		}
	}
	if(!staticFlag){
		if(menus.length > 0){
			closeAll();
		}
	}
} // end closeAll()


/*--------------------------------------------------------------------------
  openEventMenu()
 	Used by on_event fuctions in HTML to get the root menu to open.  Used
 	for dynamically placed menus where the cursor existed at the time of 
 	the event...
  --------------------------------------------------------------------------*/
function openEventMenu(menu, e) {

	// make sure no open menus exist...
	closeAll();
	
	// ensures that if the timer is already set, it will be reset to allow proper delays...
	if(timer) {
		clearTimeout(timer);
	}
	
	// set timer in the event the cursor does not move over the menu...
	timer = setTimeout("closeAll();", elementProperties.menuCloseDelay);
	
	// get starting coordinates for root menu
	var xPos = (isIE4) ? event.x : e.pageX;
	var yPos = (isIE4) ? event.y : e.pageY;
		
	// open the menu...
	openMenu(menu, xPos, yPos);
	
} // end openFirstMenu()


/*--------------------------------------------------------------------------
  openStaticMenu()
 	Used by on_event fuctions in HTML to get the root menu to open.  Used
 	for statically placed menus where a developer wants the menu to open.
  --------------------------------------------------------------------------*/
function openStaticMenu(menu, x, y) {

	// make sure no open menus exist...
	closeAll();
	
	// ensures that if the timer is already set, it will be reset to allow proper delays...
	if(timer) {
		clearTimeout(timer);
	}
	
	// set timer in the event the cursor does not move over the menu...
	timer = setTimeout("closeAll();", elementProperties.menuCloseDelay);
	
	// open the menu...
	openMenu(menu, x, y);
	
} // end openFirstMenu()


/*--------------------------------------------------------------------------
  on_MouseOver()
  	Handles all menu functionality as the cursor is moved around the menus.
  --------------------------------------------------------------------------*/
function on_MouseOver(id, color) {
	var menuChild = globalMenuElements[id].childName;
	var obj = globalMenuElements[id].obj;
	var childObj = null;
	var menuObj = globalMenuElements[id].menu;
	
	// clear timer if set...
	clearTimeout(timer);
	
	// Checks if their is an active element, if so checks to make sure not
	// to unhighlight parent element if cursor has gone over child element.
	if (activeElement) {
		if(globalMenuElements[activeElement].childName != menuObj.menuName) {
		
			var activeObj = globalMenuElements[activeElement].obj;
			var activeElement2 = globalMenuElements[activeElement];
		
			if(isIE4) {
				activeObj.style.backgroundColor = activeElement2.bgcolor;
			}
			else {
				activeObj.bgColor = activeElement2.bgcolor;
			}
		}
	}
	
	// If menu has any active elements, unhighlights them... This is needed
	// in the event that the cursor is moved out of the menus and then back
	// into the menus below the last menu openeds parent...
	if(menuObj.activeElement) {
		var activeMenuObj = globalMenuElements[menuObj.activeElement].obj;
		var activeMenuElement = globalMenuElements[menuObj.activeElement];
				
		if(isIE4) {
			activeMenuObj.style.backgroundColor = activeMenuElement.bgcolor;
		}
		else {
			activeMenuObj.bgColor = activeMenuElement.bgcolor;
		}
	}
		
		
	menuObj.activeElement = id; // sets active element in specific menu
	activeElement = id; // sets global active element
	
	// Highlight new active element
	if(isIE4) {
		obj.style.backgroundColor = color;
	}
	else {
		obj.bgColor = color;
	}
	
	// Hide all menus on stack above this menu...
	while(menus[0].menuName != menuObj.menuName) {
		
		closeMenu();
	}
	
	// open child menu for this id...
	if(menuChild) {
		
		childObj = eval(menuChild);
		if(isIE4) {
			var xCord = obj.style.pixelLeft + elementProperties.childHOverlap;
			var yCord = obj.style.pixelTop + elementProperties.childVOverlap;
		}
		else {
			var xCord = obj.left + elementProperties.childHOverlap;
			var yCord = obj.top + elementProperties.childVOverlap;
		}
		openMenu(childObj, xCord, yCord);
		
	}
	
} // end on_MouseOver()


/*--------------------------------------------------------------------------
  on_MouseOut()
  	Sets window timer to close windows if mouseout of menus....
  --------------------------------------------------------------------------*/
function on_MouseOut(id, color) {
 	timer = setTimeout("closeAll();", elementProperties.menuCloseDelay);
} // end on_MouseOut()


/*--------------------------------------------------------------------------
  closeMenu()
  	Closes menu sent to it...
  --------------------------------------------------------------------------*/
function closeMenu() {
	var staticFlag;
 	// checks if "isStatic" is set to true,,, if so,,, no close...
	if(!menus[0].isStatic)
	{
		// clear the active element for this menu...
		menus[0].activeElement = null;
		
		// Sets all bgcolors and hides the elements for this menu...
 		for(var i = 0; i < menus[0].menuElements.length; i++)
		{
		 	var currentElement = menus[0].menuElements[i].obj;
		 	var currentElement2 = menus[0].menuElements[i];
			if(isIE4) {
				currentElement.style.backgroundColor = currentElement2.bgcolor;
				currentElement.style.visibility = "hidden";
			}
			else {
				currentElement.bgColor = currentElement2.bgcolor;
				currentElement.visibility = "hidden";
			}
		}
		
		// remove menu from stack...
		pop();
		
		// sets active element to current menus active element...
		if(menus.length > 0) {
			activeElement = menus[0].activeElement;
		}
		staticFlag = 0;
	}
	else {
		staticFlag = 1; //signals closeAll() to break out of loop...
	}
	return staticFlag;
} // end closeMenu()


/*--------------------------------------------------------------------------
  resizeHandler()
  	A workaround for Netscape4 resize bug... This function is triggered
  	by an onResize event in the <BODY> tags of the web document...
  --------------------------------------------------------------------------*/
  function resizeHandler() {
  	if(isNav4) {
  		location.reload();
  	}
  } // end resizeHandler()
    	
  	
/*--------------------------------------------------------------------------
  adjustMenu()
  	Positions the elements in the menu and and sets visibility to show...
  --------------------------------------------------------------------------*/
function adjustMenu(left, top, zIndex) {

	var windowRightEdge = 0;
	var menuRightEdge = left + this.menuWidth;
	var windowBottomeEdge = 0;
	var menuBottomEdge = top + this.menuHeight;

	if(isIE4) {
		windowRightEdge = document.body.scrollLeft + document.body.clientWidth;
		windowBottomEdge = document.body.scrollTop + document.body.clientHeight;
	}
	else {
		windowRightEdge = window.pageXOffset + window.innerWidth;
		windowBottomEdge = window.pageYOffset + window.innerHeight;
	}

	// Check if menu drops below or out the side of window and adjusts it...
	if(menuRightEdge > windowRightEdge) {
		left -= (menuRightEdge - windowRightEdge);
	}
	if(menuBottomEdge > windowBottomEdge) {
		top -= (menuBottomEdge - windowBottomEdge);
	}
	
	// place each element in the correct postion...
	for(var i = 0; i < this.menuElements.length; i++){
	 	var currentElement = this.menuElements[i].obj;
		if(isIE4) {
			currentElement.style.pixelLeft = left;
			currentElement.style.pixelTop = top;
			currentElement.style.zIndex = zIndex + 20;
			currentElement.style.visibility = "visible";
			top += currentElement.offsetHeight - elementProperties.borderwidth;
			
		}
		else {
			currentElement.moveTo(left, top);
			currentElement.zIndex = zIndex + 20;
			currentElement.visibility = "visible";
			top += currentElement.clip.height - elementProperties.borderwidth;
		}
	}
} // end adjustMenu()


/*--------------------------------------------------------------------------
  openMenu()
  	Handles all opening of menus...
  --------------------------------------------------------------------------*/
function openMenu(menu, left, top) {
	
	// Get zIndex for menu that is about to be displayed... 
	var zIndex = menus.length;
	
	// Push menu onto stack...
	push(menu);
	
	// clear timer if set...
	//clearTimeout(timer);
	
	// adjust and set visibility...
	menu.adjust(left, top, zIndex);
} // end openMenu()


/*--------------------------------------------------------------------------
  openPage()
  	Opens a hyperlink if one was specified in menuDEF.js...
  --------------------------------------------------------------------------*/
function openPage(hyperlink) {

	location.href = hyperlink;
	
}// end openPage()


/*--------------------------------------------------------------------------
  menuElement()
  Constructor for menu elements.
  	Constructs both the HTML objects as well as the JavaScript Objects 
  	that get stored in the appropriate menus menuElements array...
  --------------------------------------------------------------------------*/
function menuElement(menuName, label, hyperlink, highlightcolor, bgcolor, itemproperties, childName, menuElements, menu) {
	var id = globalMenuElements.length; // assigns unique identifier for each element...
	this.bgcolor = bgcolor; 
	this.highlightcolor = highlightcolor;
	this.childName = childName;
	this.borderwidth = itemproperties.borderwidth;
	this.hyperlink = hyperlink;
	this.menu = menu;
		
	var gatherObj = "";

	if (isIE4) {
		gatherObj += "<div id=\"" + id + "\"";
		gatherObj += " class=\"" + itemproperties.classId + "\"";
		gatherObj += " style=\"";
		gatherObj += " position: absolute;";
		gatherObj += " visibility: hidden;";
		gatherObj += " left: 15;";
		gatherObj += " top: 0;";
		gatherObj += " background-color: " + this.bgcolor +";";
		gatherObj += " z-index: 1;";
		gatherObj += "\"";
		gatherObj += " onmouseover=\"on_MouseOver('" + id + "'" + ", '" + this.highlightcolor + "');\""; 
		gatherObj += " onmouseout=\"on_MouseOut('" + id + "'" + ", '" + this.bgcolor + "');\"";  
	 	if (hyperlink != "") {
			gatherObj += " onclick=\"openPage('" + hyperlink + "');\"";
		}           
		gatherObj += ">";
		if (childName != "") {
			gatherObj += "<img src=\"" + itemproperties.imageSrc + "\" align=\"right\" border=0 height=" + itemproperties.imageSize + " vspace=2>"
		}
		gatherObj += "<nobr>" + label
		gatherObj += "</nobr></div>";
	} else if (isNav4){
		gatherObj += "<layer id=\"" + id + "\"";
		gatherObj += " class=\"" + itemproperties.classId + "\"";
		gatherObj += " visibility=\"hidden\"";
		gatherObj += " left=15";
		gatherObj += " top=0";
		gatherObj += " width=" + itemproperties.width;
		gatherObj += " bgcolor=" + this.bgcolor;
		gatherObj += " z-index=0";
		gatherObj += " onmouseover=\"on_MouseOver('" + id + "'" + ", '" + this.highlightcolor + "');\""; 
		gatherObj += " onmouseout=\"on_MouseOut('" + id + "'" + ", '" + this.bgcolor + "');\"";  
	 	if (hyperlink != "") {
			gatherObj += " onFocus=\"openPage('" + hyperlink + "');\"";
		}      
		gatherObj += ">";
		if (childName != "") {
			gatherObj += "<img src=\"" + itemproperties.imageSrc + "\" align=\"right\" border=0 height=" + itemproperties.imageSize + " vspace=2>"
		}
		gatherObj += label;
		gatherObj += "</layer>";
	}
	
	document.write(gatherObj);  // writes to the browser

	this.obj = getObject(id);	
	globalMenuElements[id] = this; // stores the element in global list for quick retrieval...
	
	// stores element height...
	if(isIE4) {
		this.elementHeight = this.obj.offsetHeight - elementProperties.borderwidth;
	}
	else {
		this.elementHeight = this.obj.clip.height - elementProperties.borderwidth;
	}
		
	return this;
} // end menuElement()


/*--------------------------------------------------------------------------
  getObject()
  	Used to get the HTML object when given the id of the object created in 
  	menuElements()...
  --------------------------------------------------------------------------*/
function getObject(id) {

	if (isIE4) {
		return eval("document.all(\"" + id + "\")");
	}
	else if (isNav4) {
		return eval("document.layers[\"" + id + "\"]");
	}
	return null;
	
} // end getObject()


/*==========================================================================
  JavaScript "quasi"-stack  :-)
  	Uses the global array menus to keep track of all open menus...  Allows
  	the functionality of unlimited (well almost unlimited...) length of 
  	menus that can be used... This functionality is predifined in Nav4 but
  	not in IE4...
  ==========================================================================*/
// pops top element off the stack
function pop() {
	if(menus.length > 0) {
		
		var temp = menus[0];
			
		for (var i = 0; i < menus.length; i++) {
			menus[i] = menus[i + 1];
		}
		menus.length -= 1;
		
		return temp;
	}
}

// push top menu onto the stack...	
function push(item) {
	for (var i = menus.length; i > 0; i--) {
		menus[i] = menus[i - 1];
	}
	menus[0] = item;
}




	
	