/**********************************************
 Browser control variables  
 These variables determine which browser is being used
**********************************************/ 
var isNav = (document.layers) ? true:false				//Layers compliant browser (Netscape 4.x)
var isIE = (document.all) ? true:false				//IE4/5 compliant browser 
var isMac = (navigator.appVersion.indexOf('Mac') != -1) ? true : false //Mac based browser
var isDOM = (document.getElementById) ? true:false	   	//DOM Compliant browser (NS6, Opera 5)
var isOther = (!isNav&&!isDOM&&!isIE) ? true:false				//Other browser (NS3, Lynx)

/**********************************************
 createReference(stringexp)    
 stringexp:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  A reference to an object style.
 Description:   Creates a string reference to the style of an HTML element on the page.  Since each browser does Obj 
 				referencing differently, we have to branch it.
**********************************************/ 
function createReference(Element) {
	if (isDOM && !isIE) {
		oRef = eval("document.getElementById('" + Element + "').style")
	} else if (isNav) {
		oRef = eval("document.layers['" + Element + "']")
	} else {
		oRef = eval("document.all." + Element + ".style")
	}
	return oRef
}

/**********************************************
 setElementVisibility(stringexp1, stringexp2)    
 stringexp 1 and 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  none
 Description:  Sets the Visibility property (given in Stringexp2) for the element ID specifiec in Stringexp1.  This can be set to either
 				visible or hidden.
**********************************************/ 
function setElementVisibility(Element, state) {
	oElement = createReference(Element)
	if (isNav) { state = state.toUpperCase() == "VISIBLE" ? "show":"hide" }		//Because NAV4 does visibility states differently, swap to corresponding word.
	oElement.visibility = state.toLowerCase(); 
}

/**********************************************
 getElementVisibility(stringexp)    
 stringexp:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  none
 Description:  Gets the Visibility property for the element ID specifiec in Stringexp. 
**********************************************/ 
function getElementVisibility(Element) {
	oElement = createReference(Element)
	elementVis = oElement.visibility;
	return elementVis
}

/**********************************************
 setElementDisplay(stringexp1, stringexp2)    
 stringexp 1 and 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  none
 Description:  Sets the Display property (given in Stringexp2) for the element ID specifiec in Stringexp1.  This can be set to any valid 
 				display style (e.g. Block, inline, none)
**********************************************/ 
function setElementDisplay(Element, state) {
	oElement = createReference(Element)
    if (!isNav) { oElement.display = state.toLowerCase(); }		//This function does not work in NAV4!
}



/**********************************************
 getElementDisplay(stringexp1)    
 stringexp:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  none
 Description:  Gets the Display property for the element ID specifiec in Stringexp.  
**********************************************/ 
function getElementDisplay(Element, state) {
	oElement = createReference(Element)
    if (!isNav) { elementDisp = oElement.display }		//This function does not work in NAV4!
	return elementDisp
}


/**********************************************
 setElementPosition(stringexp1, integer1, integer2)    
 stringexp  
 	use:  Required
	Datatype:  String
	A valid string expression
 integer 1 and 2  
 	use:  Required
	Datatype:  Integer
	A valid integer
 Description:   This function moves the element in Stringexp to the coordinates specified by ints 1 and 2.  You must specify both X and Y coords.
**********************************************/ 
function setElementPosition(Element, elX, elY) {
	oElement = createReference(Element)
    if (isIE) {  												
		oElement.pixelTop = elY
		oElement.pixelLeft = elX
	} else {
        oElement.left = elX + 'px'
		oElement.top = elY + 'px'
	}
}


/**********************************************
 getElementPosition(stringexp1, stringexp2)    
 stringexp 1 and 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  Integer
 Description:   This function retrieves the coordinate (stringexp2) for the element ID specified in Stringexp1.  Stringexp2 must be set to left or top.
**********************************************/ 
function getElementPosition(Element, side) {
	oElement = createReference(Element)
    if (isIE) {  												//String manip:  Make sure side is Left or Top...IE doesn't understand all lower case.
		elementPos = eval('oElement.pixel' + (side.toUpperCase()).substring(0,1) + (side.toLowerCase()).substring(1,side.length))	
	} else if (isDOM) {
        elementPos = parseInt(eval('oElement.' + side.toLowerCase()))
    } else {
		elementPos = eval('oElement.' + side.toLowerCase())
	}
    return elementPos
}

/**********************************************
 getPageOffset(obj1, stringexp2)    
 Obj1:
 	use:required
	Datatype:  Object
	A valid object reference
 stringexp 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  Integer
 Description:   This function retrieves the coordinate (stringexp2) for the element  specified in obj1.  
 				Obj1 musty be an object reference in form document.all.ID or document.getElementbyId('ID') 
				as appropriate for the given browser.Stringexp2 must be set to left or top.
**********************************************/ 
function getPageOffset(el, coord) {
	var x;
	// Return the x coordinate of an element relative to the page.
	if (coord == "left") {
		x = el.offsetLeft;
		if (el.offsetParent != null){
			x += getPageOffset(el.offsetParent, 'left');
		}
	} else {
		x =  el.offsetTop;
		if (el.offsetParent != null){
			x += getPageOffset(el.offsetParent, 'top');
		}
	}
	return x;
}

/**********************************************
 getElementDimension(stringexp1, stringexp2)    
 stringexp 1 and 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  Integer
 Description:   This function retrieves the dimension (stringexp2) for the element ID specified in Stringexp1.  Stringexp2 must be set to width or height.
**********************************************/ 
function getElementDimension(Element, dim) {
    oElement = createReference(Element)
    if (isIE) {												//String manip:  Make sure side is Left or Top...IE doesn't understand all lower case.
		elementDim = eval('oElement.pixel' + (dim.toUpperCase()).substring(0,1) + (dim.toLowerCase()).substring(1,dim.length))
	} else if (isDOM) {
        elementDim = parseInt(eval('oElement.' + dim.toLowerCase()))
    } else {
		elementDim = eval('oElement.document.' + dim.toLowerCase())
	}
    return elementDim
}

/**********************************************
 getElementUNPOSDimension(stringexp1, stringexp2)    
 stringexp 1 and 2:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  Integer
 Description:   This function retrieves the dimension (stringexp2) for the UNDIMENSIONED element ID specified in Stringexp1.  Stringexp2 must be set to width or height.
**********************************************/ 
function getElementUNPOSDimension(Element, dim) {
	oElement = createReference(Element)
	if (isIE && !isMac) {	
		if (dim == "width") {
			dim = "scrollWidth"
		} else {
			dim = "scrollHeight"
		}						
		elementDim = eval('document.all.' + Element + '.' + dim);
	} else {
		if (dim == "width") {
			dim = "offsetWidth"
		} else {
			dim = "offsetHeight"
		}	
		elementDim = eval('document.getElementById("' + Element + '").' + dim);	
    }

    return elementDim
}

/**********************************************
 setElementClass([stringexp, str2])    
 Return:  Nothing
 Description:   Replaces style class of element found at reference stringexp with specified class str2.  Class may
 				may be specified in page, or in external stylesheet, but a class name MUST be used.
 Tips:  You may use any number of argument pairs to swap multiple classes at the same time.  Arguments MUST be 
  		paired;  args not paired will result in an error.
**********************************************/ 
function setElementClass() {
    for (var i=0; i<setElementClass.arguments.length; i+=2) {
		if (isIE) { 
			eval('document.all.' + setElementClass.arguments[i] + '.className = "' + setElementClass.arguments[i+1] + '"'); 
		} else if (isDOM) {
			eval('document.getElementById(\'' + setElementClass.arguments[i] + '\').className = "' + setElementClass.arguments[i+1] + '"'); 
		}
	}
}


/**********************************************
 Menu tracking variables
 These variables are used to determine when to shut off menus
**********************************************/ 
var currentMenu = ""		//Lists the ID of the menu currently shown
var XShift = -2			//Holds number of pixels to shift popout on X coord
var YShift = 27				//Holds number of pixels to shift popout on Y coord
var XMacShift = 20;			//Holds fudge factor for Mac X margin misread.
var YMacShift = 20          //Holds fudge factor for Mac Y margin misread.
var onMenuLink = false		//NAV4 only:  Lets you know if you're still on a triggering link.


/**********************************************
 openMenu(stringexp)    
 stringexp:  
 	use:  Required
	Datatype:  String
	A valid string expression
 Return:  none
 Description:  sets the visibility style of the Element specified by stringexp to visible.
 			   In addition, tracks that element for later deactivation.
**********************************************/ 
function openMenu(event, Element) {
	if (document.getElementById(Element) || document.all.Element ) { 
		if (isIE) {												
		  current = window.event.srcElement;					//Set current to menu trigger moused over.
		}
		else {
		  current = event.currentTarget;						//Set current to menu trigger moused over.
		}
		var elContainerWidth = getElementUNPOSDimension('globalNav', 'width');
		var elMenuWidth = getElementUNPOSDimension(Element, 'width');
		var elX = getPageOffset(current, 'left')
		var elY = getPageOffset(current, 'top')
		elY = elY-8

		if ((isMac) && (isIE)) {													// Kludge for margining in IE5 Mac:  I can't convince it to get the offset + margin position.  *shrug* 
			if (((elX+XShift) + elMenuWidth) > elContainerWidth) {
				setElementPosition(Element, (elContainerWidth - elMenuWidth + 31 + XMacShift), (elY + YShift + YMacShift))
			} else {
				setElementPosition(Element, (elX+XShift+XMacShift), (elY+YShift+YMacShift)) 
			}
			
			
		} else {
			//if (((elX+XShift) + elMenuWidth) > elContainerWidth) {
			//	setElementPosition(Element, (elContainerWidth - elMenuWidth + 31), (elY + YShift))
			//} else {
				setElementPosition(Element, (elX + XShift), (elY + YShift))
			//}
		}

		if (currentMenu != "") setElementVisibility(currentMenu, 'hidden');			//If there is a menu currently showing, set it's visibility to hidden.
		setElementVisibility(Element, 'visible');									//Set the visibility of the menu specified to visible.
		currentMenu = Element;														//Set currentMenu to be the menu we're opening now.
	}													
}

/**********************************************
 closeMenu(event, stringexp)    
 stringexp:
 	use:  Required
	Datatype:  String
	A valid string expression
 event:  
 	use:  required
	Datatype:  A browser Event
	A vaid browser event reference for capture.
 Return:  none
 Description:  Closes the specified menu when the mouse moves out of the Div 
 			  and set currentMenu to nothing. 
 Tips:  This function is called like:  closeMenu(event, 'TESTDIV1').  You must ALWAYS specify the word event as the first arg.
**********************************************/ 
function closeMenu(event, Element) {
	if (currentMenu != "") {
		var current, related, container;									//Set Varibles to track targets of event (Note:  Understanding the DOM model is KEY for this!)
		if (isIE) {												
		  current = eval("document.all." + Element);			//Set current to menu specified in Element.
		  related = window.event.toElement;						//Set related to the element we're mousing into.
		  container = eval("document.all.globalNav");
		}
		else {
		  current = event.currentTarget;						//Set current to the element that the mouseout is specified on.  (Could be done with a listener)
		  related = event.relatedTarget;						//Set related to the element we're mousing into.
		  container = eval("document.getElementById('globalNav')");
		}
		if (related != null) { 
			if (current != related && !nodeContains(current, related)) {	//If current isn't what we're mousing into, and the element we ARE mousing into doesn't contain related, then hide current, and set the currentMenu var to nothing. 
			   	if (Element == 'globalNav') {
					idstring = related.id;
					if ((idstring.indexOf('Menu') == -1) && (!nodeContains(container, related))) {
						x = getContainerWith(related, "DIV", "Menu")
						if (x == null) {
				 			if (currentMenu != "") setElementVisibility(currentMenu, 'hidden');
							currentMenu = ""
						}
					}
				} else {
					idstring = related.id;
					if ((idstring.indexOf('globalNav') == -1) && (!nodeContains(container, related))) {
				 		current.style.visibility = "hidden";					   
						currentMenu = "";
					}
				}	
			}
		}
	}
}

/**********************************************
 nodeContains(obj1, obj2)    
 obj1:
 	use:  Required
	Datatype:  Object reference
	A valid HTML object (ex.  Document.all.Elementname)
 obj2:
 	use:  Required
	Datatype:  Object reference
	A valid HTML object (ex.  Document.all.Elementname)
 Return:  Boolean
 Description:  Looks for two objects.  Loops through B's parent nodes one by one.  If A equals a 
 			   parentNode of B, then return true; A contains B.  Else, return false. 
**********************************************/ 
function nodeContains(a, b) {
		strLoop = ""		
		while (b.parentNode)
			if ((b = b.parentNode) == a)
	      		return true;
		return false;
	
}


function getContainerWith(node, tagName, className) {

  // Starting with the given node, find the nearest containing element
  // with the specified tag name and style class.

  while (node != null) {
    if (node.tagName != null && node.tagName == tagName &&
        hasClassName(node, className))
      return node;
    node = node.parentNode;
  }
  return node;
}

function hasClassName(el, name) {

  var i, list;

  // Return true if the given element currently has the given class
  // name.

  list = el.className.split(" ");
  for (i = 0; i < list.length; i++)
    if (list[i] == name)
      return true;

  return false;
}


