

var parentObj = (isFrames) ? parent.document.body : window;
parentObj.onload = setup;


var margin = 5;
//var isMenu = true;

//var menuArray = new Array ();

// Important distinction here; activeMenu is the logically active menu.
var activeMenu = null;
// mousePointerMenu is the menu the mouse pointer is currently inside.
var mousePointerMenu = null;

//var overCaption = false;
//var cancelHide = false;

var doc = null;
var bodyFrame = null;
var framesPrefix = "";

var rootMenu;
var IDs = 0;

// MOD NEEDED
// Must remember to uncomment this before this version of the code goes live.
//window.onerror = function () { return true; }

function setup ()
{
	if (isFrames)
	{
		bodyFrame = eval("parent.frames." + mainFrName);
		if (bodyFrame && bodyFrame.document && bodyFrame.document.body) {
			doc = bodyFrame.document;
		}
	}	

	if (!doc)
		doc = document;

	if (isFrames && window && window.frameElement)
	{
		if (window.frameElement.name == "NAV")
		{
			framesPrefix = "parent.frames.NAV.";
			//doc.body.onmousemove = function (ev) { parent.frames.NAV.pageMouseMove (ev); };
		}
		else if (window.frameElement.name == "SUBNAV")
		{
			framesPrefix = "parent.frames.SUBNAV.";
			//doc.body.onmousemove = function (ev) { parent.frames.SUBNAV.pageMouseMove (ev); };	
		}
		else {
			// Apparently the original frames menu was intended to always have one of the
			// above two names? this is to make it more generic if above is not the case.
			framesPrefix = "parent.frames." + window.frameElement.name + ".";
		}
		//document.body.onmousemove = function (ev) { pageMouseMove (ev); };
	}
	else
	{
	/* deprecated.
		doc.onclick = function (ev) { popDown (null, ev); };
		doc.body.onmousemove = function (event) {
			var ev;
			if (window.event) { ev = window.event; }
			else { ev = event; }
			pageMouseMove (ev);
		};
	*/
	}

	menuArray = new Array ();
	activeMenu = null;
	activeSubMenu = null;

	rootMenu = new Menu();
	rootMenu.hasChildren = true;
	// Need to iterate through the top level of menus
	createTopLevel ("arMenu", rootMenu);

	// It would be good to build all positioning data here, but I can't see a 
	// practical way to do it.
}

function createTopLevel(arrayName, rootMenu) {
	var i=1;
	var topLevelArray;

	for (i=1; ; i++) {
		// passing variables in this manner is kind of ugly, because it requires
		// exception catching
		try {
			eval(arrayName + i);
		}
		catch (e) {
			break;
		}
		createMenus(arrayName + i, rootMenu, i);
		rootMenu.subMenus[i-1].isChild = false;
	}
}

// itemName is a specific item to create.
// baseMenu is NOT the top root menu, it is just the parent of this level of menus.
// If an item is marked as having children, that child will be found and added.
// Otherwise, ignored. Only at the top level will "unknown" items be searched for.
function createMenus (itemName, baseMenu, index)
{
	//var sectionMenu = eval ("window.arMenu1");
	// arrayName is the name of the current *level* we want to create, not the name
	// of an individual popup.
	var i;
	var sectionMenu = eval(itemName);
	var itemCount=1;

//	for (i=1, sectionMenu = eval(arrayName + "1"); sectionMenu != null; i++, sectionMenu = arrayName + i ) {
	//var menu = new Menu(baseMenu.subMenus.length);
	var menu = new Menu(index);
	baseMenu.subMenus[baseMenu.subMenus.length] = menu;
	for (var x = 0; x < sectionMenu.length; )
	{
		var caption = sectionMenu [x++];
		var onClick = sectionMenu [x++];
		var hasChildren = sectionMenu [x++];
		menu.hasChildren = hasChildren;

		// for some reason, empty menu items are always passed at the top level.
		// This checks that menu items actually exist.
		if (caption != "" || onClick != "") {
			// If hasChildren is true, need to find the child and add it as a child to this node.
			var newSub = null;
			if (menu.hasChildren) {
				newSub = createMenus(itemName + "_" + itemCount, menu, itemCount )
				newSub.parent = menu;
				menu.subMenus[menu.subMenus.length] = newSub;
			}

			// Here, note that the child item is created *before* the parent item; this is
			// necessary beacuse the parent needs to know the ID of the child.

			addMenuItem (menu, caption, "", onClick, newSub, (x >= sectionMenu.length));
			itemCount +=1;
		}
		// MOD NEEDED
		// I think the positioning of menu items should also be set here, and shouldn't
		// be recalculated, except in the event of the window being resized.
	}
	return menu;
}

function Menu (index)
{
	this.index = index;
	this.height = (parseInt(borWid) * 2);
	this.srcElement = null;
	this.itemCount = 0;
	this.subMenus = new Array (0);
	this.position = "";
	this.hasChildren = 0;
	this.parent = null;
	this.ID = IDs++;
	this.active = false;
	this.popup = getPopup (this.ID);
	this.isChild = true;
	this.tableIdMarker = "Cas_Table_Id"

	this.startHTML = getDivHTML (this.tableIdMarker + this.ID);
	this.innerHTML = "";
	this.endHTML = '</table>';

/* Deprecated.
	this.offsetLeft = -1;
	this.offsetRight = -1;
	this.offsetTop = -1;
	this.offsetBottom = -1;

	this.captionLeft = -1;
	this.captionRight = -1;
	this.captionTop = -1;
	this.captionBottom = -1;
*/
	this.popupLeft = -1;
	this.popupRight = -1;
	this.popupTop = -1;
	this.popupBottom = -1;
}

function getPopup (idString)
{
	if (doc)
	{
		var popup = doc.createElement ("DIV");
		popup.style.display = "none";
		popup.style.position = "absolute";
		//popup.style.left = 0;
		//popup.style.top = 0;
		//popup.style.right = 0;
		//popup.style.bottom = 0;
		popup.id = idString;

		if (doc.body)
			doc.body.appendChild (popup);

		return popup;
	}
	return null;
}

// The timeout is left strictly as a backup option.
function timeOut() {
	//alert("timeout triggered");
	// If the timeout triggers, we want to hide all open menus.
	markActive(activeMenu, false, "none");
	activeMenu = null;
	closeTimeout = null;
}

var closeTimeout = null;
function mouseExitTrigger(theEvent) {
	//alert("mouse exited.");
	if (closeTimeout == null) {
		closeTimeout = window.setTimeout(timeOut, secondsVisible * 1000);
	}
}

// This will clear the timeout, if created. Its other purpose is to mark the
// visually active menu.
// If the menu that the mouseover events are being triggered by changes, that means
// we want to change the diplayed menus to only show the current one.
function mouseEnterTrigger(theEvent) {
	if (closeTimeout != null) {
		window.clearTimeout(closeTimeout);
		closeTimeout = null;
	}
	
	if (theEvent == null) {
		return;
	}
	// get the table that was the source of this event. Find it's ID and get the
	// associated menu.
	var xParent = getSrcElement(theEvent);
	var menuId;
	while (xParent.tagName.toLowerCase() != "table") {
		xParent = xParent.parentNode;
	}
	
	menuId = xParent.id.substring(rootMenu.tableIdMarker.length);
	var menu = getMenuById(menuId, rootMenu);
	if (mousePointerMenu != menu) {
		// focus has changed.
		setActiveMenu(menu);
		mousePointerMenu = menu;
	}
}

function getDivHTML (idString)
{
// Experiment - trying "onmouseout" event for these divs.
	var	html  = '<table border="0" cellspacing="0" cellpadding="' + itemPad + '" width=' + menuWidth;
		html += '   style="BORDER: ' + borCol + ' ' + borWid + 'px ' + borSty + '; "';
		html += ' onmouseout="' + framesPrefix + 'mouseExitTrigger(event);" '
		html += ' onmouseover="' + framesPrefix + 'mouseEnterTrigger(event);" '
		html += ' id="' + idString + '" ';
		html += '	bgcolor=' + backCol + ' unselectable="on">';
	return html;
}

function addMenuItem (menu, newCaption, newImage, newOnClick, newChild, isLast)
{
	var mouseOver = ' onmouseover="' + framesPrefix + 'mouseEnterTrigger(event);" ';

	var html  = ' <tr onClick ="' + newOnClick + '" unselectable="on" ';
	if (newChild != null) {
		//html += ' onMouseOver = "' + framesPrefix + 'showCascadeMenu (' + newChild.ID + ', event);" ';
		html += ' onMouseOver = "' + framesPrefix + 'showCascadeMenu (' + newChild.ID + ', event); ' + framesPrefix + 'mouseEnterTrigger(event)" ';
	}
	html += ' >';

	// get rid of any alphabetic characters from font size declaration. only a number should be
	// passed in the input, but we're also getting "px" at the end of it.
	var i;
	for (i = fntSiz.length - 1; i >= 0 ;i--)
	{
		if ((fntSiz.charAt(i) < '0')||(fntSiz.charAt(i) > '9')) {
			fntSiz = fntSiz.substring(0, fntSiz.length - 1);
		}
	}
	
	html += '  <td style="cursor:default; color:' + fntCol + '; font: ' + fntSiz + 'pt ' + fntFam + '; ';
	html += '       FONT-WEIGHT:' + (fntBold ? "bold" : "normal") + '; FONT-STYLE:' + (fntItal ? "italic" : "normal") + '; '; 
	html += '       BACKGROUND-COLOR: ' + backCol + '; ';

	if (!isLast) {
		html += 'BORDER-BOTTOM: ' + separatorCol + ' ' + separator + 'px solid; ';
	}
	html += '" ';
	html += '     onMouseOver="this.style.backgroundColor=' + "'" + overCol + "'; ";
	html += '                  this.style.color=' + "'" + overFnt + "'; " + framesPrefix + 'mouseEnterTrigger(event); " ';

	var mouseOut = ""; // = framesPrefix + 'pageMouseMove (event); ';
	mouseOut += 'this.style.backgroundColor=' + "'" + backCol + "'; ";
	mouseOut += 'this.style.color=' + "'" + fntCol + "';";

	html += '      onMouseOut="' + mouseOut + '">';
	html += '    <NOWRAP><SPAN style="WIDTH:' + (menuWidth - 12 - (borWid * 2) - ((newChild != null) ? imgSiz : 0)) + 'px" ';
	html += mouseOver;
	html += '>' + newCaption;
	if (newChild != null) {
		html += '</SPAN><SPAN align=right><IMG src="' + imgSrc + '" height=' + imgSiz + ' width=' + imgSiz + ' ';
html += mouseOver;
		html += ' >';
	}
	html += '    </SPAN></NOWRAP></td></tr>';
//alert(framesPrefix);

	menu.innerHTML += html;
	menu.height += parseInt(fntSiz) * 2 + (isLast ? 0 : parseInt(separator)) + (parseInt (itemPad));
	menu.itemCount++;

	if (isLast) {
		menu.popup.innerHTML = menu.startHTML + menu.innerHTML + menu.endHTML;
	}
}

/* deprecated.
function addSubMenuItem (menu, index, newCaption, newImage, newOnClick, newHasChildren, isLast)
{
	var subMenu = menu.subMenus [index];
	if (!subMenu) {
		subMenu = menu.subMenus [index] = new Menu (index);
	}

	var html  = ' <tr onClick ="' + newOnClick + '" unselectable="on">';
		html += '  <td style="cursor:default; color:' + fntCol + '; font: ' + fntSiz + 'pt ' + fntFam + '; ';
		html += '       FONT-WEIGHT:' + (fntBold ? "bold" : "normal") + '; FONT-STYLE:' + (fntItal ? "italic" : "normal") + '; '; 
		html += '       BACKGROUND-COLOR: ' + backCol + '; ';
		if (!isLast)
			html += 'BORDER-BOTTOM: ' + separatorCol + ' ' + separator + 'px solid; ';
		html += '" ';
		html += '     onMouseOver="this.style.backgroundColor=' + "'" + overCol + "'; ";
		html += '                  this.style.color=' + "'" + overFnt + "'; " + '; ' + framesPrefix + 'pageMouseMove (event); " ';
		html += '      onMouseOut="this.style.backgroundColor=' + "'" + backCol + "'; ";
		html += '                  this.style.color=' + "'" + fntCol + "';" + '; ' + framesPrefix + 'pageMouseMove (event); ">';
		html += '    <NOWRAP><SPAN style="WIDTH:' + (menuWidth - 12 - (borWid * 2) - (newHasChildren ? imgSiz : 0)) + '">' + newCaption;

		if (newHasChildren)
			html += '</SPAN><SPAN align=right><IMG src="' + imgSrc + '" height=' + imgSiz + ' width=' + imgSiz + '>';
		html += '    </SPAN></NOWRAP></td></tr>';

	subMenu.innerHTML += html;
	subMenu.height += parseInt(fntSiz) * 2 + (isLast ? 0 : parseInt(separator)) + (parseInt (itemPad));
	subMenu.itemCount++;

	if (isLast)
		subMenu.popup.innerHTML = subMenu.startHTML + subMenu.innerHTML + subMenu.endHTML;
}
*/

// This function is called from Steve's source HTML,
//and shouldn't be called from anywhere else.
function popUp (caption, theEvent)
{
	var index = parseInt (caption);
	// This seems like a fairly inefficient way of getting the job done.
	// Should fix this up as a final thing to do.
	for (i = 0; i < caption.length && isNaN(index);)
	{
		caption = caption.substring (1);
		index = parseInt (caption);
	}

	// Check that rootMenu exists. It should be impossible for it to be null,
	// but it happened in a couple of tests... not sure why.
	if (rootMenu == null) {
		rebuildMenus();
	}

	// Right now, all we need to do for this is display the popup in question.
	if (rootMenu.subMenus[index - 1]) {
		showCascadeMenu(rootMenu.subMenus[index - 1].ID, theEvent);
	}
	mouseEnterTrigger(null);
}

// as arguments, this function receives the ID of a menu and an event.
function showCascadeMenu (menuId, theEvent) {
	var menu = getMenuById(menuId);

	if (!menu.popup) {
		// body frame has changed. Rebuild all the menus.
		rebuildMenus();
		menu = getMenuById(menuId);
	}

	setActiveMenu(menu);

	if (menu.popupLeft == -1) {
		// higher level menus already have their positioning data created.
		setPosition(menu, theEvent);
	}

	if (menu == null) {
		// Don't muck about if an error occured.
		return;
	}
	menu.popup.style.display = "block";
}

function rebuildMenus() {
	// reset all the variables to default values
	activeMenu = null;
	if (closeTimeout != null) {
		window.clearTimeout(closeTimeout);
	}
	setup();

}

/* deprecated.
function hideSubMenu ()
{
	if (activeSubMenu && activeSubMenu.popup && activeSubMenu.popup.style.display == "block")
		activeSubMenu.popup.style.display = "none";	
		
	activeSubMenu = null;
}
*/


// display the popup.
function setPosition (menu, theEvent) {
	var srcElement = getSrcElement(theEvent);
	var position;
	// Need to get the popup sized and located correctly.
	// This is the annoying bit of the whole process.
	//get positioning
	//This function is older code; through other changes it may now be unreliable.
	position = getOrientation(menu.isChild, srcElement);

	if (position == "below")
	{
		xPos = totalOffsetLeft(srcElement); 
		if (isFrames && !(menu.isChild)) {
			yPos = 0;
		}
		else {
			yPos = srcElement.offsetHeight + totalOffsetTop (srcElement);
		}
	}
	else {
		var xParent = srcElement;
		while (xParent && xParent.tagName.toUpperCase() != "TABLE") {
			xParent = xParent.offsetParent;
		}

		// Need to parseInt here; because otherwise, the two numbers get concatenated as strings.
		xPos = (isFrames && !(menu.isChild)) ? 0 : (parseInt(xParent.width, 10) + totalOffsetLeft(xParent));
		if (position == "left") {
			xPos = doc.body.clientWidth - menuWidth;
		}

		yPos = totalOffsetTop (srcElement);
		var i=0;
	}

	if (isFrames)
	{
		var parentFrame = null;

		// These ways of accessing variables aren't standard, and will only work in IE.
		// therefore framed sites will only ever work in IE.
		if (srcElement.document) {
			if (srcElement.document.parentWindow) {
				parentFrame = srcElement.document.parentWindow.frameElement;
			}
		}	

		//if (parentFrame) // && (parentFrame.name == "NAV" || parentFrame.name == "SUBNAV"))
		{
			if (bodyFrame.window.frameElement)
			{
				if (position == "below")
					xPos -= totalOffsetLeft (bodyFrame.window.frameElement);
				else
					yPos -= totalOffsetTop (bodyFrame.window.frameElement);
			}
			if (parentFrame)
			{
				if (position == "below")
					xPos += totalOffsetLeft (parentFrame);
				else
					yPos += totalOffsetTop (parentFrame);			
			}
		}

		if (xPos < 0)
			xPos = 0;
		if (yPos < 0)
			yPos = 0;

		if (!(menu.isChild))
		{
			xPos += doc.body.scrollLeft;
			yPos += doc.body.scrollTop;
		}

	}

	setAbsolutePosition(menu, menu.isChild, position, xPos, yPos, theEvent);
}

function getOrientation (isChildMenu, srcElement)
{
	var position = "";
	if (isChildMenu)
		position = "right";
	else
	{
		if (isFrames)
		{
			switch (navFrLoc)
			{
				case "customtop":
					position = "below";
					break;
				case "customleft":
					position = "right";
					break;
				case "customright":
					position = "left";
					break;

				// New options - PW 23/07/2003 v7.0.14
				case "left":
					position = "right";
					break;
				case "right":
					position = "left";
					break;
				case "top":
					position = "below";
					break;
					
				default:
					position = "below";
			}
		}
		else
		{
			var parentRow = srcElement;

			while (parentRow && parentRow.tagName && parentRow.tagName.toUpperCase() != "TR") {
				parentRow = parentRow.parentNode;
			}

			if (parentRow)
			{
				// If the row has more than one cell, this is a horizontal nav.
				if (parentRow.cells && parentRow.cells.length > 1)
					position = "below";
				else
				{
					var parentTable = parentRow;
					while (parentTable && parentTable.tagName.toUpperCase () != "TABLE")
						parentTable = parentTable.parentElement;
						
					// If the table has more than one row, this is a vertical nav.
					if (parentTable && parentTable.rows && parentTable.rows.length > 1)
						position = "right";
					else
					{
						// There is only one element in the nav, so calculate the distance from the left and top of 
						// the window and use that to determine if this is a horizontal or vertical nav.
							
						var xOffset = totalOffsetLeft (srcElement);
						var yOffset = totalOffsetTop (srcElement);
						position = (xOffset > yOffset) ? "below" : "right";
					}
				}
			}
		}
	}
	return position;
}

function setAbsolutePosition (menu, isChildMenu, position, xPos, yPos, theEvent)
{
	if (!isChildMenu)
		if (activeMenu && activeMenu.popup && activeMenu.popup.style.display == "block")
			activeMenu.popup.style.display = "none";

	if (activeSubMenu && activeSubMenu.popup && activeSubMenu.popup.style.display == "block")
		activeSubMenu.popup.style.display = "none";	
	activeSubMenu = null;

	var overlap;
	if (perCentOver || perCentOver == 0)
		overlap = perCentOver / 100 * menuWidth;
	else
		overlap = childOverlap;

	var posLeft = xPos - (isChildMenu ? overlap : 0);
	var posRight = xPos + menuWidth - (isChildMenu ? overlap : 0);
	var posTop = yPos + (isChildMenu ? childOffset - borWid : 0);
	var posBottom = yPos + menu.height - (isChildMenu ? borWid : 0);

	if (position != "left" && (doc.body.clientWidth + doc.body.scrollLeft) < posRight)
	{
		// The menu doesn't fit horizontally on the document.
		
		if (isChildMenu)
		{
			// Try putting the child menu on the left-hand side of the parent menu instead.
			if (posLeft >= (menuWidth * 2))
			{
				// Ignore child overlap when on the "wrong" side.
				posLeft -= ((menuWidth * 2) - (overlap)); 
				posRight = posLeft + menuWidth;
				position = "left";
			}
		}
		else {
			if ((doc.body.clientWidth + doc.body.scrollLeft) > menuWidth)
			{
				posRight = (doc.body.clientWidth + doc.body.scrollLeft);
				posLeft = posRight - menuWidth;
				position = "absright";
			}				
		}
	}
	
	// If the body frame has navigated to a different page, the reference to the popup object will still
	// exist in the nav frame but the popup itself would have been destroyed. Hence, re-create it.
	
	if (menu.popup == null || menu.popup.parentNode == null)
	{
		var newPopup = getPopup ();
		newPopup.innerHTML = menu.startHTML + menu.innerHTML + menu.endHTML;
		
		menu.popup = newPopup;
	}

// Firefox requires the additon of "px" to these numbers.
	menu.popup.style.left = posLeft + "px";
	menu.popup.style.right = posRight + "px";
	menu.popup.style.top = posTop + "px";
	menu.popup.style.bottom = posBottom + "px";
	menu.popup.style.display = "block";

	menu.popupLeft = posLeft;
	menu.popupRight = posRight
	menu.popupTop = posTop;
	menu.popupBottom = posBottom;

	//setActiveMenu (menu, isChildMenu, position);

	//window.clearTimeout ();
	//cancelHide = true;
	//pageMouseMove (theEvent);
}

/* deprecated.
function pageMouseMove (theEvent)
{
	if (!theEvent) {
		theEvent = getEvent();
	}
	// If there is still no event, we can't do anything.
	if (!theEvent) {
		return;
	}

	// These return values are tristates. return 0 if false, 1 if true, and 2 if error.
	var outsideSubMenu = isOutsideMenuAndCaption (activeSubMenu, 1, theEvent);
	var outsideMenu = isOutsideMenuAndCaption (activeMenu, 0, theEvent);

	if ((outsideSubMenu == 2)||(outsideMenu == 2)) {
		// Error.
		return;
	}

	if (outsideSubMenu && activeSubMenu != null && activeSubMenu.popup != null) 
		hideSubMenu ();
	if (outsideSubMenu && outsideMenu)
	{
		window.clearTimeout ();
		window.setTimeout ("popDown (null)", secondsVisible * 1000);
		cancelHide = false;
	}
	else
	{
		window.clearTimeout ();
		cancelHide = true;
	}
}
*/
/* deprecated.
function isOutsideMenuAndCaption (menu, defaultValue, theEvent)
{
	if (menu && menu.popup)
	{
		try {
			menu.popup.offsetWidth;
		}
		catch (excep) {
			// This is intended to catch a "permission denied" error.
			// This occurs on framed sites when one frame has changed location.
			setup();
			// 2 indicates error
			return 2;
		}

		// get mouse pointer position
		var eventX = eventOffsetX (theEvent);
		var eventY = eventOffsetY (theEvent);

		// The popup is a "div". derive the top and left values from this object.
		// However, firefox always returns an incorrect value for height of the div.
		// Therefore height and width are derived from the table inside the DIV.

		var el = menu.popup.getElementsByTagName("table");
		var tablePopup = el[0];
		// Derive from table in popup:


//		if (!tablePopup) {
//			alert(menu.innerHTML);
//			alert(menu.popup.outerHTML);
//			alert(el.length);
//			alert(tablePopup);
//			alert(tablePopup.outerHTML);
//		}
		var popWidth = tablePopup.offsetWidth;
		var popHeight = tablePopup.offsetHeight;
		// Derive from DIV that contains the table:
		var popTop = menu.offsetTop;
		var popLeft = menu.offsetLeft

		var outsideX = (eventX < popLeft - margin 
					 || eventX > popLeft + popWidth + margin);
		var outsideY = (eventY < popTop - margin
					 || eventY > popTop + popHeight + margin);

		if (outsideX || outsideY)
		{
			if (menu.captionElement)
			{
				// Are we outside the caption?
				
				outsideX = (eventX < menu.captionLeft - margin 
						 || eventX > menu.captionRight + margin);
				outsideY = (eventY < menu.captionTop - margin
						 || eventY > menu.captionBottom + margin);			
			}

			if (outsideX || outsideY)
			{
				// Are we outside the void between the caption and the menu?
				
				switch (menu.position)
				{
					case "left":
						outsideX = (eventX < menu.offsetLeft - margin 
								 || eventX > menu.captionRight + margin);
						outsideY = (eventY < menu.captionTop - margin
								 || eventY > menu.captionBottom + margin);	
						break;

					case "right":
						outsideX = (eventX < menu.captionRight - margin 
								 || eventX > menu.offsetLeft + margin);
						outsideY = (eventY < menu.captionTop - margin
								 || eventY > menu.captionBottom + margin);	
						break;
						
					case "below":
						outsideX = (eventX < menu.captionLeft - margin 
								 || eventX > menu.captionRight + margin);
						outsideY = (eventY < menu.captionBottom - margin
								 || eventY > menu.offsetTop + margin);
						break;
				}
				
				// If one of these is still true, then the pointer is definitely not over this menu.
				if (outsideX || outsideY)
					return 1;
			}
		}
		return 0;
	}
	return defaultValue;
}
*/

function popDown (triggeredByCaption, theEvent)
{
	mouseExitTrigger(null);

/* deprecated. Function call remains for comaptibility
	with older pages, but no longer does anything.
	if (!cancelHide)
	{
		if (!triggeredByCaption)
		{
			if (activeMenu && activeMenu.popup) {
				activeMenu.popup.style.display = "none";
			}
			activeMenu = null;
			
			if (activeSubMenu && activeSubMenu.popup) {
				activeSubMenu.popup.style.display = "none";
			}
			activeSubMenu = null;
		}
		else {
			pageMouseMove (theEvent);
		}
	}
*/
}

function setActiveMenu (menu) {
	if (menu == activeMenu) {
		return;
	}
	// mark previously active menu heirarchy as inactive
	markActive(activeMenu, false, "none");
	activeMenu = menu;
	// recurse backwards and mark menu's parents as active
	markActive(menu, true, "block");

/* deprecated.
	I've not a clue what all this stuff below was originally intended to do;
	I can't seem to find a use for it now.

	menu.offsetLeft = totalOffsetLeft (menu.popup);
	menu.offsetRight = menu.offsetLeft + menuWidth;
	menu.offsetTop = totalOffsetTop (menu.popup);
	menu.offsetBottom = menu.offsetTop + menu.height;
	menu.position = position;

//menu.offsetWidth = menu.offsetRight - menu.offsetLeft;
//menu.offsetHeight =	menu.offsetBottom = menu.offsetTop;

	menu.captionLeft = totalOffsetLeft (menu.captionElement);
	menu.captionRight = menu.captionLeft + menu.captionElement.offsetWidth;
	menu.captionTop = totalOffsetTop (menu.captionElement);
	menu.captionBottom = menu.captionTop + menu.captionElement.offsetHeight;

	if (isSub)
		activeSubMenu = menu;
	else
		activeMenu = menu;
*/
}

function markActive(menu, val, disp) {
	if (menu == null) {
		return;
	}
	menu.active = val;
	menu.popup.style.display = disp;
	if (menu.parent != null) {
		markActive(menu.parent, val, disp);
	}
}

function totalOffsetLeft (object)
{
	// Calculate this object's offset from the left border by recursively adding it.
	if (object)
	{	
		var offset = object.offsetLeft;
		if (object.offsetParent)
			offset += totalOffsetLeft (object.offsetParent);
		else
			offset += totalOffsetLeft (object.parentElement);
		return offset;
	}
	return 0;
}

function totalOffsetTop (object)
{
	// Calculate this object's offset from the top border by recursively adding it.
	if (object)
	{
		var offset = object.offsetTop;
		if (object.offsetParent)
			offset += totalOffsetTop (object.offsetParent);
		else
			offset += totalOffsetTop (object.parentElement);
		return offset;
	}
	return 0;
}

/* deprecated.
function eventOffsetX (theEvent)
{
	var parent = getSrcElement(theEvent);

	while (parent && parent.tagName.toUpperCase() != "BODY")
		parent = parent.parentElement;
	
	return theEvent.clientX + (parent ? parent.scrollLeft : 0);
}

function eventOffsetY (theEvent)
{
	var parent = getSrcElement(theEvent);

	while (parent && parent.tagName.toUpperCase() != "BODY")
		parent = parent.parentElement;
	
	return theEvent.clientY + (parent ? parent.scrollTop : 0);
}
*/

function getEvent ()
{
	if (window.event) {
		return window.event;
	}
	if (parent.frames.BODY && parent.frames.BODY.event) {
		return parent.frames.BODY.event;
	}
	if (parent.frames.NAV && parent.frames.NAV.event) {
		return parent.frames.NAV.event;
	}
	if (parent.frames.SUBNAV && parent.frames.SUBNAV.event) {
		return parent.frames.SUBNAV.event;
	}
	return null;
}

function getSrcElement(theEvent) {
	var fallbackEvent;
	if (theEvent == null) {
		// wasn't givent an event argument. Assuming this is IE6, try to grab one.
		// Almost certainly won't work on other browsers.
		fallbackEvent = getEvent();
		if (fallbackEvent == null) {
			return null;
		}
		else {
			return getSrcElement(fallbackEvent);
		}
	}
	if (theEvent.srcElement) {
		return(theEvent.srcElement);
	}
	else if (theEvent.target) {
		return(theEvent.target);
	}
	else {
		return (null);
	}
}

// depth first search on given node (or root node) to find node with
// given ID.
// MOD NEEDED
// should probably be using hashtable for this, would be simpler and faster
function getMenuById(id, searchNode) {
	var i;
	var res;
	if (searchNode == null) {
		searchNode = rootMenu;
	}
	// search the subnodes of this node
	for (i=0; i < searchNode.subMenus.length; i++) {
		if (searchNode.subMenus[i].ID == id) {
			return(searchNode.subMenus[i]);
		}
		res = getMenuById(id, searchNode.subMenus[i]);
		if (res != null) {
			return(res);
		}
	}
	return(null);
}
