/**
 *	A popup menu contains one or more menu items, possibly
 *	sub-menus, which link to pages, or perform other actions.
 *
 *	Menus are configurable to open at a fixed location, or 
 *	to vary.  Their appearance is configurable via the use
 *	of stylesheets.
 */

var AllMenus = new Array();

/**
 *	The name of the popup menu.
 */
PopupMenu.prototype.name = null;

/**
 *	The ID of the div used for this menu.
 */
PopupMenu.prototype.divId = null;

/**
 *	The stylesheet class of the overall menu.
 */
PopupMenu.prototype.displayClass = "PopupMenu";

/**
 *	The menu items in the menu.
 */
PopupMenu.prototype.items = null;

/**
 *	The timeout period (in milliseconds) to wait after the
 *	user's mouse leaves the menu before closing it.
 */
PopupMenu.prototype.closeTimeout = 3 * 1000; // Default = 1 second

/**
 *	The X and Y pixel locations of the top-left corner
 *	of the menu.
 */
PopupMenu.prototype.locationX = 100;
PopupMenu.prototype.locationY = 100;
PopupMenu.prototype.width = 75;
PopupMenu.prototype.itemHeight = 30;

/**
 *	If this is true, opening this menu will close
 *	all other menus first.
 */
PopupMenu.prototype.exclusive = true;


/**
 *	Constructor.  Creates a new popup menu.
 */
function PopupMenu(name, width) {
	if(name) this.name = name;
	if(width) this.width = width;
	this.items = new Array();
}

/**
 *	Initializes the menu display.  This should be
 *	called after all of the menu items are added
 *	to the popup menu.
 */
PopupMenu.prototype.initialize = function() {
	this.createDiv();
	var txt = "";
	for(var i in this.items) {
		txt += this.items[i].toHtml(this.name, this.displayClass);
	}
	
	//	Finally, add a fake div at the bottom that controls the closing.
	txt += "<div style='width=100%; height=1px; font-size: 2px;' onmouseout=\"menuOut('"+ this.divId +"');\">&nbsp;</div>";
	
	writeToDiv(this.divId,txt);
}


PopupMenu.prototype.addItem = function(menuItem) {
	this.items[this.items.length] = menuItem;
	menuItem.parent = this;
}

PopupMenu.prototype.indexOf = function(menuItem) {
	for(var i=0;i<this.items.length; i++) {
		if(this.items[i] == menuItem) return i;
	}
	return -1;
}

PopupMenu.prototype.createDiv = function () {
	//	Create the div ID.
	this.divId = this.name;
	
	if((document.body) && (document.body.insertAdjacentHTML)) {
		var divStr = "<div ID=" + this.divId + " class='"+this.displayClass+"'></DIV>";
		document.body.insertAdjacentHTML("BeforeEnd",divStr);
	}
	else {
		var newDiv = document.createElement("DIV");
		
		newDiv.id = this.divId;
		newDiv.className = this.displayClass;
		document.body.appendChild(newDiv);
	}
	
	var styleObject = getStyleObject(this.divId);
	styleObject.position = "absolute";
	//styleObject.display = "none";
	if(this.width) styleObject.width = this.width+"px";
	
	this.setLocation(0,0);
	
	AllMenus[this.name] = this;
	this.hide();
}

/**
 *	Hides the popup menu.  Calling this function hides the
 *	menu immediately, no timeout delay is used.
 */
PopupMenu.prototype.hide = function() {
	this.setVisible(false);
}

PopupMenu.prototype.autoHide = function() {
	if(this.over != 1) {
		this.hide();
	}
}

/**
 *	Makes the menu visible at the specified locations.  If
 *	no locations are passed, the current locations are used.
 *	@param	x	The horizontal pixel location.
 *	@param	y	The vertical pixel location.
 */
PopupMenu.prototype.show = function(x, y) {
	//	If is it exclusive, hide everything else first.
	if(this.exclusive) {
		hideMenus();
	}
	//	Don't show empty menus.
	if(this.items.length == 0) return;
	
	this.setLocation(x,y);
	
	//	Now make the menu visible.
	this.setVisible(true);
}


PopupMenu.prototype.setLocation = function(x,y) {
	if(x) this.locationX = x;
	if(y) this.locationY = y;
	
	//	Now move it.
	if(! moveObject(this.divId, this.locationX, this.locationY)) {
		alert("Couldn't Move");
	}
}

/**
 *	Alters the visibility of the popup menu.  This function
 *	can be overridden to implement visibility effects like
 *	fade-in / fade-out, or roll-in / roll-out.  The basic
 *	one just does a simple show / hide.
 */
PopupMenu.prototype.setVisible = function(visible) {
	if(visible) {
		changeObjectVisibility(this.divId,'visible');
	//	setObjectDisplay(this.divId,'inline');
	}
	else {
		changeObjectVisibility(this.divId,'hidden');
	//	setObjectDisplay(this.divId,'none');
	}
}




/**
 * Called when a menu is moused over.
 */
function menuOver() {
	//AllMenus[this.id].over = 1;
}

/**
 *	Called when a menu is moused out.
 */
function menuOut(id) {
	delayedClose(id);
}

function delayedClose(id) {
	//	Create a command that will hide the menu.
	var cmd = "AllMenus['"+id+"'].autoHide();";
	
	//	Set a delay.
	setTimeout(cmd,AllMenus[id].closeTimeout);
}



// A hack to ensure the popups close when over the
// body of the document.
if(document.onclick) {
	
}
else {
	document.onclick = hideMenus;
}
function hideMenus() {
	for(var n in AllMenus) {
		AllMenus[n].hide();
	}
}

function showMenu(name, locationX, locationY) {
	if(AllMenus[name]) {
		AllMenus[name].show(locationX,locationY);
	}
}

function hideOthers(name, className) {
	for(var n in AllMenus) {
		if (n != name && className == "PopupMenu") {
			AllMenus[n].hide();
		}
	}
}

function isdefined(variable) {
    return (typeof(window[variable]) == "undefined")?  false: true;
}


//=======================================================================

// Copyright � 2000 by Apple Computer, Inc., All Rights Reserved.
//
// You may incorporate this Apple sample code into your own code
// without restriction. This Apple sample code has been provided "AS IS"
// and the responsibility for its operation is yours. You may redistribute
// this code, but you are not permitted to redistribute it as
// "Apple sample code" after having made changes.
//
// ************************
// layer utility routines *
// ************************

/**
 *	Write the specified text into the specified div layer.
 */
function writeToDiv(objectId, message) {
	if(document.getElementById && document.getElementById(objectId)) {
		// W3C DOM
		var obj = document.getElementById(objectId);
		if (obj.innerHTML || obj.innerHTML=="") { obj.innerHTML = message; }
		else if((obj.document) && (obj.document.write)){obj.document.write(message);}
		else alert("Problem With: "+objectId);
    } else if (document.all && document.all(objectId)) {
		// MSIE 4 DOM
		//return document.all(objectId).style;
	//	alert("MSIE 4");
    } else if (document.layers && document.layers[objectId]) {
		// NN 4 DOM.. note: this won't find nested layers
		//return document.layers[objectId];
	//	alert("NS 4");
    } else {
	//	alert("Failed");
    }
}



function getStyleObject(objectId) {
    // cross-browser function to get an object's style object given its id
    if(document.getElementById && document.getElementById(objectId)) {
	// W3C DOM
	return document.getElementById(objectId).style;
    } else if (document.all && document.all(objectId)) {
	// MSIE 4 DOM
	return document.all(objectId).style;
    } else if (document.layers && document.layers[objectId]) {
	// NN 4 DOM.. note: this won't find nested layers
	return document.layers[objectId];
    } else {
	return false;
    }
} // getStyleObject

function changeObjectVisibility(objectId, newVisibility) {
    // get a reference to the cross-browser style object and make sure the object exists
    var styleObject = getStyleObject(objectId);
    if(styleObject) {
	styleObject.visibility = newVisibility;
	return true;
    } else {
	// we couldn't find the object, so we can't change its visibility
	return false;
    }
} // changeObjectVisibility


function setObjectDisplay(objectId, display) {
//	if(display) alert("Showing: "+objectId);
	var styleObject = getStyleObject(objectId);
	var d = '';
	if(!display) d = 'none';
    if(styleObject) {
	styleObject.display = d;
	return true;
    } else {
	// we couldn't find the object, so we can't change its visibility
	return false;
    }
}


function moveObject(objectId, newXCoordinate, newYCoordinate) {
    // get a reference to the cross-browser style object and make sure the object exists
    var styleObject = getStyleObject(objectId);
    if(styleObject && newXCoordinate && newYCoordinate) {
	styleObject.left = newXCoordinate+"px";
	styleObject.top = newYCoordinate+"px";
	
	//alert(styleObject.left);
	
	return true;
    } else {
	// we couldn't find the object, so we can't very well move it
	return false;
    }
} // moveObject


function showMenu(name,x,y) {
	var menu = AllMenus[name];
	if(! menu) {
		//	menu not found.
		return false;
	}
	menu.show(x,y);
}

