/*pi2 Dynamic Menu System Version 1.3 Copyright © 2006 Square Root Cool New Media CC 
You may not modify the content of this file

ALL MENU DIVS FOLLOW THE BELOW ID NAMING SCHEME:

Parent div: Menu_0: child div: Menu_0_0, Menu_0_1 etc.
Each Parent div contains a series of divs with specified heights, containing <a> menu entries with id tags corresponding to the child div that must be shown: Menua0a0, Menua0a1 etc.
Menu entries with no child div to activate: Menua0aEnd.

Flyout parent menu divs are statically positioned, either in static html code, or script generated code. This allows for drop down, side, and bottom menus. The x positions of 1st level menu entries are stored in adjustDivArray for dynamic re-positioning in the event of a centered design
The width of each div is also pre-determined or script generated.
The height of individual divs containing the menu entries are totalled up statically or by script and put as a style attribute in the div that contains them. This total height is the same as the total height of the menu entries contained in said divs, plus the borders controlled by the stylesheet.

The container divs can have style sheet allocated borders, etc. which are stored as global variables: shadowBot, shadowRight etc. Netscape adds border widths to the width of the div, whereas IE & Opera contain the widths inside the div width, so have to handle them separately. 

onMouseOver and onMouseOut events are handled by initEvents function.

This menu system is Netscape 6 upwards compliant, Mozilla 1.0 upwards compliant, Opera 6 upwards compliant, and IE 5.5 upwards compliant
Netscape 4.x is dead & buried, get over it. Use XHTML strict or transitional, otherwise your style sheet will be whacked...*/

/*user defined global variables*/
var centeredDesign=true; /*for centre floating designs*/
var templateWidth=766;/*width of site template on px*/
var delay=200;/*delay onMouseout of menu divs before hiding again*/
var scrollTabHeight=10; /*height of scrolling tabs*/
var gap=1; /*vertical gap between parent & child div*/
var shadowBot=1; /*how wide the border on the bottom of the menu div is in the style sheet*/
var shadowRight=1; /*how wide the border on the RHS of the menu div is in the style sheet*/
var borderLeft=1; /*how wide the border on the LHS of the menu div is in the style sheet*/
var navPadding=0;/*have to reduce width of menu divs for IE 6.x to compensate for left & right padding of anchor tags in strict XHTML mode*/

/*global variables*/
var oldTree='blah';
var oldId='blah';
var clippedLayer='blah';/*record of div that's been clipped*/
var scrolledLayer='blah';/*record of div that's been scrolled*/
var delayed;
var Netscape=false;
var Opera=false;
var IE5=false;
var IE6=false;
var Other=false;
var scrollerFlag=false;
var clipFlag=false;
var eventCounter=0;
var oldMenu=0;
var clipTop=0;
var clipBottom=0;
var topper=0;
var lyrHeight=0;
var rootFlag=false;
var rootYFlag=false;
var readyFlag=false;
var eventFlag=false;/*makes sure event handler array only gets populated once*/
var rootDivFlag=true;/*makes sure routine to get x position of parent divs only gets run once*/
var rootDivResizeFlag=false;/*makes sure routine to correct width of divs in IE6 only gets run once*/
var rootY=0;/*records how much a root level div has moved if scrolled, for resetting*/
var rootDiv=0;/*records which root level div has been scrolled, for resetting*/
var time,amount,theTime,theHeight;
arrowArray=new Array();
divEventArray=new Array();/*array of all the divs with event handlers on them*/
eventArray=new Array();/*array of all the elements with event handlers on them*/
showDivArray=new Array();/*keeps history of divs that have been shown in showMenu*/
posDivArray=new Array();/*keeps history of divs that have been shown in showMenu*/
adjustDivArray=new Array();/*record of parent div's original x positions*/

/*set the puppy up*/
window.onload = start;
window.onresize = rePosition;

function start(){
	init('arrow_right.gif');
	rePosition();
	checkRootEvents();
	initEvents();
}

/*functions*/
function returnInt(name){/*returns the integer equivalent of a passed string of pixel height: eg '20px'*/
	name=name.split('p');
	name=parseInt(name);
	return name;
}

function init(image1){/*preloads the arrow image to swap & determines browser type*/
	readyFlag=true;
	myImage = new Image();
	myImage.src=image1;
	if(navigator.appName == "Netscape"){
		Netscape=true;
		navPadding=0;
	}
	else{
		if(navigator.userAgent.indexOf('Opera') != -1){
			Opera=true;
			navPadding=0;
		}
		else{
			if (navigator.appVersion.indexOf("MSIE")!=-1){
				temp=navigator.appVersion.split("MSIE")
				var version=parseFloat(temp[1])
				if (version>=5.5 && version < 6.0){ //NON IE browser will return 0
					IE5=true;
					navPadding=0;
				}
				else{
					if(version>=6.0){
						IE6=true;
						rootDivResizeFlag=true;
					}
				}
			}
			else{
				Other=true;
			}
		}
	}
}

function checkRootEvents(){/*creates all root level event handlers*/
	var str=new String('Menua0');
	var eor=true;
	var i=0;
	while (eor==true){
		if (document.getElementById(str)){
			eventArray.push(document.getElementById(str));
		}
		else{
			eor=false;	
		}
		str=str.replace(i,i+1);
		i++;
	}
}

function initEvents(){/*handles all onMouseOver & onMouseOut events on menu entry divs*/
	for(var i=0; i<eventArray.length; i++){
		eventArray[i].onmouseover = function () {showMenu(this)}
		eventArray[i].onmouseout = function () {delayed=setTimeout('HideMenu()',delay)}
	}
	for(var i=0; i<divEventArray.length; i++){/*handles all onMouseOver & onMouseOut events on menu divs*/
		divEventArray[i].onmouseover = function () {beyondEdgeCaller(this)}
		divEventArray[i].onmouseout = function () {beyondEdgeCaller(this)}
	}
}

function initScroll(layer,botShifter,topShifter)
{
	clipTop=topShifter+scrollTabHeight;
	clipBottom = botShifter;
	topper = returnInt(layer.style.top);
	lyrHeight=returnInt(layer.style.height);
	layer.style.clip = 'rect('+topShifter+'px auto '+botShifter+'px 0px)';
	test=layer.id.split('_');
	if(test.length==2 && rootDiv!=layer){
		rootY=layer.style.top;
		rootDiv=layer;
		rootYFlag=true;
	}
}

function scrollayer(layer,amt,tim){
	test=layer.id.split('_');
	layernm='Menu_'+test[1];
	rootDiv=document.getElementById(layernm);
	rootFlag=true;
	thelayer = layer;
	if (!thelayer) return;
	amount = amt;
	theTime = tim;
	realScroll();
}

function stopScroll(){
	if (time) clearTimeout(time);
}

function realScroll(){
	clipTop += amount;
	clipBottom += amount;
	topper -= amount;
	if (clipTop < 0 || clipBottom > lyrHeight)
	{
		clipTop -= amount;
		clipBottom -= amount;
		topper += amount;
	}
	clipstring = 'rect('+clipTop+'px auto '+clipBottom+'px 0px)'
	thelayer.style.clip = clipstring;
	thelayer.style.top = topper+'px';
	time = setTimeout('realScroll()',theTime);
}

function beyondEdgeCaller(menu){
	if(oldMenu==menu){
		return;
	}
	else{
		if (scrollerFlag==true){
			resetScrollers();
		}
		if (clipFlag==true){
			resetClip();
		}
		beyondEdgeDecide(menu);
		oldMenu=menu;
	}
}
	   
function resetScrollers(){
	var myDocument=document;
	scrollDown=document.getElementById('scroller_down');
	scrollUp=document.getElementById('scroller_up');
	scrollDown.style.visibility="hidden"; 
	scrollUp.style.visibility="hidden";
	scrollDown.style.left='0px';
	scrollUp.style.left='0px';
	scrollDown.style.top='0px'
	scrollUp.style.top='0px';
	scrollerFlag=false;
}

function resetClip(){
	clippedLayer.style.clip = 'rect(0px auto auto 0px)';
	clipFlag=false;
}

function resetArrows(){/*Resets arrows that got flipped by edgeDecide*/
	var myDocument=document;
	for (var i=0;  i<arrowArray.length; i++){
		Arrow=arrowArray[i];
		myDocument.getElementById(Arrow).childNodes[0].setAttribute("src", "/pics/arrow_right.gif");	
	}
	arrowArray.length=0;/*Otherwise it gets huge over time*/
}

function resetRootDiv(){
	if (rootYFlag==true){
		rootDiv.style.top=rootY;
		rootYFlag=false;
	}
	posMenu(rootDiv);
	rootDiv=0;
	rootFlag=false;
}

function detectScreenHeight(){
	myDocument=document;
	if (window.innerHeight){/*this is for Mozilla)*/
		screenHeight = window.innerHeight;
		return screenHeight;
	}
	else{/*for IE 6.x in "standards compliant" mode*/
		if(document.documentElement.clientHeight){
			screenHeight = document.documentElement.clientHeight;
			return screenHeight;
		}
		else{/*for Other browsers*/
			screenHeight = myDocument.body.clientHeight;/*other browsers*/
			return screenHeight;
		}
	}
}

function detectScreenWidth(){
	myDocument=document;
	if (window.innerWidth){/*this is for Mozilla && Opera and other buggers)*/
		screenWidth = window.innerWidth;
		screenHeight=detectScreenHeight();/*so that I can detect for scrollbar*/
		if(document.body.scrollHeight>screenHeight){
			screenWidth-=21;//remove scrollbar width for Mozilla Firefox & Opera
		}
		return screenWidth;
	}
	else{/*for IE 6.x in "standards compliant" mode*/
		if(document.documentElement.clientWidth){
			screenWidth = document.documentElement.clientWidth;
			return screenWidth;
		}
		else{/*for Other browsers*/
			screenWidth = myDocument.body.clientWidth;/*other browsers*/
			return screenWidth;
		}
	}
}

function initRoot(){/*positions the 1st level pop-out menu items*/
	var myDocument=document;
	screenWidth=detectScreenWidth();
	myxpos=(screenWidth-templateWidth)/2;
	myxpos=Math.round(myxpos);
	return myxpos;
}

function rePosition(){/*Creates an array of all the root Menu divs, to be repositioned by posMenu, when the browser detects onLoad & onResize events, or first loads*/
	if (centeredDesign==true)
	{
		tempx=initRoot();
	}
	else{
		tempx=0;
	}
	eventCounter=0;/*Resets everytime the user resizes the window, for populating showDivArray in posMenu, to be passed to initEvents*/
	var myDocument=document;
	if(Netscape||Opera||Other){
		var j=0;
		var i=1;
		do{
			divEventArray[j]=myDocument.getElementById('Menu').childNodes[i];
			test=divEventArray[j].id.split('_');
			if(test.length==2){
				posDivArray[j]=divEventArray[j];
			}
			j++;
			i+=2
		}
		while(divEventArray[j-1]!=myDocument.getElementById('Menu').lastChild.previousSibling);												
	}
	else{
		var i=0;
		do{
			divEventArray[i]=myDocument.getElementById('Menu').childNodes[i];
			test=divEventArray[i].id.split('_');
			if(test.length==2){
				if (rootDivResizeFlag==true){/*on page load, adjusts width of menu divs in IE6 to adjust for left & right padding*/
					divEventArray[i].style.width=returnInt(divEventArray[i].style.width)-navPadding+'px';
					rootDivResizeFlag=false;
				}
				posDivArray[i]=divEventArray[i];
			}
			i++;
		}		
		while(myDocument.getElementById('Menu').childNodes[i-1]!=myDocument.getElementById('Menu').lastChild);
	}
	resetArrows();/*Restores any flipped arrows back to normal*/
	if (rootDivFlag==true){/*on page load, passes parent div's x positions to adjustDivArray*/
		for(var i=0; i<posDivArray.length; i++){
			adjustDivArray[i]=returnInt(posDivArray[i].style.left);
		}
		rootDivFlag=false;
	}
	for(var i=0; i<posDivArray.length; i++){
		posDivArray[i].style.left=adjustDivArray[i]+tempx+'px';
		posMenu(posDivArray[i]);
	}
	eventFlag=true;
}

function beyondEdgeDecide(layer){/*checks if a div is extending beyond the bottom or top of the browser and makes it scrollable if necessary*/
	var myDocument=document;
	screenHeight = detectScreenHeight();
	if (self.pageYOffset){ // all except Explorer
		y = self.pageYOffset;
	}
	else if (myDocument.documentElement && myDocument.documentElement.scrollTop){// Explorer 6 Strict, I know, I know...
		y = myDocument.documentElement.scrollTop;
	}
	else if (myDocument.body) // all other Explorers
	{
		y = myDocument.body.scrollTop;
	}
	height=returnInt(layer.style.height);
	myTop=returnInt(layer.style.top);
	if((myTop-y+height+shadowBot>screenHeight)||(myTop<y)){
		scrollerFlag=true;
		clipFlag=true;
		clippedLayer=layer;
		scrollUp=myDocument.getElementById('scroller_up');
		scrollDown=myDocument.getElementById('scroller_down');
		if (y-myTop<0){/*Positioning top scroller*/
			topShifter=0;
		}
		else{
			topShifter=y-myTop;
		}
		scrollUp.style.top=returnInt(layer.style.top)+topShifter+'px';
		botShifter=height-(myTop-y+height+shadowBot-screenHeight+scrollTabHeight);/*Positioning bottom scroller*/
		if (botShifter<height){
			scrollDown.style.top=myTop+botShifter+'px';
		}
		else{
			scrollDown.style.top=myTop+height+'px';
			botShifter=height;
		}
		scrollUp.style.visibility="visible";
		scrollDown.style.visibility="visible";
		if(IE5 == true){
			scrollUp.style.width=layer.style.width;
			scrollDown.style.width=layer.style.width;
		}
		else{
			scrollUp.style.width=returnInt(layer.style.width)+shadowRight+borderLeft+navPadding+'px';
			scrollDown.style.width=returnInt(layer.style.width)+shadowRight+borderLeft+navPadding+'px';
		}
		re = /_/gi;/*making id for scrollers for the div that it's currently on*/
		str = layer.id;
		newstr = str.replace(re,"a");
		newstr=newstr+'aEnd';
		scrollUp.childNodes[0].id=newstr;/* cheap and nasty way of making usable object */
		layertoshow=scrollUp.childNodes[0];
		scrollUp.style.left=layer.style.left;
		scrollDown.style.left=layer.style.left;
		initScroll(layer,botShifter,topShifter);
		scrollDown.onmouseover = function () {showMenu(layertoshow); scrollayer(layer,10,50);}
		scrollUp.onmouseover = function () {showMenu(layertoshow); scrollayer(layer,-10,50);}
		scrollDown.onmouseout = function () {delayed=setTimeout('HideMenu()',delay); stopScroll(); posMenu(layer);}
		scrollUp.onmouseout = function () {delayed=setTimeout('HideMenu()',delay); stopScroll(); posMenu(layer);}
	}
	else{
		return;
	}
}
	
function edgeDecide(layer,parentxpos,parentypos,target_anchor){/*checks if a div is extending beyond the side of the browser window, and flips it to the other side of that div's parent*/
	var myDocument=document;
	if(document.documentElement.clientWidth){/*for IE 6.x in "standards compliant" mode*/
		testwidth = document.documentElement.clientWidth;
	}
	else{/*for Other browsers*/
		testwidth = myDocument.body.clientWidth;/*other browsers*/
	}
	rePosWidth=returnInt(layer.style.width)+2;/*offset slightly, so you can see it above the bottom menu*/
	left=returnInt(layer.style.left);
	if(rePosWidth+left+shadowRight>testwidth){
		if(IE5 == true){
			layer.style.left=parentxpos-(rePosWidth+gap);
			layer.style.top=returnInt(layer.style.top)+3+'px';/*offset slightly, so you can see it above the bottom menu*/
		}
		else{
			layer.style.left=parentxpos-(rePosWidth+gap+shadowRight+borderLeft)-navPadding+'px';
			layer.style.top=returnInt(layer.style.top)+3+'px';/*offset slightly, so you can see it above the bottom menu*/
		}
		arrowArray.push(target_anchor);/*keeps a history of all the elements whose arrows got flipped*/
		myDocument.getElementById(target_anchor).childNodes[0].setAttribute("src", "/pics/arrow_left.gif");		
	}
}

function posMenu(layer){/*takes in object: 'layername', goes throught the anchor tags in that object, positioning any divs that are triggered by said anchor tags*/
	var myDocument=document;
	treeLength=1;
	treeFlag=true;
	childArray=new Array();
	tempArray=new Array();
	tempArray[0]=layer;
	while(treeFlag==true){
		for(var i=0;i<treeLength;i++){
			if(Netscape||Opera||Other){
				var j=1;
			}
			else{
				var j=0;
			}
			height=0;
			width=tempArray[i].style.width;/*gets properties of 'layername' to assign to child div, root divs are statically positioned so this gets passed on to child div, which then gets inherited by successive children*/
			width=returnInt(width);
			xpos=tempArray[i].style.left;
			xpos=returnInt(xpos);
			ypos=tempArray[i].style.top;
			ypos=returnInt(ypos);
			do{
				if(Netscape||Opera||Other){
					elementTest=myDocument.getElementById(tempArray[i].id).childNodes[j].childNodes[1];
				}
				else{
					elementTest=myDocument.getElementById(tempArray[i].id).childNodes[j].childNodes[0];
				}
				element=elementTest;
				if (eventFlag==false){
					eventArray[eventCounter]=element;/*adds all <a> tags of 'layername' to eventArray, which contains all child elements of all Menu divs*/
				}
				re = /End/gi;
				str = element.id;
				if (str.search(re) == -1){
					re = /a/gi;
					str = element.id;
					newstr = str.replace(re,"_");
					divToPos=myDocument.getElementById(newstr);/*child element is now positioned & added to temp array for positioning of all that child elements children*/
					divToPos.style.top=ypos+height+'px';
					if(IE5 == true){
						divToPos.style.left=xpos+width+gap+'px';
					}
					else{
						divToPos.style.left=xpos+width+gap+shadowRight+borderLeft+navPadding+'px';
					}
					edgeDecide(divToPos,xpos,ypos,element.id);
					childArray.push(divToPos);
				}
				height+=returnInt(element.parentNode.style.height);
				/*have to increase by 2 for Netscape...because of in-between text node...*/
				eventCounter++;
				if(Netscape||Opera||Other){
					testCon=myDocument.getElementById(tempArray[i].id).lastChild.previousSibling.childNodes[1];
					j+=2;
				}
				else{
					testCon=myDocument.getElementById(tempArray[i].id).lastChild.childNodes[0];
					j++;
				}
			}
			while(element!=testCon);
			tempArray[i].style.height=height+'px';
		}
		treeLength=childArray.length;
		if (treeLength==0){
			treeFlag=false;
			return;
		}
		for(var i=0;i<childArray.length;i++){
			tempArray[i]=childArray[i];
		}
		childArray.length=0;
	}
}

function showMenu(layername){
	var myDocument=document;
	clearTimeout(delayed);
	if(layername.id){
		id=layername.id;
	}
	else{
		id=layername;
		layername=document.getElementById('layername');		
	}
	if (id!=oldId){/*no need to change anything if it's the same as before, ie. another link on the same div that also ends in 'End'*/
		restoreStyles();
		layershow=id.split('a');
		if(rootFlag==true && layershow.length==2){/*resets scrolled div, if you're activating root level divs*/
			resetRootDiv();
		}
		mylength=layershow.length;
		if(mylength<3){/*for if hovering over root menu items*/
			oldMenu=0;
			if (scrollerFlag==true){
				resetScrollers();
			}
			if (clipFlag==true){
				resetClip();
			}
		}
		prevname='_';
		tempArray=new Array();
		for (var i=1; i<mylength; i++){
			name='Menu'+prevname+layershow[i];
			if(layershow[i]!='End'){
				element=myDocument.getElementById(name);
				element.style.visibility="visible";
				if(showDivArray[i-1]){
					if(showDivArray[i-1]!=name){/*compares element in showDivArray to current one, if not the same, make the correspondingly indexed showDivArray element invisible*/	
						element=myDocument.getElementById(showDivArray[i-1]);
						element.style.visibility="hidden";
					}
				}
				tempArray.push(name);
				prevname+=layershow[i]+'_';
			}
			else{
				break;/*Need 'i' to be an accurate representation of what index in showDivArray the comparisons stopped */
			}
		}
		if(showDivArray[i-1]){/*if there are more elements in showDivArray than have just been shown, set these excess elements to 'invisible'*/
			for(var j=i-1;j<showDivArray.length;j++){
				element=myDocument.getElementById(showDivArray[j]);
				element.style.visibility="hidden";
			}
		}
		showDivArray=tempArray;
		oldTree=name;
		if(layershow[mylength-1]=='End'){/*if the link has 'End' in it, give the oldId the current id, for testing whether or not to change anything the next time the user activates showMenu*/
			oldId=id;
		}
		else{
			oldId='blah';/*Sets oldId to something else, in case the user goes off the link onto another one which doesn't have 'End' in its id, and then straight back onto it, in which case the old id will be equal to the new id, and the old tree won't collapse ;)*/
		}
		//apply hover style to active menu tree elements:
		if (mylength>2){
			mylength=mylength-1;
			prevname='a';
			for (var i=1; i<mylength; i++){
				name='Menu'+prevname+layershow[i];
				element=myDocument.getElementById(name);
				if(element.className=='nolink'){
					element.className='nolink_active';
					prevname+=layershow[i]+'a';
				}
				else{
					element.className='menu_active';
					prevname+=layershow[i]+'a';
				}
			}
		}
	}
}

function styleRestore(){/*restore old styles to now de-activeted tree elements:*/
	var myDocument=document;
	if (mylength>2){/*if it's just the 1st level of the tree showing, then the styles were never changed on the menu items*/
		mylength=mylength-1;/*excludes elements that have 'End' at the end, which never had their style changed in the first place*/
		prevname='a';
		for (var i=1; i<mylength; i++){
			name='Menu'+prevname+layershow[i];
			element=myDocument.getElementById(name);
			if(element.className=='nolink_active'){
				element.className='nolink';
				prevname+=layershow[i]+'a';
			}
			else{
				if(element.className!='nolink'){
					re = /a/gi;/*if it's a root_nav, need to reset style too*/
					str = element.id;
					newstr = str.split(re);
					if (newstr.length==2){
						element.className='root_nav';
					}
					else{
						element.className='';
					}
					prevname+=layershow[i]+'a';
				}			
			}
		}
		for (var i=0; i<rootNoLinkArray.length; i++){/*for root_nav elements that have no_link style applied to them*/
			element=myDocument.getElementById(rootNoLinkArray[i]);
			element.className='nolink root_nav';
		}
	}
}

function restoreStyles(){/*for the showMenu function, restores all styles to rheir previous state, before showing the new tree*/
	layershow = oldTree.split('_');
	mylength = layershow.length;
	styleRestore();
}

function HideMenu(){/*hides all elements recorded in oldTree*/
	var myDocument=document;
	layershow = oldTree.split('_');
	mylength = layershow.length;
	prevname='_';
	for (var i=1; i<mylength; i++){
		if(layershow[i]!='End'){
			name='Menu'+prevname+layershow[i]
			element=myDocument.getElementById(name);
			element.style.visibility="hidden";
			prevname+=layershow[i]+'_';
		}
	}	
	styleRestore();
	oldMenu='blah';
	if (clipFlag==true){
		resetClip();
	}
	if (scrollerFlag==true){
		resetScrollers();
	}
	if (rootFlag==true){
		resetRootDiv();
	}
}