// JOHN'S NEW MENU CLASS SCRIPTS AS OF 2008-06-02
// INTENDED TO REPLACE COOLJSMENU
// FIX: MAKE A TAG FOR THIS

// Create the base menu.
function Menu() {
	var self = this;

	// Create Settings
	this.settings = new Object();

	// Default Settings
	this.settings.defaultTimeout = 500;

	// Items is an Array of Menu Item Objects
	this.items = new Array();

	this.create = function() {
		this.addItem("menuBase",0);
		this.setup();
	}

	// Overridden on a Menu by Menu basis- adds all the items.
	this.setup = function() { }

	this.addItem = function(divId,parentIndex) {
		// initialize variables
		var item   = "";

		// optional arguments
		var timeout    = (arguments.length > 2) ? arguments[2] : 0;
		var transition = (arguments.length > 3) ? arguments[3] : "none";

		this.items.push(new MenuItem(divId,parentIndex,timeout,transition));
	}

	this.openItem = function(index) {
		// initialize variables
		var thisParent = 0;

		if(self.items.length == 0) { self.create(); }

		// show the item
		this.items[index].show();

		// Ensure our parents do not close on us.
		thisParent = this.items[index].parent;

		if(typeof(thisParent) == "number") {
			// Close all other menu items on this level.
			for(var a = 1; a < this.items.length; a++) {
				if(a != index && this.items[a].parent == thisParent) { this.closeItem(a); }
			}

			// Clear timers on all parents.
			while(thisParent > 0) {
				this.items[thisParent].clear();
				thisParent = this.items[thisParent].parent;
			}
		}

		// Fire the event
		this.onOpen(index);
	}

	this.timeoutItem = function(index) {
		// initialize variables
		var thisParent  = 0;
		var thisTimeout = 0;

		if(self.items.length == 0) { self.create(); }

		// Ensure Timer is completely clear.
		this.items[index].clear();

		// Get proper timeout.
		thisTimeout = this.items[index].timeout;

		if(typeof(thisTimeout) != "number" || thisTimeout == 0) { thisTimeout = this.settings.defaultTimeout; }

		// Start new Timer.
		this.items[index].timer = setTimeout(function() { self.closeItem(index); self.onTimeout(index); }, thisTimeout);

		// Set our parents to close as well.
		thisParent = this.items[index].parent;

		if(typeof(thisParent) == "number" && thisParent > 0) {
			while(thisParent > 0) {
				this.items[thisParent].timer = setTimeout(function() { self.closeItem(thisParent) }, thisTimeout);
				thisParent = this.items[thisParent].parent;
			}
		}
	}

	this.closeItem = function(index) {
		if(self.items.length == 0) { self.create(); }

		for(var a = 1; a < self.items.length; a++) {
			// First close all of its children.
			if(self.items[a].parent == index) { self.items[a].hide(); }
		}

		// Fire the event
		if(self.items[index].showing()) { this.onClose(index); }

		// Then we close the actual menu item.
		self.items[index].hide();
	}

	// EVENT FUNCTIONS (OVERRIDE AS NEEDED)
	this.onOpen    = function(index) { }
	this.onClose   = function(index) { }
	this.onTimeout = function(index) { }
}

function MenuItem(divId,parentIndex,itemTimeout) {
	this.div        = document.getElementById(divId);
	this.parent     = parentIndex;
	this.timer      = "";
	this.transition = (arguments.length > 3) ? arguments[3] : "none";
	this.timeout    = itemTimeout; // 0 = Use Default Timeout

	// Ensure timer is completely clear.
	this.clear = function() {
		clearTimeout(this.timer);
		this.timer = "";
	}

	this.show = function() {
		this.clear();
		if(this.showing()) { return true; }

		if(this.transition == "slidevert" && typeof jQuery != "undefined") {
			jQuery(this.div).slideDown(400);
		} else if(this.transition == "slidevertfast" && typeof jQuery != "undefined") {
			jQuery(this.div).slideDown(200);
		} else {
			this.div.style.display = "";
		}
	}

	this.hide = function() {
		this.clear();
		if(this.transition == "slidevert" && typeof jQuery != "undefined") {
			jQuery(this.div).slideUp(400);
		} else if(this.transition == "slidevertfast" && typeof jQuery != "undefined") {
			jQuery(this.div).slideUp(200);
		} else {
			this.div.style.display = "none";
		}
	}

	this.showing = function() { return (this.div.style.display != "none"); }
}
