/**
 * 
 * DHTML Menuing System v1.0a
 *
 * Copyright (C) Noggin 2001
 * http://www.noggin.com.au/
 *
 * Supported Browsers (* To Be Tested): 
 *	     Netscape 4.xx (Win, Mac, Linux, FreeBSD, Solaris x86*), 
 *           IE 4.xx (Win*), 
 *           IE 5.xx (xx < 5) (Win, Mac),
 *           IE 5.5x (Win, Mac*)
 *           Netscape 6.xx / Mozilla (Win*, Mac*, Linux*, FreeBSD*, Solaris x86*)
 * 
 * Successfully tested browsers
 *           Netscape (Mac 4.05, Mac 4.7, Win 4.73, Win 4.72, Linux 4.72, FreeBSD 4.73)
 *           IE (Mac 5, Win 5, Win 5.5)
 *
 */


//----------------------------------------- Global Variables ------------------------------------------

// Configuration
var nogmnu_offsetx = 0;
var nogmnu_offsety = 0;

// State & Browser Detect info
var nogmnu_visible  = 'visible';
var nogmnu_hidden   = 'hidden';
var nogmnu_stack    = new Array();
var nogmnu_rootpane = getLayerById('rootpane');	
var nogmnu_openroot = null;

//--------------------------------------------- Code --------------------------------------------------

function push(item, stack) {
	stack[stack.length] = item;
}


function pop(stack) {
	var item = stack[stack.length-1];
	delete stack[stack.length-1];
	stack.length = stack.length - 1;
	return item;
}


function top(stack) {
	if (stack && stack.length > 0)
		return stack[stack.length-1];
	else
		return null;
}

function menuItem(item, menu, child) {						// menuItem object constructor
	this.item = item;
	this.menu = menu;
	this.oldsrc = item.src;
	this.child = child;
}


function findMenu(menu, stack) {
	for (var i=0; i<stack.length; i++) {
		if (menu == stack[i].menu) return i;
	}
	return -1;
}


function oM(item, menu, child, direction, highlightsrc, menurootid) {
	menu  = getLayerById(menu);
	child = getLayerById(child);
	overMenuItemInternal(item, menu, child, direction, highlightsrc, menurootid);
}

function overMenuItemInternal(item, menu, child, direction, highlightsrc, menurootid) {
	
	showRootPane();

	
	var menu_item    = null;
	var idx          = 0;
	var top_of_stack = top(nogmnu_stack);
	
	if ((menurootid != null) && (nogmnu_openroot != menurootid)) {
		if (top_of_stack)
			hM();
		nogmnu_openroot = menurootid;
	}
		
	if (top_of_stack && top_of_stack.item == item) return;	// This is a duplicate event

	if (top_of_stack && top_of_stack.menu == menu) {
		// In the current menu
		menu_item = pop(nogmnu_stack);
		hideMenu(menu_item.child);		
		menu_item.item.src = menu_item.oldsrc;
		
		push(new menuItem(item, menu, child), nogmnu_stack);
		item.src = highlightsrc;
		if (placeMenu(item, menu, child, direction))
			showMenu(child);
		
	} else if (top_of_stack && (idx = findMenu(menu, nogmnu_stack)) >= 0) {
		
		for (i=(nogmnu_stack.length-idx); i>1; i--) {
			menu_item = pop(nogmnu_stack);
			hideMenu(menu_item.child);
			menu_item.item.src = menu_item.oldsrc;
		}
		
		// Call again, menu is now the current menu
		overMenuItemInternal(item, menu, child, direction, highlightsrc, menurootid);
				
	} else {
		// In a child menu
		
		push(new menuItem(item, menu, child), nogmnu_stack);
		item.src = highlightsrc;
		if (placeMenu(item, menu, child, direction))
			showMenu(child);

	}
}


function hM() {
	
	hideRootPane();
	
	var menu_item = null;
	
	while (nogmnu_stack && nogmnu_stack.length > 0) {
		menu_item = pop(nogmnu_stack);
		hideMenu(menu_item.child);
		menu_item.item.src = menu_item.oldsrc;
	}
}


function showRootPane() {
	var clientsize = getClientSize();
	setLayerPosition(nogmnu_rootpane, 0, 0);
	setLayerSize(nogmnu_rootpane, clientsize[0], clientsize[1]);
	showMenu(nogmnu_rootpane);
}

function hideRootPane() {
	hideMenu(nogmnu_rootpane); 
}


function showMenu(menu) {
	if (menu && menu.style && menu.style.visibility != nogmnu_visible) {
		menu.style.visibility = nogmnu_visible;
	} else if (menu && menu.visibility != nogmnu_visible) {
		menu.visibility = nogmnu_visible;
	}
}


function hideMenu(menu) {
	if (menu && menu.style && menu.style.visibility != nogmnu_hidden) {
		menu.style.visibility = nogmnu_hidden;
	} else if (menu && menu.visibility != nogmnu_hidden) {
		menu.visibility = nogmnu_hidden;
	}
}


function getImageById(img_id) {
	return document[img_id];
}


function getLayerById(lyr_id) {
	if (document.layers) {
		return document.layers[lyr_id];
	} else  if (document.all) {
		return document.all[lyr_id];
	} else {
		return document.getElementById(lyr_id);
	}
}



	
function placeMenu(refitem, parent, child, direction) {

	var refpos     = getImagePosition(refitem);
	var refsize    = getImageSize(refitem);
	var parentpos  = getPagePosition(parent);
	var parentsize = getLayerSize(parent);
	var menusize   = getLayerSize(child);
	var windowsize = getClientSize();
	var scrollpos   = getScrollPosition();
	
	if (!refpos || !refsize || !parentpos || !parentsize || !menusize || !windowsize || !scrollpos) return false;
	
	var x0 = parentpos[0] + refpos[0];
	var y0 = parentpos[1] + refpos[1] - menusize[1];
	var x1 = parentpos[0] + refpos[0] + refsize[0] - nogmnu_offsetx;
	var y1 = parentpos[1] + refpos[1] + nogmnu_offsety;
	var x2 = x0;
	//alert('x2 = '+parentpos[0]+ ' + ' +refpos[0]);
	var y2 = parentpos[1] + refpos[1] + refsize[1];
	var x3 = parentpos[0] + refpos[0] - menusize[0] + nogmnu_offsetx;
	var y3 = y1;

	switch (direction) {
		case 0:
			if ((y0 < scrollpos[1]) && (y2 + menusize[1] < windowsize[1] + scrollpos[1]))
				y = y2;
			else
				y = y0;
			
			if ((x0 + menusize[0] > windowsize[0] - scrollpos[0]) && (x0 + refsize[0] - menusize[0] > scrollpos[0])) {
				x = x0 + refsize[0] - menusize[0];
			} else
				x = x0;
			break;
		case 1:
			if ((x1 + menusize[0] > windowsize[0] + scrollpos[0]) && (x3 > scrollpos[0]))
				x = x3;
			else
				x = x1;
			
			if (y1 + menusize[1] + scrollpos[1] > windowsize[1]) {
				if (menusize[1] > windowsize[1])
					y = scrollpos[1];
				else
					y = windowsize[1] - menusize[1] + scrollpos[1];
			} else {
				y = y1;
			}
			break;
		case 2:
			if ((y2 + menusize[1] > windowsize[1] + scrollpos[1]) && (y0 > scrollpos[1]))
				y = y0;
			else
				y = y2;
			
			if ((x2 + menusize[0] > windowsize[0] + scrollpos[0]) && (x2 + refsize[0] - menusize[0] > scrollpos[0]))
				x = x2 + refsize[0] - menusize[0];
			else
				x = x2;
			break;


		case 3:
			if ((x3 < scrollpos[0]) && (x1 + menusize[0] < windowsize[0] + scrollpos[0]))
				x = x1;
			else
				x = x3;

			if (y3 + menusize[1] + scrollpos[1] > windowsize[1]) {
				if (menusize[1] > windowsize[1])
					y = scrollpos[1];
				else
					y = windowsize[1] - menusize[1] + scrollpos[1];
			} else {
				y = y3;
			}
			break;
		
	}
	
	setLayerPosition(child, x, y);
	return true;
}


function getPagePosition(obj) {

	if (obj) {
		if (obj.pageX >= 0 || obj.pageY >= 0) {
	
			return new Array(obj.pageX, obj.pageY);
			
		} else if (obj.x >= 0 || obj.y >= 0) {
	
			return new Array(obj.x, obj.y);
	
		} else {
	
			var pageX = obj.offsetLeft;
			var pageY = obj.offsetTop;
			var tmp = obj.offsetParent; 
	
			while (tmp && tmp != document.body) { 
	
				if (tmp.offsetLeft) pageX += tmp.offsetLeft; 
				if (tmp.offsetTop) pageY += tmp.offsetTop;
				tmp = tmp.offsetParent;
	
			} 
	
			if (tmp.offsetLeft) pageX += tmp.offsetLeft; 
			if (tmp.offsetTop) pageY += tmp.offsetTop;
			
			if (navigator.platform.indexOf('Mac') != -1) {
				if (document.body.leftMargin > 0) pageX += parseInt(document.body.leftMargin);
				if (document.body.topMargin  > 0) pageY += parseInt(document.body.topMargin );
			}
	
			return new Array(pageX, pageY); 
		}
	}
}

function getImagePosition(obj) {

	if (obj) {
		if (obj.x >= 0 || obj.y >= 0) {
			return new Array(obj.x, obj.y);
		} else {
			return new Array(obj.offsetLeft, obj.offsetTop);
		}
	}
}

function getImageSize(img) {
	if (img) {
		if (img.offsetWidth || img.offsetHeight) {
			return new Array(img.offsetWidth, img.offsetHeight);
		} else {
			return new Array(img.width, img.height);	
		}	
	}
}

function getLayerSize(lyr) {
	if (lyr) {
		if (lyr.offsetWidth || lyr.offsetHeight) {
			return new Array(lyr.offsetWidth, lyr.offsetHeight);
		} else {
			return new Array(lyr.clip.width, lyr.clip.height);	
		}
	}
}

function getClientSize() {
	if (window.innerHeight || window.innerWidth) {
		return new Array(window.innerWidth, window.innerHeight);
	} else {
		return new Array(document.body.clientWidth, document.body.clientHeight);
	}
}

function getScrollPosition() {
	if (window.pageYOffset >= 0 || window.pageXOffset >= 0) {
		return new Array(window.pageXOffset, window.pageYOffset);
	} else {
		return new Array(document.body.scrollLeft, document.body.scrollTop);	
	}
}


function setLayerPosition(lyr, x, y) {
	if (lyr) {
		if (lyr.pageX >= 0 || lyr.pageY >= 0) {
			lyr.pageX = x;
			lyr.pageY = y;
		} else {
			lyr.style.top  = y;
			lyr.style.left = x;
		} 
	}
}

function setLayerSize(lyr, width, height) {
	if (lyr.clip) {
		lyr.clip.width = width;
		lyr.clip.height = height;	
	} else {
		lyr.style.width = width;
		lyr.style.height = height;
	}
}

function alignMenuToImage(menu, img) {
	menu = getLayerById(menu);
	img  = getImageById(img );
	if (menu && img) {
		var img_pos = getPagePosition(img);
		setLayerPosition(menu, img_pos[0], img_pos[1]);
		showMenu(menu);
	}
}
		
