
function Menu ( id, cell ) {
	this.displayBelow = Menu.displayBelowDefault;
	this.id = Menu.register( this );
	if ( id ) {
		this.cell = document.getElementById( id );
		this.cell.menuInst = this;
		this.cell.onmouseover = Menu.forwardCellEvent;
		this.cell.onmouseout = Menu.forwardCellEvent;
		this.cell.onclick = Menu.forwardCellEvent;
		this.menuTableClass = this.cell.className;
	} else {
		this.cell = cell;
		this.isSubmenu = true;
	}
	this.menu = document.createElement( "SPAN" );
	document.body.appendChild( this.menu );
	this.menu.style.position = "absolute";
	this.menu.style.display = "none";
	var table = document.createElement( "TABLE" );
	this.menu.appendChild( table );
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.className = Menu.menuClass;
	this.tableBody = document.createElement( "TBODY" );
	table.appendChild( this.tableBody );
	var images = this.cell.getElementsByTagName("IMG");
	if (images.length > 0) this.image = images[0];
}
Util.extend( Menu, BaseObject );

Menu.displayBelowDefault = true;
Menu.itemArrow = "/images/menuArrow.gif";
Menu.submenuArrow = "/images/menuArrow.gif";
Menu.menuClass = "menu";
Menu.menuItemOverClass = "menuItemOver";
Menu.menuTableOverClass = "activeMenuItem";
Menu.longCloseDelay = 1000;
Menu.closeDelay = 600;
Menu.openDelay = 300;

Menu.prototype.displayBelow = true;
Menu.prototype.hideTimeout = null;
Menu.prototype.openTimeout = null;
Menu.prototype.shown = false;
Menu.prototype.isSubmenu = false;
Menu.prototype.openSubmenu = null;
Menu.prototype.leftOffsetPlacement = -5;
Menu.prototype.topOffsetPlacement = 10;

Menu.prototype.addSubMenu = function ( text, url ) {
	return this.addItem(text, url, true);
}

Menu.prototype.addItem = function ( text, url, hasSubMenu ) {
	var tr = document.createElement( "TR" );
	tr.style.cursor = url ? "pointer" : "default";
	this.tableBody.appendChild( tr );
	var cell = document.createElement( "TD" );
	tr.appendChild( cell );
	var html = "<table cellspacing=0 cellpadding=0 border=0><tr><td width='100%'>";
	if (Menu.itemArrow) html += "<img src='" + Menu.itemArrow + "' width=14 height=9 align='absmiddle'>";
	html += text + "</td>";
	if ( hasSubMenu && Menu.submenuArrow ) html += "<td><img src='" + Menu.submenuArrow + "' width=14 height=9 style='padding-left:10px;'></td>";
	html += "</tr></table>";
	cell.innerHTML = html;
	cell.menuInst = this;
	cell.url = url;
	cell.onmouseover = Menu.forwardItemEvent;
	cell.onmouseout = Menu.forwardItemEvent;
	cell.onclick = Menu.forwardItemEvent;
	if ( hasSubMenu ) {
		cell.submenu = new Menu( null, cell );
		return cell.submenu;
	}
}

Menu.prototype.showMenu = function ( dontHideOthers ) {
	var topOffset, leftOffset;
	if ( this.isSubmenu ) {
		if (this.cell.menuInst.openSubmenu) {
			this.cell.menuInst.openSubmenu.hideMenu(false);
		}
		// Offset placement.
		leftOffset = this.cell.offsetWidth + this.leftOffsetPlacement;
		topOffset = -this.cell.offsetHeight + this.topOffsetPlacement - 1;
		this.cell.menuInst.openSubmenu = this;
	} else {
		if ( this.displayBelow ) {
			topOffset = 0;
			leftOffset = -1;
		} else {
			leftOffset = this.cell.offsetWidth;
			topOffset = -this.cell.offsetHeight;
		}
		if (this.image) this.image.src = this.getImageURL( "on" );
		this.cell.className = Menu.menuTableOverClass;
	}
	var curParent = this.cell;
	while ( curParent ) {
		topOffset += curParent.offsetTop;
		leftOffset += curParent.offsetLeft;
		curParent = curParent.offsetParent;
	}
	this.menu.style.display = "block";
	if ( document.body.offsetWidth < leftOffset + this.menu.offsetWidth ) leftOffset -= this.cell.offsetWidth + this.menu.offsetWidth + this.leftOffsetPlacement * 2 + 1;
	this.menu.style.top = topOffset + this.cell.offsetHeight;
	this.menu.style.left = leftOffset;
	if ( !this.shown ) {
		if ( !dontHideOthers ) Menu.closeAll();
		this.shown = true;
	}
}

Menu.prototype.getImageURL = function ( status ) {
	if ( this.isSubmenu ) alert( "Menu error!" );
	var url = this.image.src;
	return url.substr( 0, url.indexOf(this.cell.id) ) + this.cell.id + "-" + status + ".gif";
}

Menu.prototype.hideMenu = function ( closingAll ) {
	this.cancelHide();
	if ( !closingAll && this.openSubmenu ) {
		this.hideTimeout = -1;  // Special case so this menu will close automatically if its submenu closes.
		return;
	}
	if ( this.isSubmenu ) {
		this.cell.menuInst.openSubmenu = null;
		// Close the parent menu if it hasn't been moused over (hideTimeout would be null) and isn't already going to timeout (hideTimeout would be > 0).
		if ( this.cell.menuInst.hideTimeout == -1 ) this.cell.menuInst.startHide();
	} else {
		if (this.image) this.image.src = this.getImageURL( "off" );
		this.cell.className = this.menuTableClass;
	}
	this.menu.style.display = "none";
	this.shown = false;
}

Menu.prototype.mouseoverCellHandler = function () {
	this.cancelHide();
	this.cell.className = Menu.menuTableOverClass;
	var anyMenuIsOpen = false;
	for ( var i=0; i < Menu.insts.length; i++ ) {
		var inst = Menu.insts[ i ];
		if ( inst.shown ) {
			anyMenuIsOpen = true;
			break;
		}
	}
	if (anyMenuIsOpen)
		this.showMenu();
	else
		this.openTimeout = setTimeout( "var m=Menu.insts[" + this.id + "];m.showMenu()", Menu.openDelay );
}

Menu.prototype.startHide = function ( useLongDelay ) {
	if (!this.shown) this.cell.className = this.menuTableClass;
	this.cancelHide();
	this.hideTimeout = setTimeout( "Menu.insts[" + this.id + "].hideMenu()", useLongDelay ? Menu.longCloseDelay : Menu.closeDelay );
}

Menu.prototype.mouseoutCellHandler = Menu.prototype.startHide;

Menu.prototype.cancelHide = function () {
	if ( this.hideTimeout ) {
		clearTimeout( this.hideTimeout );
		this.hideTimeout = null;
	}
	if ( this.openTimeout ) {
		clearTimeout( this.openTimeout );
		this.openTimeout = null;
	}
}

Menu.prototype.clickItemHandler = function ( cell, event ) {
	if ( cell.url ) document.location.href = cell.url;
	event.cancelBubble = true;
}

Menu.prototype.clickCellHandler = function ( cell ) {
	var anchors = cell.getElementsByTagName( "A" );
	if ( anchors.length > 0 ) document.location.href = anchors[0].href;
}

Menu.prototype.mouseoverItemHandler = function ( cell ) {
	this.cancelHide();
	cell.className = Menu.menuItemOverClass;
	if ( cell.submenu ) {
		cell.submenu.showMenu( true );
		cell.submenu.startHide( true );
	}
}

Menu.prototype.mouseoutItemHandler = function ( cell ) {
	cell.className = "";
	this.startHide();
}

Menu.forwardCellEvent = function ( event ) {
	Menu.forwardEvent( event, "Cell" );
}

Menu.forwardItemEvent = function ( event ) {
	Menu.forwardEvent( event, "Item" );
}

Menu.forwardEvent = function ( event, type ) {
	if ( !event ) event = window.event;
	var curElement = event.srcElement || event.target;
	while ( curElement && !curElement.menuInst )
		curElement = curElement.parentElement || curElement.parentNode;
	if ( !curElement ) return;
	curElement.menuInst[ event.type + type + "Handler" ]( curElement, event );
}

Menu.insts = [];

Menu.register = function ( inst ) {
	var id = Menu.insts.length;
	Menu.insts[ id ] = inst;
	return id;
}

Menu.closeAll = function () {
	for ( var i=0; i < Menu.insts.length; i++ ) {
		var inst = Menu.insts[ i ];
		if ( inst.shown ) inst.hideMenu( true );
	}
}

Util.registerOnload(function () {
	document.body.onclick = Menu.closeAll;
});

Menu.unavailable = document.layers || ( navigator.platform == "MacPPC" && this.name == "Microsoft Internet Explorer" );
