/* ****************************************************************
	ovMenu.js
	Drop-menu class
	author: Jesse Hemingway
	copyright (c) 2008 Jirosoft	
**************************************************************** */

// Used for the event-driven calls in OvMenu
var ovMenuStack = new Array();

function OvMenu(parentElement, items, options)
{
	this.parentElement = parentElement;
	this.menuClass = options.menuClass;
	this.rowClass = options.rowClass;
	this.rowClassDisabled = options.disabledClass;
	this.extraContainerClasses = options.extraContainerClasses;
	this.widthBoost = options.widthBoost;
	this.fadeTime = options.fadeTime;
	this.menuItems = items;
	this.menu = null;
	this.clickOutActive = false;
	this.iStack = 0;
	this.menuTimer = null;
	
	this.show = function(srcElement, position, substitutions, enables)
	{
		if (this.menu)
			return;
		ovMenuStack.push(this);
		var iStack = this.iStack = ovMenuStack.length - 1;
			
		var menuHTML = "<div id='" + this.parentElement + "_menu' class='" + this.menuClass + "'>";
		for (var i = 0; i < this.extraContainerClasses.length; i++)
			menuHTML += "<div class='" + this.extraContainerClasses[i] + "'>"; 
		for (i = 0; i < this.menuItems.length; i++) {
			var enabled = !enables || i >= enables.length || enables[i]; 
			var className = enabled  ? this.rowClass : this.rowClassDisabled;
			var rowIdent = this.parentElement + "_menuRow_" + i; 
			if (enabled) {
				menuHTML += "<a href='" + this.menuItems[i].url + "'";
				if (this.menuItems[i].onHover)
					menuHTML += " onmouseover=\"" + this.menuItems[i].onHover + "\"";
				menuHTML += " onclick=\"";
				if (!this.menuItems[i].subItems)
					menuHTML += "ovMenuStack[" + iStack + "].onClick('" + rowIdent + "');"; 
				if (this.menuItems[i].onClick)
					menuHTML += this.menuItems[i].onClick;
				if (this.menuItems[i].subItems) {
					this.menuItems[i].subMenu = new OvMenu(rowIdent, this.menuItems[i].subItems,
						{ menuClass: this.menuClass, rowClass: this.rowClass, disabledClass: this.rowClassDisabled,
						extraContainerClasses: this.extraContainerClasses, widthBoost: this.widthBoost, fadeTime: this.fadeTime });
					this.menuItems[i].substitutions = substitutions;				
//					menuHTML += " ovMenuStack[" + iStack + "].menuItems[" + i + "].subMenu.show('" + rowIdent + "', 'top right', ovMenuStack[" + iStack + "].menuItems[" + i + "].substitutions); return false\"";
					menuHTML += " ovMenuStack[" + iStack + "].showSub(" + i + ", '" + rowIdent + "'); return false\"";
				} else
					menuHTML += "; return true;\"";
				menuHTML += "><span class='" + className + "' id='" + rowIdent + "'>" + this.menuItems[i].text + "</span></a>";
			} else
				menuHTML += "<span class='" + className + "' id='" + rowIdent + "'>" + this.menuItems[i].text + "</span>";
		}
		for (i = 0; i < this.extraContainerClasses.length; i++)
			menuHTML += "</div>";
		menuHTML += "</div>";
		for (j = 1; j <= substitutions.length; j++)	// perform substitutions
			menuHTML = menuHTML.replace(eval('/%{1}' + j +'/g'), substitutions[j - 1]);
//alert(menuHTML);			
		$(this.parentElement).insert({ top: menuHTML });			 
		this.menu = $(this.parentElement + '_menu');

		// size the menu to the content
		var maxWidth = 0;
		for (i = 0; i < this.menuItems.length; i++) {
			var elem = $(this.parentElement + "_menuRow_" + i);
			var elemDim = elem.getDimensions();
			maxWidth = Math.max(maxWidth, elemDim.width);
		}
		maxWidth += this.widthBoost;
		this.menu.style.width = maxWidth + 'px';
		dim = this.menu.getDimensions();
	
		// position the menu
		srcElement = $(srcElement);
		var srcDim = srcElement.getDimensions();
		if (position.match('center'))
			srcDim.width = -dim.width / 2 + srcDim.width / 2;
		else if (position.match('overlapped'))
			srcDim.width = -dim.width * 0.1 + srcDim.width / 2;			
		else if (position.match('left'))
			srcDim.width = -dim.width;
		if (position.match('middle'))
			srcDim.height /= 2;
		else if (position.match('top'))
			srcDim.height = 0;

		this.menu.clonePosition(srcElement, { setWidth: false, setHeight: false, offsetLeft: srcDim.width, offsetTop: srcDim.height});
		this.menu.style.zIndex = 100;
		
		// ensure the menu has not gone off the viewport
		var winDim = document.viewport.getDimensions();
		var scrollOff = document.viewport.getScrollOffsets();
		winDim.height += scrollOff.top;
		winDim.width += scrollOff.left;
		var pos = this.menu.cumulativeOffset();
		var posParent = this.menu.getOffsetParent().cumulativeOffset();
		if (pos.top + dim.height >= winDim.height)
			this.menu.style.top = winDim.height - dim.height - posParent.top + 'px';
		if (pos.left + dim.width >= winDim.width)
			this.menu.style.left = winDim.width - dim.width - posParent.left + 'px';
			
		this.menuTimer = setTimeout("ovMenuStack[" + iStack + "].hide()", 3000);
		this.clickOutActive = false;
		setTimeout("ovMenuStack[" + iStack + "].activateClickOut()", 50);
	}
	
	this.showSub = function(i, rowIdent)
	{
		if (ovMenuStack.length > this.iStack + 1)
			ovMenuStack[this.iStack + 1].hide(); 
		this.menuItems[i].subMenu.show(rowIdent, 'top right', this.menuItems[i].substitutions);
	}
	
	this.hide = function()
	{
		if (this.menu) {
			for (i = ovMenuStack.length - 1; i >= this.iStack; i--) {
				clearTimeout(ovMenuStack[i].menuTimer);
				ovMenuStack[i].menu.remove();
				ovMenuStack[i].menu = null;
				ovMenuStack.pop();
			}				
		}	
	}

	this.activateClickOut = function()
	{
		this.clickOutActive = true
	}
	
	this.inMenu = function(event)
	{ 	
		var pos = this.menu.cumulativeOffset();
		var dim = this.menu.getDimensions();
		var mouseX = event.pointerX();
		var mouseY = event.pointerY();
		var inMenu = mouseX >= pos.left && mouseX < pos.left + dim.width && mouseY >= pos.top && mouseY < pos.top + dim.height;

		return inMenu;
	}
	
	this.checkMotion = function(event)
	{
		if (ovMenuStack.length) {
			var inMenu = false;
			for (var i = 0; i < ovMenuStack.length; i++)
				clearTimeout(ovMenuStack[i].menuTimer);
			for (var i = ovMenuStack.length - 1; i >= 0; i--) {
				if (!ovMenuStack[i].inMenu(event))
					ovMenuStack[i].menuTimer = setTimeout("ovMenuStack[" + ovMenuStack[i].iStack + "].hide()", 1000);
				else
					break;
			}
		}
	}
	
	this.checkClick = function(event)
	{
		if (ovMenuStack.length) {
			var inMenu = false;
			for (var i = ovMenuStack.length - 1; i >= 0; i--) {
				inMenu = ovMenuStack[i].inMenu(event) || !ovMenuStack[i].clickOutActive;
				if (!inMenu)
					ovMenuStack[i].hide();
				else break;
			}
		}
	}
	
	this.onClick = function(rowIdent)
	{
		clearTimeout(this.menuTimer);
		var iStack = this.iStack;
		new Effect.Opacity(this.parentElement + "_menu", { duration: this.fadeTime, from: 1, to: 0, afterFinish: function() { ovMenuStack[iStack].hide() }  });
		for (i = 0; i < this.menuItems.length; i++) {
			var curIdent = this.parentElement + "_menuRow_" + i;
			if (curIdent != rowIdent)
				new Effect.Opacity(curIdent, { duration: this.fadeTime * 0.67, from: 1, to: 0 });
			else
				$(curIdent).addClassName('treeMenuRowActive');
		}
		for (i = 0; i < ovMenuStack.length - 1; i++) {
			new Effect.Opacity(ovMenuStack[i].parentElement + "_menu", { duration: this.fadeTime, from: 1, to: 0  });
		}
	}
	
	Event.observe(window, 'mouseover', this.checkMotion);
	Event.observe(window, 'click', this.checkClick);
	
}
