//menu style constants
var NONE = -1;
var INLN = 0;
var VERT = 1;
var HORI = 2;
var TABD = 3;
var STRT = 4;
var GRID = 5;

//arContentPath is defined before this JS is called.
//topMenuIndex is defined in menu.js

//Other constants
var BASE_LEVEL = 1;								//Starting level of menu
var BASE_MENU_ID = "mim";						//Prefix for all menu related ids - used as a test.
var BASE_MENU_ID_LEN = BASE_MENU_ID.length;		//Length of BASE_MENU_ID
var MENU_SEP_ID = "xmimsep";					//ID used my seperator

//Global variables
//Other globals can be found in the menu.js file:
//OPEN_MENU_DELAY, CLOSE_MENU_DELAY, DEBUG, INLINE_MENU_INDENT, DEPTH_TO_FIX_OPEN, TOPMENU_MIN_WIDTH, SIDEMENU_MIN_WIDTH, TOPMENU_WIDTH, TOPMENU_STYLE


var IE = false;					//Is the browser IE > 4
var NS = false;					//Is the browser Netscape > 4
var Mac = false;				//Is the browser on a Mac.
var bNoTopMenu = false;			//Stop dynamic topmenu.
var bSliding = false;			//New menus slide into position?

var bCurrentOver = null;		//Are we currently over a menu item
var bCurrentOut = null;			//Was the last mouseout from a menu item
var currentLevel = BASE_LEVEL;	//Level of the current menu item

var activeMenu = null;			//Currently active menu
var activeItem = null;			//Currently active menu item
var oldItem = null;				//Last active menu item

var activeTimer = null;			//ID of the current active timer (null if no timer running)
var sliderTimer = null;			//ID of the timer running the menu sliding
var openTimer = null;			//ID of the timer running the menu opening
var scrollTimer = null;			//ID of the timer running the screen scrolling down
var openNode = null;			//Holds menu that is to be shown
var openTarget = null;			//Holds menuitem to put menu near
var activeSlider = null;		//Menu to slide out

var intMouseX, intMouseY;		//Position of the pointer in the browser window.			

var intMenuLevelOffset = 0;		//Offset so that level 1 of sidemenu menudef is the first visible level

var Menus = new Array();		//Array of menu items currently in use.
var arrMenuSizes = new Array();	//Temp array (used as a dictionary) used to hold the id and size of menus
								//This fixes a problem with IE5.0 - NN6 still broken!
var arrFixedMenuSizes = new Array(); //Temp array to hold the menus that are being forced open. Trying to solve 
									 //menu size problems
									 
//NS6 specific size adjustment variables - only used in menu construction									 
var currentMenu = null;			//Menu currently under construction
var currentMaxItem = null;		//ID of current largest item
var intMaxSize = 0;				//Maximum size of menu
 
							
var intWinWidth, intWinHeight;	//Width and height of browser window.							

//Works out which browser the client is using
var userAgent = navigator.userAgent.toLowerCase();
var userAgentVer = parseInt(navigator.appVersion);
if ( userAgent.indexOf("msie") > -1 && userAgentVer > 3 ) {
    IE = true;
} else if ( userAgent.indexOf("mozilla") > -1 && userAgentVer > 4 ) {
    NS = true;
} else {
	bNoTopMenu = true;
}

if ( userAgent.indexOf("mac") > -1 ) {
	Mac = true;
	if (!bNoTopMenu) {
		if (IE) {
			// we know that mac IE 5.0 on classic works
			// so assume versions <5 on mac don't
			// NB: IE 4 & 5 give an appVersion of 4
			var iIEPos = userAgent.indexOf("msie");
			var fIEVer = parseFloat(userAgent.substring(iIEPos+5, iIEPos+5+4));
			if (fIEVer < 5.0) 
				bNoTopMenu = true;
		} else if (userAgent.indexOf("opera") > -1 ||userAgent.indexOf("omniweb") > -1) {
			// opera and omniweb on mac don't work
			bNoTopMenu = true;
		}	
	}
}
	
//======================================== ONLOAD + ONRESIZE =======================================
window.onload = setup;
window.onresize = getSize;
//==================================================================================================


//Setups up the event handlers
function setup() {
	getSize();
	adjustSubmenuWidths();
	openSelectedItem();
	document.onmouseout = handleOut;
	document.onmouseover = handleOver;
	document.onmousemove = handleMove;
}

//strTemp = "";

//Gets the width and height of the browser.
//NB. Needs to be attached to resize event.
function getSize() {
	intWinWidth = ( NS ) ? window.innerWidth : document.body.offsetWidth-20
	intWinHeight = ( NS ) ? window.innerHeight : document.body.offsetHeight-4
	//window.alert("width: " + intWinWidth + ", height: " + intWinHeight);
}

//This function is called when the mouseover event is fired.
//It checks whether the target of the event is part of the menu
//handleOver function :
//	updates which is the active menu item
//	closes any unnecessary menus
//  highlights the active item
//	opens any menus associated with the active item
//NB: This function is called for EVERY mouseover event on the entire page
function handleOver(evt) {

    var target = getTargetElement(evt);
    var overTable = getParent(target);
    bCurrentOver = isMenuTable(overTable);

	if (!bCurrentOver && bCurrentOut) startTimer(); 
	if (bCurrentOver && !bCurrentOut) stopTimer(activeTimer);
	
    if ( isNewTable(overTable) ) {
		//In a new table.		
		
		//Stops any running open menu timers
		if ( !isNaN(openTimer) ) {
			window.clearTimeout(openTimer);
			openTimer = null;
			openTarget = null;
			openNode = null;						
		}
		
		//Unhighlight last table
		//remove 'h' from class of oldItem
		if ( activeItem && (activeItem.className.lastIndexOf("h") > 0 || activeItem.vbnHighlighted )) {
			UnhighlightTable(activeItem);
		} 
		
		//update activeItem
		updateActiveItem(overTable);
		
		//Handle changing between menu levels etc.
		dealWithMenus(overTable);
						
		//Change item to highlighted
		//add 'h' to class to get highlighted class
		//base class ends in n=normal or s=selected
		if (activeItem) {
			if (self.name!='bfora_purchase_title'&&self.name!='bfora_purchase_list')
				scrollScreen();			
			HighlightTable(activeItem);
		}

		//Open any associated menus
		if ( activeItem ) ToggleOn(activeItem, activeItem.id + "c", 0, 0);
    }
}

//Handles the mouseout event.
//Checks whether the target of the event is part of the menu
//handleOut function :
//	unhighlights the active item
//NB: This function is called for EVERY mouseout event on the entire page
function handleOut(evt) {
    var target = getTargetElement(evt);
    var outTable = getParent(target);
    bCurrentOut = isMenuTable(outTable);
}

//Handles mouse move events.
function handleMove(evt) {
    evt = (evt) ? evt : ((window.event) ? window.event : null);

	if (evt) {	
		if (IE) {
			intMouseX = evt.clientX;
			intMouseY = evt.clientY;
		} else {
			intMouseX = evt.pageX - window.pageXOffset;
			intMouseY = evt.pageY - window.pageYOffset;
		}
	}
}

//dealWithMenus function :
//	Closes any unnecessay open menus
//	sets the activeMenu object
//	changes the currentLevel variable
function dealWithMenus(thisNode) {

	var newLevel = getLevelFromID(thisNode);
	var oldLevel = (oldItem) ? getLevelFromID(oldItem) : currentLevel;
	
	if (newLevel > oldLevel) {
		Menus[oldLevel] = activeMenu;
		activeMenu = null;
		currentLevel = newLevel;
	} else if (newLevel == oldLevel) {
		ToggleOff();
	} else if (newLevel < oldLevel) {
		for (var i = oldLevel; i >= newLevel; i--) {
			
			if ( !oldItem || (oldItem.parentNode && oldItem.parentNode.id != thisNode.id + "c") ) 
			{
				ToggleOff();				//closes current active menu
				activeMenu = Menus[i-1];	//get active menu from next level down
				Menus[i] = null;			//clear level above from array
				Menus.length--;				//change array size
			}
		}
		
		activeMenu = null;
		currentLevel = newLevel;		//change level
	}
}

//openNormal function :
//	opens any menus associated with a menuitem (changes their visibility)
//	works out if the new menu needs to be below or to the left of the item
//	if sliding is enabled. starts the sliding
function openNormal(menu, target, style) {
	//Change position of menu
	changeMenuPosition(menu, target, style);
				 
	//Doing sliding
	if ( bSliding ) {
		activeSlider = menu;
		if ( HORI == style || GRID == style) slideY(20, 0, 20);
		else slideX(20, 0, 20);
	}
			
	//make visible
	if ( "hidden" == menu.style.visibility ) {
		menu.style.visibility = "visible";
	}
}

//changeMenuPosition :
//  works out where the menu needs to be in relation to the menuitem
//  changes position BUT does not affect visibility.
function changeMenuPosition(menu, target, style) {
	var left = getPositionLeft(target);
	var top = getPositionTop(target);
	
	var menuWidth = menu.offsetWidth;
	var menuHeight = menu.offsetHeight;
	var targetWidth = target.offsetWidth;
	var targetHeight = target.offsetHeight;
	
	var intTargetLevel = getLevelFromID(target);
	
	if ( HORI == style || GRID == style ) {
		menu.style.left = (( left + menuWidth > intWinWidth && intTargetLevel > 1 ) ? (left-menuWidth) : left) + 'px';
		menu.style.top  = (top + targetHeight) + 'px';	
	} else {
		menu.style.left = (( left + targetWidth + menuWidth > intWinWidth ) ? (left-menuWidth) : (left+targetWidth)) + 'px';
		menu.style.top  = top + 'px';
	}
	
}

//ToggleOn function :
//	Works out which style of menu you are using and calls the relevant opening function
//NB: at present only floating menus ('normal') and inline menus are supported.
function ToggleOn(target, strContainerId, bLeft, bTop) {

	if (target) {
		//if target is a text node then get its parent.
		if ( 3 == target.nodeType ) target = target.parentNode;
		
		var node = document.getElementById(strContainerId);
	
		if (node) {		
			var style = getStyleFromLevel( currentLevel, isNodeTopMenu( node ) );
						
			switch (style) {
				case TABD:
					//Tabbed style
					window.alert("Tabbed style not finished");
					var left = getPositionLeft(target);
					var top = getPositionTop(target);

					node.style.top  = top + target.offsetHeight + 'px';
					if ( 1 == currentLevel ) {
						var parentTABLE = target.parentNode.parentNode.parentNode.parentNode;
						if ( parentTABLE ) {
							var TABLEleft = getPositionLeft(parentTABLE);
							node.style.left = TABLEleft + 'px'; 
							//window.alert("parentTABLE.tagName: " + parentTABLE.tagName + ", TABLEleft: " + TABLEleft);
						}
					} else {
						node.style.left = left + 'px';
					}
					
					if ( "hidden" == node.style.visibility ) {
						node.style.visibility = "visible";
					}
					
					break;
				case INLN:
					//window.alert("Toggle on INLN. target: " + target.id + ", node: " + node.id );
					var intNextLevelStyle = getStyleFromLevel( currentLevel+1, isNodeTopMenu( node ) );
					if ( INLN != intNextLevelStyle ) {
						openNode = node;
						openTarget = target
						openTimer = window.setTimeout("openNormal(openNode, openTarget, " + intNextLevelStyle + ");", OPEN_MENU_DELAY);
					}
					break;
				case STRT:
					//window.alert("START on");
					//not used. Needs lots of clever stuff about knowing size of screen and last opening etc.
					break;
				case HORI:
					//window.alert("HORIZONTAL on");
				case VERT:
					//window.alert("VERTICAL on");
				case GRID:
					//window.alert("GRID on");
				default:
					//window.alert("style: " + style + ", DEFAULT on");
					openNode = node;
					openTarget = target
					openTimer = window.setTimeout("openNormal(openNode, openTarget, " + style + ");", OPEN_MENU_DELAY);
			}
												
			activeMenu = node;
			Menus[currentLevel] = node;
		}				
	}
}

//ToggleOff function :
//	Closes open menus
//	Unhighlights items
function ToggleOff() {

	if (activeMenu) {
		if (activeItem) {
			if ('h' == activeItem.className.charAt(activeItem.className.length-1) || activeItem.vbnHighlighted) UnhighlightTable(activeItem);
		}
		
		if ( "absolute" == activeMenu.style.position ) {
			activeMenu.style.visibility = "hidden";
			activeMenu.style.top = '0px';
			activeMenu.style.left = '0px';
		}
		
		activeMenu = null;
	}
}

//Calcs the vertical position of the item
function getPositionTop(node) {
	var y = 0;
	
	if (IE || NS) { 
		do {
			y += node.offsetTop;
			node = node.offsetParent;
		} while ((node != null) && (node.tagName != 'BODY'))
	}

	return y;
}

//Calcs the horizontal position of the item
function getPositionLeft(node) {
	var x = 0;

	if (IE || NS) {
		do {
			x += node.offsetLeft;
			node = node.offsetParent;
		} while ((node != null) && (node.tagName != 'BODY'))
	}

	return x;
}

//Event handler setup.
//Gets correct event object and target node
function getTargetElement(evt) {
    evt = (evt) ? evt : ((window.event) ? window.event : null);
    
    if (evt) {
		var elem;
		if (evt.target) {
		    elem = ( 3 == evt.target.nodeType ) ? evt.target.parentNode : evt.target;
		} else {
		    elem = evt.srcElement;
		}
		return elem;
	} else {
		return false;
	}
}

//Works out of the passed in node is from the top or side menu.
//	Top menu = true
//	otherwise = false
function isNodeTopMenu(node) {
	var bReturn = false;
	if ("t" == node.id.charAt(0) ) bReturn = true;
	return bReturn;
}

//doClick :
//If the menu style is inline then clicking opens/closes the submenus
//Will handle sliding if it is enabled
function doClick(target) {
	var id = target.id;
	
	if (target) {
		if ( 3 == target.nodeType ) target = target.parentNode;
		var node = document.getElementById(id + "c");
		if (node) {
			if ( bSliding ) {
				activeSlider = node;
				inlineSlideX(10, 5, -100, 20);
			} else {
				node.style.marginLeft = INLINE_MENU_INDENT;
			}
				
			//Make visible/invisible
			if ( "block" == node.style.display) {
				node.style.display = "none";
			} else {
				node.style.display = "block";
			}			
			
			adjustSubmenuWidths();	
		}
	}
}

//doHREF :
//If menu has an anchor tag inside it (it should do!) then it goes to the HREF.
function doHREF(target) {
	if (target) {
		if ( 3 == target.nodeType ) target = target.parentNode;
		var objATag = target.getElementsByTagName("A")[0];
		
		if (objATag && objATag.href && objATag.href.length > 0) {
			if (objATag && objATag.target && objATag.target.length > 0)
				window.parent.location.href = objATag.href;
			else
				location.href = objATag.href;
		}
	}
}

//Starts the timer which will close all the open menus
//Time can be varied with CLOSE_MENU_DELAY constant
function startTimer() {
	stopTimer(activeTimer);	
	activeTimer = window.setTimeout("closeAllMenus();", CLOSE_MENU_DELAY);
}

//Stops the specified timer
function stopTimer(timer) {
	if ( !isNaN(timer) ) {
		window.clearTimeout(timer);
		timer = null;
	}
}

//Works out if the mouse is near the bottom of the screen. Scrolls the screen down a little.
function scrollScreen() {
	scrollScreenY(25, 5, 100);
}

//Controls the the gradual scrolling of the screen as the approach the edge.
function scrollScreenY(intTotal, deltaY, time) {
	if ( intMouseY + intTotal >= intWinHeight ) {
		window.scrollBy(0, deltaY);
		scrollTimer = window.setTimeout("scrollScreenY(" + intTotal + ", " + deltaY + ", " + time + ");", time)
	} else {
		if ( intMouseY <= intTotal ) {
			window.scrollBy(0, -deltaY);
			scrollTimer = window.setTimeout("scrollScreenY(" + intTotal + ", " + deltaY + ", " + time + ");", time)
		}
	}
}

//Controls the gradual appearance floating menus
//Menu appears to slide in horizontally
function slideX(dx, x, time) {
	if ( activeSlider ) {
		if ( (x+dx) < activeSlider.offsetWidth ) {
			activeSlider.style.clip = "rect(0 " + (x+dx) + " " + activeSlider.offsetHeight + " 0)";
			sliderTimer = window.setTimeout("slideX(" + dx + ", " + (x+dx) + ", " + time + ");", time);
		} else {
			activeSlider.style.clip = "rect(auto auto auto auto)";
			activeSlider = null;
		}
	}
}

//Controls the gradual appearance floating menus
//Menu appears to slide down
function slideY(dy, y, time) {
	if ( activeSlider ) {
		if ( (y+dy) < activeSlider.offsetHeight ) {
			activeSlider.style.clip = "rect(0 " + activeSlider.offsetWidth + " " + (y+dy) + " 0)";
			sliderTimer = window.setTimeout("slideY(" + dy + ", " + (y+dy) + ", " + time + ");", time);
		} else {
			activeSlider.style.clip = "rect(auto auto auto auto)";
			activeSlider = null;
		}
	}
}

//Controls the sliding in of inline submenus.
//Menu slides in from the edge of the screen (assumes menu is on the left)
function inlineSlideX(indent, dx, x, time) {
	if ( activeSlider ) {
		if ( (x+dx) < indent ) {
			activeSlider.style.left = (x+dx) + 'px';
			sliderTimer = window.setTimeout("inlineSlideX(" + indent + ", " + dx + ", " + (x+dx) + ", " + time + ");", time);
		} else {
			activeSlider.style.left = indent + 'px';
			activeSlider = null;
		}
	}
}

function inlineSlideY(dy, y, time) {
	//Needs implementing
}

//Checks if the table is part of the menu
function isMenuTable(table) {
	var bReturn = false;
	if ( table && table.id && BASE_MENU_ID == table.id.substr(1, BASE_MENU_ID_LEN) ) bReturn = true;
	return bReturn;
}

//Changes the stylesheet of the table. Adds an 'h' to the end of the class
function HighlightTable(table) {
	//strTemp = "";
	var newName;
	if (table.className.charAt(table.className.length-1)=="h") return;
	newName = table.className + 'h';
	var childTDS = table.getElementsByTagName("TD");
	
	if (!(IE&&Mac)) { 
		
		table.className = newName;
		for(var i = 0; i < childTDS.length; i++) {
			childTDS[i].className += "h";
		}
	} else { 
		applyStyle(table, newName);
		table.vbnHighlighted = true;
		for(var i = 0; i < childTDS.length; i++) {
			applyStyle(childTDS[i], childTDS[i].className + 'h');
			if(typeof(childTDS[i].firstChild)=="object") { 
				applyStyle(childTDS[i].firstChild, childTDS[i].className + 'h');
			}
		}
	}
		
	var childIMGS = table.getElementsByTagName("IMG");
	for(var i = 0; i < childIMGS.length; i++) {
		var src = childIMGS[i].src;
		var imgIndex = ( src.indexOf(".gif") > 0 ) ? src.indexOf(".gif") : src.indexOf(".jpg") ;
		
		var newSrc = src.substr(0, imgIndex);
		newSrc += "h";
		newSrc += src.substr(imgIndex, src.length-1);
		
		childIMGS[i].src = newSrc;
	}
}

//Changes the stylesheet of the table. Removes the 'h' on the end of the class
function UnhighlightTable(table) {

	var childTDS = table.getElementsByTagName("TD");
		
	if (!(IE&&Mac)) {
		table.className = table.className.substr(0, table.className.length-1);
		for(var i = 0; i < childTDS.length; i++) {
			childTDS[i].className = childTDS[i].className.substr(0, childTDS[i].className.length-1);
		}
	} else { 
		applyStyle(table, table.className);
		table.vbnHighlighted = false;
		for(var i = 0; i < childTDS.length; i++) {
			applyStyle(childTDS[i], childTDS[i].className);
			if(typeof(childTDS[i].firstChild)=="object") { 
				applyStyle(childTDS[i].firstChild, childTDS[i].className);
			}
		}
	}

	
	
	var childIMGS = table.getElementsByTagName("IMG");
	for(var i = 0; i < childIMGS.length; i++) {
		var src = childIMGS[i].src;
		var imgIndex = ( src.indexOf(".gif") > 0 ) ? src.indexOf(".gif") : src.indexOf(".jpg") ;
		childIMGS[i].src = src.substr(0, imgIndex-1) + src.substr(imgIndex, src.length-1);
	}
}

//Closes all the open menus. Called from the timer.
function closeAllMenus() {

	for (var i = 1; i < Menus.length; i++) {
		if (Menus[i]) {
			activeMenu = Menus[i];
			ToggleOff();
		}
	}
	
	Menus.length = 1;
	oldItem = null;
	activeItem = null;
	currentLevel = BASE_LEVEL;
}

//Checks whether the node is the same as the active item
//Returns true if testNode != activeItem
function isNewTable(testNode) {
	var bReturn = false;
	if (testNode && activeItem && testNode.id != activeItem.id) bReturn = true;
	else if (testNode && !activeItem) bReturn = true; //first time case
	
	if (MENU_SEP_ID == testNode.id || "DIV" == testNode.tagName) bReturn = false;
	
	return bReturn;
}

//changes the activeItem to tempNode IF it has a menu id.
function updateActiveItem(tempNode) {
    if (tempNode && tempNode.id.indexOf(BASE_MENU_ID) > -1 ) {
		if (activeItem && tempNode.id != activeItem.id) {
			oldItem = activeItem;
			activeItem = tempNode;
		} else if (!activeItem && tempNode.id.indexOf(BASE_MENU_ID) > -1 ) {
			activeItem = tempNode;
		}
    } else {
		oldItem = activeItem;
		activeItem = null;
    }
}

//Finds the table or DIV that is holding the target of the fired event.
function getParent(node) {
	var tag = node.tagName;
	var tempNode = node;
	if ( "IMG" == tag || "A" == tag || "TD" == tag || "TR" == tag || "TBODY" == tag || "TABLE" == tag || "DIV" == tag ) {
		while (tempNode.tagName != "TABLE" && tempNode.tagName != "DIV") {
			if ( "BODY" == tempNode.tagName || "HTML" == tempNode.tagName ) {
				return false;
			}
			tempNode = tempNode.parentNode;
		}
		return tempNode;
	} else {
		return false;
	}
}

//gets level information from node id.
function getLevelFromID(node) {
	var iLevel = currentLevel;

	if (node.id) {
		var search = "lvl";
		var iMenuIndex = -1;
		var iMenuItem = -1;
	
		var tempId = node.id;
		var iTemp = tempId.indexOf(search);
		if (iTemp > -1) {
			var iLevel = parseInt ( tempId.slice(iTemp+search.length, tempId.length) );
		}
	}
	return iLevel;
}


//Menu generation functions.
//draws a menu item. 
//Uses network specific functions: getFrameForItem, getClassForItem
//Calls strDrawMenuCells for the actual drawing
function drawMenuItem(item, strPrefix, intItem, bIsTop, bHasMenu, bIsVisible, intMenuStyle) {
	var click = "", strTable = "";
	var strPayload = ( "" == item.image  ) ? item.name : item.image;
	var strHREF = item.href;
	var strID = ( bIsVisible && bHasMenu ) ? strPrefix + item.id + "-fixed" : strPrefix + item.id;
	var bHasMenu = ( item.menuIndex > -1 ) ? true : false;
	var bIsSelected = isItemSelected(item);
	var intLevel = item.level;
	
	var frameArray = getFrameForItem(intLevel, intItem, strPayload, bIsTop);
	var strClass = getClassForItem(intLevel, intItem, strPayload, bIsTop);
	strClass += ( bIsSelected ) ? "s" : "n"; 

	if ( strPayload.length > intMaxSize ) {
		intMaxSize = strPayload.length; 
		currentMaxItem = strID; 	
	}
	
	var smallCapsSetting;
	smallCapsSetting = getStyleSheetRuleAttribute(strClass, "fontVariant");
	if ("small-caps"==smallCapsSetting) {
		strPayload = strPayload.toUpperCase();
	}

	if ( bHasMenu && INLN == intMenuStyle ) { 
		click = "onClick=\"doClick(this);return false;\"";
	} else {
		click = "onClick=\"doHREF(this);return true;\"";
	}
	
	strTable = "<table width='100%' class='" + strClass + "' id='" + strID + "' border='" + DEBUG + "' cellpadding='0' cellspacing='0' " + click + ">";

	//Add framing cells	
	if ( frameArray && frameArray.length > 0 ) {
		strTable += strDrawMenuCells(frameArray, strClass, strHREF, strPayload, bHasMenu, bIsSelected, intMenuStyle);
	} else {
		// if we're in the purchasing system top frame
		if (self.name == 'bfora_purchase_title' || self.name == 'bfora_purchase_list') {
			strTable += "<tr><td  width='100%' class='" + strClass + "'><a target=\"_top\" href='" + strHREF + "'>" + makeImg(strPayload, bIsSelected, null) + "</a></td></tr>";
		} else {
			strTable += "<tr><td  width='100%' class='" + strClass + "'><a href='" + strHREF + "'>" + makeImg(strPayload, bIsSelected, null) + "</a></td></tr>";
		}
	}
	
	strTable += "</table>";
	
	document.writeln(strTable);
	//alert(strTable);
}

//Checks if the item is in the arContentPath.
//If so returns true
//Calls the recursive function bCheckMenu
function isItemSelected(item) {

	var level = item.level;
	if ( arContentPath[level] && arContentPath[level] == item.name ) 
	{
		var bReturn = bCheckMenu(item.parentIndex, level-1);
		if ( bReturn ) addItemToArray(arContentPath, item, level);
		return bReturn;
	}
	else 
	{
		return false;
	}
}

//Recursively checks the menu name against the arContentPath of the level
//Calls itself recursively to move backwards through the menu
function bCheckMenu(parentIndex, level) {
	if ( arrMenus[parentIndex].name == arContentPath[level] ) 
	{
		if ( arrMenus[parentIndex].parentIndex != null && level > 0) 
		{
			var bReturn = bCheckMenu( arrMenus[parentIndex].parentIndex, level-1 );
			if ( bReturn ) addItemToArray(arContentPath, arrMenus[parentIndex], level);
			return ( true && bReturn );
		} 
		else 
		{
			addItemToArray(arContentPath, arrMenus[parentIndex], level);
			return true;
		}
	} 
	else 
	{
		return false;
	}
}

//addItemToArray
// adds the specified item to the arContentPath so it can be opened when the menu has been built.
function addItemToArray(array, item, position) {
	array[position + "_item"] = item;
}

//Takes the item text and works out if it is an image. If so creates an IMG tag.
function makeImg(strItem, bIsSelected, width, height) {

	//If the item is an image already.
	if ( strItem.indexOf("<img") > -1 ) {
		var a = strItem.indexOf("n.gif");
		if (bIsSelected && (typeof(strItem.replace)=="function")) { 
			var re = /n\.gif/g;
			strItem = strItem.replace(re, 's.gif');
		}
		return strItem;
	}
	
	if ( (strItem.indexOf(".gif") > 0) || (strItem.indexOf(".jpg") > 0) ) {
		var strImage = strItem;
		var intImgSize = strImage.indexOf("n.gif");
		var strWidth = (width) ? " width='" + width + "'" : "" ;
		var strHeight = (height) ? " height='" + height + "'" : "" ;
		if ( bIsSelected && intImgSize > 0 ) strImage = strImage.substr(0, intImgSize) + "s.gif";
		return "<img border='" + DEBUG + "' src='" + strImage + "' " + strWidth + strHeight + ">";
	} else {
		return strItem;
	}
}

//If an item has a submenu this function checks whether a specific cell has
//different contents.
function checkFrameCell(arrFrame, cell, width, height, bHasMenu, bIsSelected) {	
	if ( !bHasMenu || "undefined" == typeof(arrFrame[cell + "_menu"]) ) {
		return makeImg(arrFrame[cell], bIsSelected, width);
	} else {
		return makeImg(arrFrame[cell + "_menu"], bIsSelected, width, height);
	}
}

//Draws the TD that holds the img
function strDrawCellTD(frameArray, intItem, strClass, bHasMenu, bIsSelected)
{
	var strReturn = "<td class='" + strClass + "' ";
	var width = null;
	var height = null;
	
	if ( "undefined" != typeof(frameArray[intItem + "_valign"]) ) {
		strReturn += "valign='" + frameArray[intItem + "_valign"] + "' ";
	}

	if ( "undefined" != typeof(frameArray[intItem + "_align"]) ) {
		strReturn += "align='" + frameArray[intItem + "_align"] + "' ";
	}
	
	if ( "undefined" != typeof(frameArray[intItem + "_width"]) ) {
		width = frameArray[intItem + "_width"];
		strReturn += "width='" + width + "' ";		
	}
	
	if ( "undefined" != typeof(frameArray[intItem + "_height"]) ) {
		height = frameArray[intItem + "_height"];
		strReturn += "height='" + height + "' ";		
	}
	
	strReturn += ">" + checkFrameCell(frameArray, intItem, width, height, bHasMenu, bIsSelected) + "</td>";
	
	//alert("strDrawCellTD strReturn: " + strReturn);
	return strReturn;
}

//Draws the menu items contents and surrounding cells.
//Checks whether the framing cells exist
//Adds anchor tags as necessary
function strDrawMenuCells(frameArray, strClass, strHREF, strPayload, bHasMenu, bIsSelected, intMenuStyle) {
	strTable = "";
	
	//Check if we can ignore row 1
	if ( frameArray[0] || frameArray[1] || frameArray[2] )
	{
		//Turn undefined to "&nbsp;" (prevents the cell being transparent in NS)
		for( var i = 0; i < 3; i++ ) if(!frameArray[i]) frameArray[i] = "&nbsp;";
		strTable += "<tr>" + strDrawCellTD(frameArray, 0, strClass, bHasMenu, bIsSelected) + strDrawCellTD(frameArray, 1, strClass, bHasMenu, bIsSelected) + strDrawCellTD(frameArray, 2, strClass, bHasMenu, bIsSelected) + "</tr>";
		//strTable += "<tr><td class='" + strClass + "'>" + checkFrameCell(frameArray, 0, bHasMenu, bIsSelected) + "</td><td  class='" + strClass + "'>" + checkFrameCell(frameArray, 1, bHasMenu, bIsSelected) + "</td><td  class='" + strClass + "'>" + checkFrameCell(frameArray, 2, bHasMenu, bIsSelected) + "</td></tr>"
	}
		
	//Do row 2
	strTable += "<tr>";
	
	//if ( frameArray[3] ) strTable += "<td  class='" + strClass + "'>" + checkFrameCell(frameArray, 3, bHasMenu, bIsSelected) + "</td>";
	if ( frameArray[3] ) strTable += strDrawCellTD(frameArray, 3, strClass, bHasMenu, bIsSelected);

		

	
	strTable += "<td  width='100%' class='" + strClass + "'>";
	// add anchor: if hasHREF unless (hasMenu and menustyle is inline)
	if ( strHREF.length > 0 && !(bHasMenu && INLN == intMenuStyle) ) {
		if (self.name == 'bfora_purchase_title' || self.name == 'bfora_purchase_list')
			strTable += "<a target=\"_top\" href='" + strHREF + "'>" +makeImg(strPayload, bIsSelected, null) + "</a>";
		else
			strTable += "<a href='" + strHREF + "'>" +makeImg(strPayload, bIsSelected, null) + "</a>";
	} else {
		strTable += makeImg(strPayload, bIsSelected, null);
	}
	strTable += "</td>";
	
	//if (frameArray[4]) strTable += "<td  class='" + strClass + "'>" + checkFrameCell(frameArray, 4, bHasMenu, bIsSelected) + "</td>";
	if ( frameArray[4] ) strTable += strDrawCellTD(frameArray, 4, strClass, bHasMenu, bIsSelected);
	
	strTable += "</tr>";
		
	//Check if we can ignore row 3
	if ( frameArray[5] || frameArray[6] || frameArray[7] )
	{
		//Turn undefined to "&nbsp;" (prevents the cell being transparent in NS)
		for( var i = 6; i < 9; i++ ) if(!frameArray[i]) frameArray[i] = "&nbsp;";
		strTable += "<tr>" + strDrawCellTD(frameArray, 5, strClass, bHasMenu, bIsSelected) + strDrawCellTD(frameArray, 6, strClass, bHasMenu, bIsSelected) + strDrawCellTD(frameArray, 7, strClass, bHasMenu, bIsSelected) + "</tr>";
		//strTable += "<tr><td class='" + strClass + "'>" + checkFrameCell(frameArray,5, bHasMenu, bIsSelected) + "</td><td  class='" + strClass + "'>" + checkFrameCell(frameArray, 6, bHasMenu, bIsSelected) + "</td><td class='" + strClass + "'>" + checkFrameCell(frameArray, 7, bHasMenu, bIsSelected) + "</td></tr>"
	}

	return strTable;
}

//Draws any menu separators (a separator is just another menuitem with a different class) 
function drawMenuSep(style, level, bIsTop) {
	var arrSep = getSepForLevel(level, bIsTop);
	var strTable = "";
	var strClass = ( bIsTop ) ? "tl" : "sl";
		
	if ( arrSep && arrSep["contents"] && arrSep["level"] ) {
		strClass += arrSep["level"] + "sep";
		
		if ( HORI == style || TABD == style || GRID == style ) strTable += "</td><td>";
	
		strTable += "<table id='" + MENU_SEP_ID + "' width='100%' cellpadding='0' cellspacing='0' border='" + DEBUG + "'>";
		//Ideally should be this but has too many problems... oh well some day.
		//strTable += strDrawMenuCells(arrSep, strClass, "", arrSep["contents"], false, false, NONE);
		strTable += "<td class='" + strClass + "' width='100%'>" + makeImg(arrSep["contents"], false, null, null) + "</td>";
		strTable += "</table>";
	}
		
	if ( HORI == style || TABD == style || GRID == style ) strTable += "</td><td>";
	
	document.writeln(strTable);
}

//Creates the DIV which will contain the menu
function drawMenuStart(intLevel, strID, bVertical, bIsVisible, intMenuStyle) {
	var style = "\"";
	var bIsTop = ( 't' == strID.charAt(0) );
	var strClass = getClassForMenu(intLevel, bIsTop);
	var strNewID = strID;
	var intMinWidth = ( bIsTop ) ? TOPMENU_MIN_WIDTH : SIDEMENU_MIN_WIDTH ;
	
	if ( bVertical ) {
		if ( bIsVisible ) {
			style += "position:absolute; visibility:visible; width:" + intMinWidth + "px;"; 
			strNewID = strID + "-fixed";
		} else {
			style += "position:absolute; visibility:hidden; width:" + intMinWidth + "px;";
		}
	} else {
		if ( bIsVisible ) {
			style += "position:relative; display:block; width:" + intMinWidth + "px;"; 
			strNewID = strID + "-fixed";
		} else {
			style += "position:relative; display:none; width:" + intMinWidth + "px;";
		}
	}
	
	if ( INLN == intMenuStyle ) {
		style += "margin-left: " + INLINE_MENU_INDENT + "px;";
		style += "z-index:1;";
	} else {
		style += "z-index:50;";
	}
	
	if (DEBUG > 0) style += "border: inset " + DEBUG + " red;\"";
	else style += "\"";

	//alert("MENU ID: " + strNewID + ", class: " + strClass);
	
	if ( strNewID.indexOf("-fixed") > 0 ) {
		arrFixedMenuSizes[arrFixedMenuSizes.length] = strID;
		//arrMenuSizes[arrMenuSizes.length] = strNewID;
	} else {
		arrMenuSizes[arrMenuSizes.length] = strID;
	}
	currentMenu = strNewID;
	
	document.writeln("<div class=" + strClass + " id=" + strID + " style=" + style + ">");
}

//Closes the menu DIV
//Resets item size varaibles
function drawMenuEnd() {
	document.writeln("</div>");

	arrMenuSizes[currentMenu + "_item"] = currentMaxItem;
	arrMenuSizes[currentMenu + "_max"] = intMaxSize;
	
	intMaxSize = 0;
	currentItem = null;
	currentMenu = "";
	
}

//Creates a table and row to hold horizontally placed menu items
function drawHorizontalMenuStart() {
	
	var w,s;
	w = 0;
	s = 0;
	
	if (typeof(TOPMENU_WIDTH)!="undefined") {
		w  = TOPMENU_WIDTH;
	}
	if (typeof(TOPMENU_STYLE)!="undefined") {
		s  = TOPMENU_STYLE;
	}
	document.writeln("<table border='" + DEBUG + "' cellspacing='0' cellpadding='0'" + (w==0?"":" width='"+w+"'") + (s==0?"":" style='"+s+"'") + "><tr><td>");
	
}

//Closes the row and table
function drawHorizontalMenuEnd() {
	document.writeln("</td></tr></table>");
}

//Closes the row and table
function drawNewMenuRow() {
	document.writeln("</td></tr><tr><td>");
}

//Creates a new table cell for horizontal menu items
function drawHorizontalMenuItem() {
	document.writeln("</td><td>");
}


//============================= Menuitem object ===============================================
function menuItem(strText, strImage, strHREF, intMenu, intLevel, intItem, intIndex) {
	this.name = strText;
	this.image = strImage;
	this.href = strHREF;
	this.level = intLevel;
	this.item = intItem;
	this.menuIndex = intIndex; //index of any submenus
	this.parentIndex = intMenu;
	this.id = BASE_MENU_ID + intMenu + "i" + intItem + "lvl" + intLevel;
}


//============================ Menu object =============================================================
function addItem(item) {
	this.items[this.items.length] = item;
}

function addingMenu(objMenu) {
	this.items[this.items.length-1].menu = objMenu;
}

function menu(strName, intLevel, intID, intParentIndex) {
	this.items = new Array();
	this.name = strName;
	this.level = intLevel+1; //+1 converts zero based JS to 1 based XSL
	this.id = intID;
	this.parentIndex = intParentIndex;
	
	this.add = addItem;
	this.addMenu = addingMenu;	
}
//======================================== end objects ==================================================

//=================== Functions that will be modified for each site =====================================
//These functions are now in separate JS file and are specific for each network.
/*
//Gets the menu style (ie vertical, horizontal, inline etc) for each level
function getStyleFromLevel(level, bIsTop) {}

//Gets the className for a menu
function getClassForMenu(level, bIsTop) {}

//Returns the className (used to select CSS) for an item in a level. 
function getClassForItem(level, item, name, bIsTop) {}

//Returns frameArray used for an item. Used to construct the cells which surround a menu item
function getFrameForItem(level, item, name, bIsTop) {}

//Returns an array containing the contents and cells for a menu separator.
function getSepForLevel(level, bIsTop) {}

*/
//=========================== end site specific functions ================================================

function buildMenus(menuIndex, strPrefix, intForcedMenuStyle, bIsTop) {

	var menu = arrMenus[menuIndex];
	if (menu) {
		var item, strID, bHasMenu, bIsVisible, bIsClickable;
		var intLevel = menu.level;
		var intStyle = ( intForcedMenuStyle != NONE ) ? intForcedMenuStyle : getStyleFromLevel(intLevel, bIsTop);
		var intNumItems = menu.items.length;
		 		
		if (  HORI == intStyle || TABD == intStyle || GRID == intStyle ) {
			drawHorizontalMenuStart();
		}
		
		for (var i = 0; i < intNumItems; i++) {
			item = menu.items[i];
			strID = strPrefix + item.id;
			
			if ( !bIsTop ) {
				bIsVisible = (intLevel - intMenuLevelOffset) <= DEPTH_TO_FIX_OPEN;
				if (bIsVisible) intStyle = INLN;				
			} else {
				bIsVisible = false;
			}
			
			bHasMenu = ( item.menuIndex > -1 ) ? true : false;
			bIsClickable = ( INLN == getStyleFromLevel(intLevel+1, bIsTop) ) ? true : false;			
			drawMenuItem(item, strPrefix, i, bIsTop, bHasMenu, bIsVisible, intStyle);
			
			//Inline menus need to built recursively.
			//Otherwise loopMenus deals with building submenus.
			if ( bHasMenu && INLN == intStyle ) {
				drawMenuStart(intLevel, strID+"c", bIsTop, bIsVisible, intStyle);
				buildMenus(item.menuIndex, strPrefix, intForcedMenuStyle, bIsTop);
				drawMenuEnd();
			}
			
			
			//Controls whether to add separator or break to new row
			if ( i < intNumItems-1 && !( GRID == intStyle && 0 == ((i+1)%GRID_WIDTH) ) ) {
				drawMenuSep(intStyle, intLevel, bIsTop);
			} else if ( GRID == intStyle ) drawNewMenuRow();
			
		}
			
		if ( HORI == intStyle || TABD == intStyle || GRID == intStyle ) {
			drawHorizontalMenuEnd();
		}
	}
}

//Call this function to add the menu defined by the topmenu elements in menudef.xml
function addTopMenu() {

	buildMenuArray();	//Function in users JS file 
	
	var strPrefix = "t";

	document.writeln("<DIV id='basediv' style='z-index:1;'>");
	buildMenus(topMenuIndex, strPrefix, NONE, true);
	document.writeln("</DIV>");
	if ( !bNoTopMenu ) loopMenus(topMenuIndex, strPrefix, true, 0);
				
}

//Call this function to add the menu defined by the topmenu elements in menudef.xml
function addTopMenu2(intStartLevel) {

	buildMenuArray();	//Function in users JS file 

	var strPrefix = "t";
	var menuIndex = getMenuIndexFromContentPath(intStartLevel);

	if (menuIndex != -1) {
		document.writeln("<DIV id='basediv' style='z-index:1;'>");
		buildMenus(menuIndex, strPrefix, NONE, true);
		document.writeln("</DIV>");
		if ( !bNoTopMenu ) loopMenus(menuIndex, strPrefix, true, 0);
	}				
}

//Call this function to add the menu defined by the sidemenu elements in menudef.xml
function addSideMenu(intStartLevel) {

	buildMenuArray();	//Function in users JS file
	intMenuLevelOffset = intStartLevel; //Set level offset
	
	var strPrefix = "s";
	var menuIndex = getMenuIndexFromContentPath(intStartLevel);
	if (menuIndex != -1) {
		var intStyle = getStyleFromLevel(arrMenus[menuIndex].level, false);

		document.writeln("<DIV id='sidediv'>");
	
		if ( INLN == intStyle) {
			buildMenus(menuIndex, strPrefix, NONE, false);
			document.writeln("</DIV>");
			loopMenus(menuIndex, strPrefix, false, 2);
			
		} else {
			buildMenus(menuIndex, strPrefix, NONE, false);
			document.writeln("</DIV>");
			loopMenus(menuIndex, strPrefix, false, 2);			
		}
	}		
}

//Recursively builds a menu and its submenus (unless style is inline)
//Calls buildMenus.
function loopMenus(intMenuIndex, strPrefix, bIsTop) {

	var menu = arrMenus[intMenuIndex];
	var style = getStyleFromLevel(menu.level, bIsTop);
	if (menu && INLN != style) {
		
		drawMenuStart(menu.level, strPrefix + menu.id, true, false, style);
		buildMenus(intMenuIndex, strPrefix, NONE, bIsTop);
		drawMenuEnd();
		
		for (var i = 0; i < menu.items.length; i++) {
			if ( menu.items[i].menuIndex > 0 ) loopMenus(menu.items[i].menuIndex, strPrefix, bIsTop);
		}
	}
}

//Finds the menuindex from the level of arContentPath
//NB: returns -1 if unable to find a match.
function getMenuIndexFromContentPath(intContentPathLevel) {

	var iReturn = -1;

	for (var i = 0; i < arrMenus.length; i++) {
		if (arrMenus[i].name == arContentPath[intContentPathLevel]) iReturn = i;
	}
	
	return iReturn;
}


//Takes the menu ids from arrMenuSizes and adjusts their sizes.
//Fixes problem with IE5.0 AND increases responsiveness!
//Also adjusts menu sizes so images lineup on forced opened menus
function adjustSubmenuWidths() {

	intMaxSize = 0;

	//IE 5   - same problems as IE 5.5. Topmenu menus aren't square (until mouseover then gets right size!)
	//IE 5.5 - causes strange top menu sizes - ie resource centre is very very long
	//NS 6   - side: makes biggest item a little bigger?! (for fixed open menus)
	//		 - top: makes underlying div the size of the biggest item - required
	changeDIVToMaxItem() 

	//IE 5   - fixes top menu shape - required
	//IE 5.5 - this or modifyFixedOpenMenus fixes image lineup on fixed open menus
	//NS 6   - with modifyFixedOpenMenus makes all fixed menus items the same width.
	changeDIVSize()

	//IE 5   - Fixes image lineup and sidemenu shape - required
	//IE 5.5 - this or changeDIVSize fixes image lineup on fixed open menus 
	//		 - this has better side menu sizing
	//NS 6   - increases holding item size
	modifyFixedOpenMenus()
}

function changeDIVSize() {
	var strTemp = "changeDIVSize\n";
	var strID, strParent;
	var objMenu, objItem;
	var menuOffsetWidth;
	var itemOffsetWidth;
	
 	//This increases the width of the underlying DIV to prevent items sticking out of the menu
	//This fixes a problem with IE5 topmenus
	for (var i = 0; i < arrMenuSizes.length; i++) {
		
		//Fixes menu shape in IE5.
		objMenu = document.getElementById(arrMenuSizes[i]);
		if ( objMenu ) { 
			menuOffsetWidth = objMenu.offsetWidth;
			if (NS && menuOffsetWidth == 0) { menuOffsetWidth = 1; }
			objMenu.style.width = menuOffsetWidth;
		}
	}	
}

function changeDIVToMaxItem() {
	//Changes the underlying div to the size of the largest menu item (plus a little extra)
	var strTemp = "changeDIVToMaxItem\n";
	var strCurrentID = "";
	var objItem = null;
	var objMenu = null;
	var intMaxWidth = 0;
	var bIsSideMenu = false;

	for ( var i = 0; i < arrMenuSizes.length; i++ ) {
		strCurrentID = arrMenuSizes[i];
		
		bIsSideMenu = ( 's' == strCurrentID.charAt(0) ) ? true : false;
		objItem = document.getElementById( arrMenuSizes[strCurrentID + "_item"] );
		objMenu = document.getElementById( strCurrentID );
		if ( objMenu && objItem) {
			if ( objItem.offsetWidth > objMenu.offsetWidth ) {
				intMaxWidth = ( bIsSideMenu && objItem.offsetWidth > intMaxWidth ) ? objItem.offsetWidth : intMaxWidth;
				if ( !bIsSideMenu ) objMenu.style.width = objItem.offsetWidth;
			} else {
				intMaxWidth = ( bIsSideMenu && objMenu.offsetWidth > intMaxWidth ) ? objMenu.offsetWidth : intMaxWidth;
			}
		}		
	}

	//Fix Mac IE problem
	if (Mac && IE) { 
		intMaxWidth = intMaxWidth - 6;
	}
	
	if (intMaxWidth<=0) { intMaxWidth=1; }
	
	for ( var i = arrMenuSizes.length-1; i > -1; i-- ) {
		strCurrentID = arrMenuSizes[i];
		
		if ( 's' == strCurrentID.charAt(0) ) {
			objItem = document.getElementById( arrMenuSizes[strCurrentID + "_item"] );
			objMenu = document.getElementById( strCurrentID );
			if ( objItem ) {
				objItem.style.width = intMaxWidth;
			}
			if ( objMenu ) {
				objMenu.style.width = intMaxWidth;
			}
		}
	}
}


function modifyFixedOpenMenus() {
	var strTemp = "modifyFixedOpenMenus\n";
	var strID, strParent, objMenu, objItem;

	//Menus that have been fixed open need to make sure all the images lineup
	for (var i = 0; i < arrFixedMenuSizes.length; i++) {
		strID = arrFixedMenuSizes[i];
		strParent = strID.substr(0, strID.length-1);
		objMenu = document.getElementById(strID);
		objItem = document.getElementById(strParent + "-fixed");
		if ( objMenu && objItem && objItem.offsetWidth > objMenu.offsetWidth ) {
			objMenu.style.width = objItem.offsetWidth-INLINE_MENU_INDENT;
		} else {
			objItem.style.width = objMenu.offsetWidth+INLINE_MENU_INDENT;
		}
	}
		
}

//function openSelectedItem :
// finds the selected item and opens any menu that contain it and any menus that contain that menu. etc. etc.
// only needed if the menu is inline.
function openSelectedItem() {

	if ( INLN == getStyleFromLevel(2, false) ) {
	
		var strID;
		for (var i = arContentPath.length-1; i > -1; i--) {
			
			if ( arContentPath[i+"_item"] ) {
				strID = "s" + arContentPath[i+"_item"].id;
				
				if ( strID && 'c' == strID.charAt(strID.length-1) ) {
					var objTemp = document.getElementById(strID.substr(0, strID.length-1));
					if ( objTemp ) doClick(objTemp);
				}
			}	
		}
	}
}


// Helper method to return a value of a stylesheet setting
var ruleCache;
initRuleCache();
function getStyleSheetRuleAttribute(ruleSelectorText, ruleAttrib) {

	var selectorText = "." + ruleSelectorText;

	//Return value from cached style if found
	if(typeof(ruleCache[selectorText])=="object") {
		return ruleCache[selectorText][ruleAttrib];
	} else {
		return;
	}
}

function applyStyle(node, ruleSelectorText) { 

	if (typeof(node)=="undefined") { return;}
	if (typeof(node.style)=="undefined") { return;}
	
	var selectorText = "." + ruleSelectorText;

	//Return value from cached style if found
	if(typeof(ruleCache[selectorText])=="object") {
		var s;
		s = ruleCache[selectorText];
		node.style.backgroundColor = s.backgroundColor;
		node.style.color = s.color;
		
	}
}


function initRuleCache() { 

	ruleCache = new Object();
	
	//exit if styleSheet examination not supported by DOM 
	if (typeof(document.styleSheets)=="undefined") { return; }
  
	//Cache stylesheet rules
	var styleSheets = document.styleSheets;
	var styleSheetsLength = styleSheets.length;
	var styleSheet, rules, j, rulesLength;
	for(var i=0;i<styleSheetsLength;i++) { 
		styleSheet = styleSheets[i];
		rules = false;
	
		//Get mozilla-compatible rules
		if (typeof(styleSheet.cssRules)!="undefined") { 
			rules = styleSheet.cssRules;
		} else {
			//Get ie-compatible rules
			if (typeof(styleSheet.rules)!="undefined") { 
				rules = styleSheet.rules;
			}
		}
		
		//exit if cannot access rules for stylesheet
		if (typeof(rules)=="boolean") {return;}
		
		rulesLength = rules.length;
		
		if (rulesLength == 0) { continue; }

		//Ignore non-menu stylesheets
		if (rules[0].selectorText==".tl1alln") { 
			for(r=0; r<rulesLength; r++) { 
				ruleCache[rules[r].selectorText] = rules[r].style;
			}
		}
		//Special-case for IE5 Mac
		if (rules[0].selectorText=="*.tl1alln") { 
			for(r=0; r<rulesLength; r++) { 
				ruleCache[rules[r].selectorText.substr(1)] = rules[r].style;
			}
		}	
	}
}

