/***********************************************/
/* PopMenu 1.0                                 */
/* Publish Date: 3/9/2007                      */
/***********************************************/

// constants and globals
var pm_menuCache = new Array(), pm_itemCache = new Array(), pm_frameCache = new Array();
var pm_eventCache = new Array();
var pm_createFrames = null, pm_timer = null;

// editable variables
var pm_class = "active";
var pm_zIndex = 1000, pm_delay = 500;

// make sure that the basic stack functions are in place
if (Array.push == null)
{
	Array.prototype.push = function()
	{
		for (var i=0; i<arguments.length; i++)
			this[this.length] = arguments[i];
		return this.length;
	};

	Array.prototype.pop = function()
	{
		var el = this[this.length - 1];
		this.length--;
		return el;
	};
}

function pm_activate(el)
{
	// make the given element "active" by class
	var classes = el.className != "" ? el.className.split(" ") : new Array();
	classes.push(pm_class);
	el.className = classes.join(" ");
}

function pm_deactivate(el)
{
	// make the given element "inactive" by class
	var classes = el.className.split(" ");
	var newClasses = new Array();
	
	for (var i=0; i<classes.length; i++)
		if (classes[i] != "" && classes[i] != pm_class)
			newClasses.push(classes[i]);
	el.className = newClasses.join(" ");
}

function pm_find(el)
{
	// find and apply a transition for the given element
	if (el.filters != null)
	{
		for (var t in el.filters)
		{
			if (t == "length") continue;
			if (el.filters[t].duration)
			{
				el.filters[t].apply();
				return t;
			}
		}
	}
	return "";
}

function pm_play(el, t)
{
	// play the given filter for the given element
	if (t != "") el.filters[t].play();
}

function pm_reset(level)
{
	// set menu visibility by hierarchy level
	pm_stop();
	for (var i=pm_menuCache.length-1; i>=level; i--)
	{
		var menu = pm_menuCache.pop();
		var item = pm_itemCache.pop();
		
		var t = pm_find(menu);
		menu.style.visibility = "hidden";
		if (pm_createFrames) pm_frameCache[i].style.visibility = "hidden";
		pm_play(menu, t);
		pm_deactivate(item);
		if (item.rel != "") eval(item.rel);
	}
}

function pm_coords(el)
{
	// return the cumulative offset position of the given element
	var l = 0, t = 0;
	while (el)
	{
		l += el.offsetLeft || 0;
		t += el.offsetTop || 0;
		
		if ((/KHTML|Konqueror|Safari/.test(navigator.userAgent) || window.opera)
			&& el.offsetParent == document.body
			&& pm_style(el, "position") == "absolute")
			break;
		el = el.offsetParent;
	}
	return [l, t];
}

function pm_style(el, prop)
{
	// return the value of the given style property whether it's inline or global
	var camelized = prop.replace(/\-([a-z])/gi, function(m, a) { return a.toUpperCase(); });
	var val = el.style[camelized];
	
	if (!val)
	{
		if (document.defaultView && document.defaultView.getComputedStyle)
		{
			var css = document.defaultView.getComputedStyle(el, null);
			val = css ? css.getPropertyValue(prop) : null;
		}
		else if (el.currentStyle)
			val = el.currentStyle[camelized];
	}
	return val;
}

function pm_page()
{
	// create an object to hold the properties
	var page = new Object();
	page.viewHeight = page.viewWidth = page.scrollX = page.scrollY = page.height = page.width = 0;
	
	if (window.innerHeight)
	{
		// get the properties for Firefox, Opera, etc.
		page.viewHeight = window.innerHeight;
		page.viewWidth = window.innerWidth;
		page.scrollX = window.pageXOffset;
		page.scrollY = window.pageYOffset;
		page.height = document.documentElement.offsetHeight;
		page.width = document.documentElement.offsetWidth;
	}
	else if (document.compatMode && document.compatMode != "BackCompat")
	{
		// get the properties for Internet Explorer strict mode
		page.viewHeight = document.documentElement.clientHeight;
		page.viewWidth = document.documentElement.clientWidth;
		page.scrollX = document.documentElement.scrollLeft;
		page.scrollY = document.documentElement.scrollTop;
		page.height = document.documentElement.scrollHeight;
		page.width = document.documentElement.scrollWidth;
	}
	else
	{
		// get the properties for Internet Explorer normal mode
		page.viewHeight = document.body.clientHeight;
		page.viewWidth = document.body.clientWidth;
		page.scrollX = document.body.scrollLeft;
		page.scrollY = document.body.scrollTop;
		page.height = document.body.scrollHeight;
		page.width = document.body.scrollWidth;
	}
	
	// make sure the page's height and width aren't zero
	if (page.viewHeight > page.height) page.height = page.viewHeight;
	if (page.viewWidth > page.width) page.width = page.viewWidth;
	return page; // return the created object
}

function pm_show(el, level, id, ox, oy)
{
	// 1. make sure the menus stay visible
	// 2. get the starting coordinates and menu reference
	pm_stop();
	var coords = pm_coords(el);
	var menu = document.getElementById(id);
	if (pm_menuCache[level] == menu) return;
	
	// 1. set the menus to the current hierarchy level
	// 2. put the active menu and item in their respective arrays
	pm_reset(level);
	pm_menuCache[level] = menu;
	pm_itemCache[level] = el;
	
	// set the menu's coordinates and stacking level
	menu.style.left = (coords[0] + ox) + "px";
	menu.style.top = (coords[1] + oy) + "px";
	menu.style.zIndex = pm_zIndex;
	
	// adjust the menu's coordinates for page dimensions
	var page = pm_page();
	if (menu.offsetLeft + menu.offsetWidth > page.viewWidth + page.scrollX)
		menu.style.left = (coords[0] - ox) + "px";
	if (menu.offsetTop + menu.offsetHeight > page.viewHeight + page.scrollY)
		menu.style.top = (coords[1] - oy) + "px";
	
	// 1. show the menu with a transition (if applicable)
	// 2. "activate" the given item
	var t = pm_find(menu);
	menu.style.visibility = "visible";
	pm_play(menu, t);
	pm_activate(el);
	
	if (!pm_createFrames)
	{
		// determine whether or not to apply the iframe fix for Windows IE 5 to 6
		var ua = navigator.userAgent.toLowerCase();
		if (ua.indexOf("msie") > -1 && ua.indexOf("mac_powerpc") == -1)
		{
			var version = parseFloat(ua.substr(ua.indexOf("msie") + 5, 3));
			if (version < 7)
				pm_createFrames = true;
			else
				pm_createFrames = false;
		}
		pm_createFrames = false;
	}
	
	if (pm_createFrames)
	{
		if (pm_frameCache.length - 1 < level)
		{
			// create a new underlay frame if it's not available for this hierarchy level
			var iframe = document.createElement("iframe");
			iframe.src = "about:blank";
			iframe.border = iframe.frameBorder = 0;
			iframe.style.visibility = "hidden";
			iframe.style.position = "absolute";
			iframe.style.left = iframe.style.top = iframe.style.height = iframe.style.width = "0px";
			iframe.style.zIndex = pm_zIndex - 1;
			iframe.style.filter = "alpha(opacity=0)";
			document.body.appendChild(iframe);
			pm_frameCache.push(iframe);
		}
		
		// set up this level's frame to be an underlay to the current menu
		pm_frameCache[level].style.left = menu.offsetLeft + "px";
		pm_frameCache[level].style.top = menu.offsetTop + "px";
		pm_frameCache[level].style.height = menu.offsetHeight + "px";
		pm_frameCache[level].style.width = menu.offsetWidth + "px";
		pm_frameCache[level].style.visibility = "visible";
	}
}

function pm_start()
{
	// start the hide timer
	pm_timer = setTimeout("pm_reset(0)", pm_delay);
}

function pm_stop()
{
	// clear the hide timer
	clearTimeout(pm_timer);
}
