// ========================================================
// VERSION 1.1 Aug 8, 2001
// Author	Doug Houghton doug_houghton@sympatico.ca
// I, nor any member or assosciate of paraknowya.com,
// take any responsibility whatsoever for this scripts q
// uality, reliability or accuracy.  
// ========================================================
//
// function librarie for client side building and
// execution of a menuing system
var GET_ID = 1;
var GET_ALL = 2;

var INSERT_HTML = 1;
var CREATE_RANGE = 2;

var BODY_SCROLL = 1;
var PAGE_OFFSET = 2;

var SUBMENU_PADDING = "5";
var SUBMENU_COLOUR = "#f5f5f5";
var SUBMENU_BORDER = "1";
var SUBMENU_BORDER_COLOUR = "#dddddd";
var SUBMENU_SUFFIX = "_sm"; // don't use '_sm' at the end of a tags id
var lastMenuId;

// checks for needed browser support
function validate(id)
{
	var menu;
	var getEl;
	var insEl;
	var scroll;

	if (!document.body)
		return(0);

	if (!document.body.removeChild)
		return(0);

	if (!(document.body.getAttribute && document.body.setAttribute))
		return(0);

	if (!(document.getElementById || document.all))
		return(0);
	
	if (!(document.body.insertAdjacentHTML || document.createRange))
		return(0);

	if (document.body.scrollTop || (document.body.scrollTop == 0))
		return(1);
	else
		if (window.pageXOffset || (window.pageXOffset==0))
			return(1);
		else
			return(0);
}

function getScroll()
{
	if (document.body.scrollTop || (document.body.scrollTop == 0))
		return(BODY_SCROLL);
	else
		return(PAGE_OFFSET);
}

// ============== define Menu ============
// find the parent based on the id and inserts 
// a div absolutely posotiuons into the doc that 
// will contain menu commands provided by calling 
// addSubMenu
// ---------------------------------
function defineMenu(id)
{
	var menu;
	var subMenuHTML;
	var range;
	var scroll;
	var getEl;

	// get some properties of the broswer to pass as event arguments
	if (document.getElementById)
	{
		menu = document.getElementById(id);
		getEl = GET_ID;
	}
	else
	{
		menu = document.all[id];
		getEl = GET_ALL;
	}

	if (document.body.insertAdjacentHTML)
		insEl = INSERT_HTML;
	else
		insEL = CREATE_RANGE;

	scroll = getScroll();

	// open the div tag
	subMenuHTML = "<DIV id='" + id + SUBMENU_SUFFIX + "'";
	subMenuHTML += " style='position:absolute;top:0;";
	subMenuHTML += "background-color:" + SUBMENU_COLOUR + ";";
	subMenuHTML += "padding:" + SUBMENU_PADDING + "px;";
	subMenuHTML += "border-width:" + SUBMENU_BORDER + "px;";
	subMenuHTML += "border-style:solid;";
	subMenuHTML += "border-color:" + SUBMENU_BORDER_COLOUR + ";";
	subMenuHTML += "visibility:hidden;'" ;
	subMenuHTML += " onmouseout='onMenuExit(this, event, " + getEl + ", " + scroll + ");'";
	subMenuHTML += " owner='" + id + "'";
	subMenuHTML += " showing='0'";
	subMenuHTML += " ></DIV>";



	if (document.body.insertAdjacentHTML)
		document.body.insertAdjacentHTML("beforeEnd", subMenuHTML);
	else
	{
		// netscape
		range = document.createRange();
		range.setStartBefore (menu);
		document.body.appendChild(range.createContextualFragment(subMenuHTML));
	}

	menu.setAttribute("onMouseOut", "onMenuExit(this, event, " + getEl + ", " + scroll + ");");
	menu.setAttribute("onmouseover", "onMenuEnter(this, " + getEl + ");");


	// IE needs a kick to hook up the menus
	if (menu.outerHTML)
		menu.outerHTML = menu.outerHTML;
}

// ================ Remove ================
// adds a submenu to a defined submenu group
// uses the id of the parent and adds the submenu 
// prefix to fins the child menu command container (DIV)
// --------------------------------
function addSubMenu(menuId, caption, url)
{
	
	var commandHTML;
	var subMenu;
	var menu;
	var range;

	// build the anchor
	if (url.length)
		commandHTML = "<a href='" + url + "'>" + caption + "</a>";
	else
		commandHTML = caption;
			
	// get the submenudiv
	if (document.getElementById)
		subMenu = document.getElementById(menuId + SUBMENU_SUFFIX);
	else
		subMenu = document.all[menuId + SUBMENU_SUFFIX];

	// add a preceding breaj if this isn't the first link
	if (subMenu.firstChild)
		commandHTML = "<BR>" + commandHTML;

	if (document.body.insertAdjacentHTML)
	{
		subMenu.insertAdjacentHTML("beforeEnd", commandHTML);
	}
	else
	{	// netscape
		range = document.createRange();
		range.setStartBefore(subMenu);
		subMenu.appendChild(range.createContextualFragment(commandHTML));
	}
		
}


// note tha this function will remove all 
// instances of the id not just the first
function remove(id)
{
	var cull;
	
	if (document.getElementById)
		cull = document.getElementById(id);
	else
		cull = document.all[id];

	while(cull)
	{		
		if (cull.outerHTML)
			cull.outerHTML = "";
		else
			cull.parentNode.removeChild(cull);

		if (document.getElementById)
			cull = document.getElementById(id);
		else
			cull = document.all[id];
	}
}


function onMenuEnter(menu, getEl)
{
	var subMenu;

	if (getEl == GET_ID)
		subMenu = document.getElementById(menu.id + SUBMENU_SUFFIX);
	else
		subMenu = document.all[menu.id + SUBMENU_SUFFIX];
	
	if (subMenu.getAttribute("showing")==0)
	{
		killMenu(lastMenuId);
		subMenu.style.top = subMenuTop(menu);
		subMenu.style.left = getLeft(menu) - SUBMENU_PADDING - SUBMENU_BORDER;
		subMenu.setAttribute("showing", "1");
		subMenu.style.visibility = "visible";
		lastMenuId = subMenu.id;
	}	
}

function onMenuExit(obj, e, getEl, scroll)
{
	var menu;
	var subMenu;
	var scrLeft;
	var scrTop;

	if (obj.getAttribute("owner"))
	{
		subMenu = obj;
		if (getEl == GET_ID)
			menu = document.getElementById(obj.getAttribute("owner"));
		else
			menu = document.all[obj.getAttribute("owner")];
	}
	else
	{
		menu = obj;
		if (getEl == GET_ID)
			subMenu = document.getElementById(obj.id + SUBMENU_SUFFIX);
		else
			subMenu = document.all[obj.id + SUBMENU_SUFFIX];

	}

	if (scroll == BODY_SCROLL) 
	{
		scrLeft = document.body.scrollLeft;
		scrTop = document.body.scrollTop;
	}
	else
	{
		scrLeft = pageXOffset;
		scrTop = pageYOffset;
	}
	
	if (document.body.clientLeft)
	{
		scrLeft -= document.body.clientLeft;
		scrTop -= document.body.clientTop;
	}

	if (inBounds(e.clientX + scrLeft , e.clientY + scrTop , menu, subMenu))
		return(0);


	subMenu.style.visibility = "hidden";
	subMenu.setAttribute("showing", "0");
	
}

function killMenu(id)
{
	var menu;

	if (document.getElementById)
		menu = document.getElementById(id);
	else
		menu = document.all[id];
	
	if (menu)
	{
		menu.style.visibility = "hidden";
		menu.setAttribute("showing", "0");
	}
}

// ================= In Bounds =================
// check if the curser is within the top menu and it's submenu
// add a single pixel margin of error
// return true if the curser (mouse) is within the mening system
// under netscape the DIV border doesn't get included in the 
// getTop and getLeft calculations.
// add a pixel of buffer for testing the main menu
// ------------------------------------
function inBounds(x, y, menu, subMenu)
{

	if (y < parseInt(subMenu.style.top))	
	{
		if ((x - 1) <= getLeft(menu))
			return(0);

		if ((x + 1) >= getRight(menu))
			return(0);
								
		if ((y - 1) <= getTop(menu))
			return(0);
	}
	else
	{		
		if (x <= parseInt(subMenu.style.left))
			return(0);

		if (x >= (parseInt(subMenu.style.left) + subMenu.offsetWidth))
			return(0);
		
		if (y >= (parseInt(subMenu.style.top) + subMenu.offsetHeight))
			return(0);
	}
	return(1);
}

// ============ sub menu top =============
// returns the top coordinate where the 
// sub menu should be placed.
// this function may require occasional 
// revision if the page layout changes.
// it looks for a TD enclosing the menu 
// and returns the bottom of it + 1
// ----------------------------------
function subMenuTop(menu)
{
	var parent;
	var i=0;
	var rv = 0;

	parent = menu.parentNode;
	while (parent && (i < 3))
	{
		if (parent.tagName.toUpperCase() == "TD")
		{
			rv = getBottom(parent) + 1;

			// IE - I still don't know exactly where
			// the sizes are coming from
			if (document.body.clientTop)
				rv += document.body.clientTop - 2;

			break;
		}
		i++;
		parent = parent.parentNode;
	}
	
	// right now the above loop should find a table data tag
	// if the website design should change, this check should ensure 
	// that at least some kind of menu appears
	if (rv)
		return(rv);
	else
		return(getBottom(parent) + 4);
}

function getTop(obj)
{	
	var rv = 0;

	while(obj)
	{
		rv += obj.offsetTop;
		obj = obj.offsetParent;
	}

	return(rv);
}

function getLeft(obj)
{	
	var rv = 0;

	while(obj)
	{
		rv += obj.offsetLeft;	
		obj = obj.offsetParent;
	}
	return(rv);
}

function getRight(obj)
{
	return(getLeft(obj) + obj.offsetWidth);
}

function getBottom(obj)
{
	return(getTop(obj) + obj.offsetHeight);
}