if (typeof(MENUHANDLER) != 'boolean') {

var MENUHANDLER = true;

var menuHandler = {
	menus : new Array(),
	target : null,	// the CM div id="cMenu"
	submenu : null,	// the submenu div id="cMenuSubmenu"
	currMenu : null,
	currSubmenu : null,
	keepOpen : false,
	initialWidth : 0,
	currSubstitutionText : "",
	submenuTimerCloseId : 0,	// the timeoutId of the closeSubmenu function
	submenuTimerShowId : 0,
	/**
	*	menuHandler.createTarget()
	*
	*	this creates a div as the last element in the body tag
	*	this *must* be called before any rendering of the context menus
	*	this *must* be called after the body has finished loading
	*	eg:
	*
	*	function init() {
	*		menuHandler.createTarget();
	*	}
	*	<body onload="init()">
	*/
	createTarget : function () {
		this.target = document.createElement('div');
		this.target.id = "cMenu";
		this.target.className = "cMenu";
		this.target.style.position = "absolute";	// this could be done in the CSS, but it's better to make sure here.
		this.initialWidth = this.target.style.width;
		hide(this.target);
		document.body.appendChild(this.target);

		this.submenu = document.createElement('div');
		this.submenu.id = "cMenuSubmenu";
		this.submenu.className = "cMenu";
		this.submenu.style.position = "absolute";	// this could be done in the CSS, but it's better to make sure here.
		this.submenu.style.display = "none";
		this.submenu.onmouseover = cancelSubmenuClose;
		this.submenu.onmouseout = closeSubmenu;
		hide(this.target);
		document.body.appendChild(this.submenu);
	},

	showMenu : function (menuId, subText) {
		if (this.target) {					// this.target will be null if the page hasn't finished loading yet because the body.onload() (which creates this.target) hasn't been called
			this.currSubstitutionText = subText;			// need to remember this for the submenus
			if (typeof menuId == "string") {
				menuId = this.getMenuIdByName(menuId);		// a string (name) has been passed in for the display, so lets find the menu with that name and get the id.
			}
			this.keepOpen = true;		// this is to prevent the menu being immediately closed after opening
			hide(this.submenu);
			this.currMenu = menuId;
			this.setWidth(this.menus[menuId].width);
			this.target.innerHTML = this.menus[menuId].draw(subText);
			show(this.target);
		}
	},

	hideMenu : function () {
		if (this.currMenu != null && !this.keepOpen) {
			this.currMenu = null;
			hide(this.target);
			hide(this.submenu);
		}

		this.keepOpen = false;
	},
	hideSubmenu : function () {
		hide(this.submenu);
	},

	addMenu : function (menu) {
		this.menus.push(menu);
	},
	addMenus : function (menuArray) {
		for (x in menuArray) {
			this.menus.push(menuArray[x]);
		}
	},

	getMenuIdByName : function (name) {
		for (x in this.menus) {
			if (this.menus[x].name == name) return x;
		}
	},


	setWidth : function (newWidth) {
		if (newWidth == undefined || newWidth == null) {
			this.resetWidth();
		} else {
			this.target.style.width = parseInt(newWidth) + "px";
		}
	},
	resetWidth : function () {
		this.target.style.width = this.initialWidth;
	},

	// this is called when you click on something inside the menu and you DON'T want it to close the menu
	// ie: don't close the menu, and don't reposition to the cursor
	innerClick : function () {
		this.keepOpen = true;
		this.innerClicked = true;
	},

	// linkEl is the <a> element from which this submenu is going to display
	// it's needed so we can position the submenu properly
	showSubmenu : function (subId, linkEl) {
		if (this.submenuTimerCloseId != 0) {
			clearInterval(this.submenuTimerCloseId);
		}
		hide(this.submenu);
		this.currSubmenu = subId;
		this.positionSubmenu(linkEl);
	},

	positionSubmenu: function(linkEl) {
		var pos = getPos(linkEl);

		var newPos = {x : pos.x + linkEl.offsetWidth,
					  y : pos.y};

		this.populateSubmenu();						// must populate and show before
		this.submenu.style.visibility = "hidden";	// repositioning, since we need to know the calculated width, etc.
		this.submenu.style.top = this.submenu.style.left = "0";
		show(this.submenu);							// but we'll make it invisible so it doesn't flash for 1 frame at its last position


		var browserWidth = (this.ie && !window.opera) ? ietruebody().clientWidth - this.offsetxpoint
													  : window.innerWidth - this.offsetxpoint - 20;
		var browserHeight = (this.ie && !window.opera) ? ietruebody().clientHeight - this.offsetypoint
													  : window.innerHeight - this.offsetypoint - 20;
		//alert ("bw: " + browserWidth + "\nbh: " + browserHeight);
		if (this.submenu.offsetWidth > browserWidth) {	// submenu is wider than the browser
			newPos.x = 0;
		} else if (newPos.x + this.submenu.offsetWidth > browserWidth) {
			newPos.x = pos.x - this.submenu.offsetWidth;	// make it come from the left edge
		}
		var scrollY = (this.ie && !window.opera ? ietruebody().scrollTop : window.pageYOffset);
		if (this.submenu.offsetHeight > browserHeight) {
			newPos.y = 0;
		} else if (newPos.y + this.submenu.offsetHeight > browserHeight + scrollY) {
			newPos.y = browserHeight - this.submenu.offsetHeight + scrollY;
		}

		this.submenu.style.left =  newPos.x + "px";
		this.submenu.style.top = newPos.y + "px";
		this.submenu.style.visibility = "visible";
	},
	populateSubmenu : function () {
		this.submenu.innerHTML = this.menus[this.currMenu].submenus[this.currSubmenu].drawItems(this.currSubstitutionText);
	},

	// returns an object with properties "right", "bottom" and "left"
	getWindowEdges : function (e) {
		var rightedge = (this.ie && !window.opera) 	? ietruebody().clientWidth - event.clientX - this.offsetxpoint
													: window.innerWidth - e.clientX - this.offsetxpoint - 20;
		var bottomedge = (this.ie && !window.opera) ? ietruebody().clientHeight - event.clientY - this.offsetypoint
												  	: window.innerHeight - e.clientY - this.offsetypoint - 20;

		var leftedge = (this.offsetxpoint < 0) ? -this.offsetxpoint : -1000;
		return {"right" : rightedge, "bottom" : bottomedge, "left" : leftedge};
	},

	position : function(e) {
		//if (this.currMenu == null) return;			// don't need to reposition if it's not visible
		if (!this.target) return;
		if (this.innerClicked) {
			this.innerClicked = false;
			return;		// don't need to reposition if the user clicked on a toggle or submenu
		}

		var curX = (this.ns6) ? e.pageX : event.clientX + ietruebody().scrollLeft;
		var curY = (this.ns6) ? e.pageY : event.clientY + ietruebody().scrollTop;

		//alert ("Positioning to: " + curX + ", " + curY);
		//Find out how close the mouse is to the corner of the window
		var edges = this.getWindowEdges(e);

		//if the horizontal distance isn't enough to accomodate the width of the context menu
		if (edges.right < this.target.offsetWidth) {
			//move the horizontal position of the menu to the left by its width
			this.target.style.left = this.ie ? Math.max(0, ietruebody().scrollLeft + event.clientX - this.target.offsetWidth) + "px"
											 : Math.max(0, window.pageXOffset + e.clientX - this.target.offsetWidth) + "px";
		} else if (curX < edges.left) {
			this.target.style.left = "5px";
		} else {
			//position the horizontal position of the menu where the mouse is positioned
			this.target.style.left = Math.max(0, curX + this.offsetxpoint) + "px";
		}
		//same concept with the vertical position
		if (edges.bottom < this.target.offsetHeight) {
			this.target.style.top = this.ie ? Math.max(0, ietruebody().scrollTop + event.clientY - this.target.offsetHeight - this.offsetypoint) + "px"
											: Math.max(0, window.pageYOffset + e.clientY - this.target.offsetHeight - this.offsetypoint) + "px";
		} else {
			this.target.style.top = Math.max(0, curY + this.offsetypoint) + "px";
		}
		this.target.style.visibility = "visible";
	},
	clearFlags : function () {
		this.keepOpen = false;
	},
	init : function () {
		this.offsetxpoint = 0;
		this.offsetypoint = 0;
		this.ie = document.all;
		this.ns6 = document.getElementById && !document.all;
	}

} //end of menuHandler definition

menuHandler.init();
document.onclick = function (e) {
	menuHandler.hideMenu();
	menuHandler.position(e);
	setTimeout("menuHandler.clearFlags()", 100);
}
function showMenu (a, b) {
	menuHandler.showMenu(a, b);	// just an alias function name
}

function showSubmenu(subId, linkEl) {
	menuHandler.submenuTimerShowId = setTimeout("anotherShowSubmenuFunction(" + subId + ", '" + linkEl.id + "')", 300);
}
function anotherShowSubmenuFunction (subId, linkId) {
	menuHandler.showSubmenu(subId, getElement(linkId));
}
function closeSubmenu() {
	clearInterval(menuHandler.submenuTimerShowId);
	if (menuHandler.submenuTimerCloseId != 0) {
		clearInterval(menuHandler.submenuTimerCloseId);
	}
	menuHandler.submenuTimerCloseId = setTimeout(anotherCloseMenuFunction, 1000);
}
function anotherCloseMenuFunction () {

	menuHandler.hideSubmenu();
}
function cancelSubmenuClose() {
	if(menuHandler.submenuTimerCloseId != 0) {
		clearInterval(menuHandler.submenuTimerCloseId);
	}
	menuHandler.submenuTimerCloseId = 0;

}
/*if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", init, null);
}*/

} // end if not defined (line 1)

