//	Menu JavaScript functions
//	ReleaseDate: 18 Jan 2004
//	Copyright (c) 2003-2004 by inCharge.co.uk limited
//	http://www.inCharge.co.uk  mailto:enquiries@inCharge.co.uk


/*
**	clsMenu
*/

function strrMatch(strValue, strFind)
{
	return strValue.substr(strValue.length-strFind.length, strFind.length) == strFind;
}

function strrStrip(strValue, strFind)
{
	if (strrMatch(strValue, strFind))
		return strValue.substr(0,strValue.length-strFind.length)
	else
		return strValue;
}

/*
*/
function getClassxx(strClass,cMode)
{
	var arrClass = strClass.split(" ");
	for (var i=0;i<arrClass.length; i++)
	{
		arrClass[i]=strrStrip(arrClass[i], 'Ov');
		arrClass[i]=strrStrip(arrClass[i], 'Sel');
		switch (cMode)
		{
			case 'n': arrClass[i]+=''; break;
			case 'o': arrClass[i]+='Ov'; break;
			case 's': arrClass[i]+='Sel'; break;
		}
	}
	return arrClass.join(" ");
}

function setClassxx(e, str)
{
	if (e.className != str) e.className=str;
}

function strMatch(strValue, strFind)
{
	return strValue.substr(0, strFind.length) == strFind;
}

// Given a TD, return the first A child
function getAfromItem(e)
{
	if ( e.tagName != 'TD' )
		return null;

	for (var c = e.firstChild; c; c = c.nextSibling)
	{
		if ( c.tagName == 'A' )
		{
			return c;
		}
	}

	return  null;
}

// Given a TD, find the first DIV
// The TD is a subMenu comtainer, and the DIV is the subMenu
function getMenufromItem(e)
{
	if ( e.tagName != 'TD' )
		return  null;

	for (var c = e.firstChild; c; c = c.nextSibling)
	{
		if ( c.tagName == 'DIV' && strMatch(c.className,"subMenu") )
		{
			return c;
		}
	}

	return  null;
}

function isTopLevel(e) {

	while (e) {
		if ( strMatch(e.className,"subMenu") )
			return false;
		else if ( strMatch(e.className,"menu") )
			return true;
		e = e.parentNode;
	}
	return true;
}

function clsMenu(strMenuId)
{
	var arr, i, objSelected;

	var objThis = this;

	this.arrOver=null;		// array of elements from the 'over' element up
	this.arrSelected=null;	// array of elements from the 'selected' element up
	this.objTimer=null;		// timer to hide submenus
	this.eSelected=null;	// selected menu item
	this.elMenu=xGetElementById(strMenuId);
	this.popup=false;
	this.topStatic=false;

	// Set mouse over/out events on all As
	arr = xGetElementsByTagName('A', this.elMenu);
	for (i = 0; i < arr.length; ++i) {
		xAddEventListener(arr[i], 'mouseover', onMouseOver, false);
		xAddEventListener(arr[i], 'mouseout', onMouseOut, false);
	}

	//
	this.arrOver = new Array();
	this.arrOver[0] = this.elMenu;
	objSelected = xGetElementById('idSelected');
	if (objSelected)
		setSelected( getAfromItem(objSelected) );

	//
	function setOver(e)
	{
		objThis.arrOver = new Array();

		while (e) {
			if ( xDef(e.tagName) )
			{
				if (e.tagName=='TD')
				{
					var objMenu = getMenufromItem(e);
					if (objMenu && !objThis.arrOver.length)
					{
						// Over an item with a submenu
						//alert('its a submenu!:' + e.firstChild.tagName);
						objThis.arrOver[0] = getMenufromItem(e);
					}

					objThis.arrOver[objThis.arrOver.length] = getAfromItem(e)
				}
				else if (strMatch(e.className,'menu') || strMatch(e.className,'subMenu') )
					objThis.arrOver[objThis.arrOver.length] = e;
			}

			e = e.parentNode;
		}
	}

	function setSelected(e) {
		objThis.arrSelected = new Array();

		while (e) {
			if ( xDef(e.tagName) && e.tagName == 'TD' )
					objThis.arrSelected[objThis.arrSelected.length] = getAfromItem(e)
			e = e.parentNode;
		}
	}

	function dumpOver() {
		var str='', i;
		for ( i=0; i<objThis.arrOver.length; i++)
			str=str+'-'+objThis.arrOver[i].tagName;
		window.alert(objThis.arrOver.length + ' elements: ' + str);

	}

	function clearTimer() {
		if (objThis.objTimer)
		{
			clearInterval(objThis.objTimer);
			objThis.objTimer=null;
		}
	}

	function onMouseOver(evt) {
		clearTimer();
		var e = new xEvent(evt);

		e = e.target;
		setOver(e);
		objThis.show();
	}

	function onTimeOut(evt) {
		clearTimer();
		setOver(null);
		if (objThis.popup)
			objThis.hide();
		else
			objThis.show();
	}

	function onMouseOut(evt) {
		objThis.objTimer = window.setInterval(onTimeOut, 1200);
	}

};

//
clsMenu.prototype.isSelected = function (e) {
	for (var i=0; this.arrSelected && i<this.arrSelected.length; i++)
		if (e == this.arrSelected[i])
			return true;
	return false;
};

//
clsMenu.prototype.isOver = function (e) {
	for (var i=0; this.arrOver && i<this.arrOver.length; i++)
		if (e == this.arrOver[i])
			return true;
	return false;
};

// Hide the menu
clsMenu.prototype.hide = function () {
	if (!this.elMenu) return;
	this.elMenu.style.visibility='hidden';
}

// Set the state of all menus
clsMenu.prototype.showPopup = function (x,y) {
	if (!this.elMenu) return;
	this.elMenu.style.left=x;
	this.elMenu.style.top=y;
	this.popup = true;
	this.show();
}

// Set the state of all menus
clsMenu.prototype.show = function () {
	if (!this.elMenu) return;
	objThis = this;
	this.elMenu.style.visibility='visible';

	xWalkTree(this.elMenu,
		function (e) {
			if ( e.tagName == 'A' )
			{
				if ( !objThis.topStatic || !isTopLevel(e) )
				{
					if ( objThis.isOver(e) )
					{
						setClassxx(e, getClassxx(e.className,'o'))
					}
					else if ( objThis.isSelected(e) )
						setClassxx(e, getClassxx(e.className,'s'))
					else
						setClassxx(e, getClassxx(e.className,'n'))
				}
			}
			else if ( e.tagName == 'DIV' )
			{
				if ( strMatch(e.className,'subMenu' ) )
				{
					if ( objThis.isOver(e) )
					{
						e.style.visibility='visible'
					}
					else
						e.style.visibility='hidden';
				}
			}
		}
	);
};


/******* x - cross-browser JavaScript ***********/

// From x_event.js
function xEvent(evt) { // cross-browser event object prototype
  this.type = '';
  this.target = null;
  this.pageX = 0;
  this.pageY = 0;
  this.offsetX = 0;
  this.offsetY = 0;
  this.keyCode = 0;
  var e = evt ? evt : window.event;
  if(!e) return;
  if(e.type) this.type = e.type;
  if(e.target) this.target = e.target;
  else if(e.srcElement) this.target = e.srcElement;
  if(xOp5or6) { this.pageX = e.clientX; this.pageY = e.clientY; }
  else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }
  if(xDef(e.offsetX,e.offsetY)) { this.offsetX = e.offsetX; this.offsetY = e.offsetY; }
  else { this.offsetX = this.pageX - xPageX(this.target); this.offsetY = this.pageY - xPageY(this.target); }
  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
  else if (xDef(e.which)) { this.keyCode = e.which; }
}

function xAddEventListener(e,eventType,eventListener,useCapture) {
  if(!(e=xGetElementById(e))) return;
  eventType=eventType.toLowerCase();
  if((!xIE4Up && !xOp7) && e==window) {
	if(eventType=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eventListener; xResizeEvent(); return; }
	if(eventType=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eventListener; xScrollEvent(); return; }
  }
  var eh='e.on'+eventType+'=eventListener';
  if(e.addEventListener) e.addEventListener(eventType,eventListener,useCapture);
  else if(e.attachEvent) e.attachEvent('on'+eventType,eventListener);
  else if(e.captureEvents) {
	if(useCapture||(eventType.indexOf('mousemove')!=-1)) { e.captureEvents(eval('Event.'+eventType.toUpperCase())); }
	eval(eh);
  }
  else eval(eh);
}

// From x_dom.js
/* xWalkTree()
   Perform a preorder traversal
   on the subtree starting at oNode
   and pass each Element node to fnVisit.
*/
function xWalkTree(oNode, fnVisit)
{
  if (oNode) {
	if (oNode.nodeType == 1) {fnVisit(oNode);}
	for (var c = oNode.firstChild; c; c = c.nextSibling) {
	  xWalkTree(c, fnVisit);
	}
  }
}

/* xGetElementsByTagName()
   Returns an array of elements which are
   descendants of parentEle and have tagName.
   If parentEle is null or not present, document will be used.
   if tagName is null or not present, "*" will be used.
*/
function xGetElementsByTagName(tagName, parentEle)
{
	var list = null;
  tagName = tagName || '*';
  parentEle = parentEle || document;
  if (xIE4 || xIE5) {
	if (tagName == '*') list = parentEle.all;
	else list = parentEle.all.tags(tagName);
  }
  else if (parentEle.getElementsByTagName) list = parentEle.getElementsByTagName(tagName);
  return list || new Array();
}

// From x_core.js
// Variables:
var xVersion='3.15.1',xNN4=false,xOp7=false,xOp5or6=false,xIE4Up=false,xIE4=false,xIE5=false,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  xOp7=(xUA.indexOf('opera 7')!=-1 || xUA.indexOf('opera/7')!=-1);
  if (!xOp7) xOp5or6=(xUA.indexOf('opera 5')!=-1 || xUA.indexOf('opera/5')!=-1 || xUA.indexOf('opera 6')!=-1 || xUA.indexOf('opera/6')!=-1);
}
else if (document.all) {
  xIE4Up=xUA.indexOf('msie')!=-1 && parseInt(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
}
// Object:
function xGetElementById(e) {
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}
function xDef() {
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}
function xPageX(e) {
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
	if (xDef(e.offsetLeft)) x += e.offsetLeft;
	e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}
function xPageY(e) {
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
	if (xDef(e.offsetTop)) y += e.offsetTop;
	e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324
  return y;
}
function xScrollLeft(e) {
  var offset=0;
  if (!(e=xGetElementById(e))) {
	if(document.documentElement && document.documentElement.scrollLeft) offset=document.documentElement.scrollLeft;
	else if(document.body && xDef(document.body.scrollLeft)) offset=document.body.scrollLeft;
  }
  else { if (xNum(e.scrollLeft)) offset = e.scrollLeft; }
  return offset;
}
function xScrollTop(e) {
  var offset=0;
  if (!(e=xGetElementById(e))) {
	if(document.documentElement && document.documentElement.scrollTop) offset=document.documentElement.scrollTop;
	else if(document.body && xDef(document.body.scrollTop)) offset=document.body.scrollTop;
  }
  else { if (xNum(e.scrollTop)) offset = e.scrollTop; }
  return offset;
}
