/*
 Popupmenu V0.9
 (C) Matthias Wiede 2008-2009
 http://www.mwiede.de
*/

menuOpaque = 70; // 100=full opaque, 0=invisible

function createParentName (prefix, parents, offs) {
	var name = prefix;
	if (parents)
	{
		for (var i=1;i<parents.length+offs;i++)
			name+=("_"+parents[i]);
	}
	return name;
}

function unmarkParentItem (menuName, name) 
{
	var parents = name.split ("_");
	var parentItem = document.getElementById 
		(createParentName (menuName+"-item", parents, 0));
	if (parentItem)
		setClass ("remove", parentItem, "active", "");	
}

function getSubMenu (menuItems, parents, offs) {
	if (parents!=null && parents.length>1)
	{
		var linkURL = menuItems[parents[offs]-1][1];
		var subMenuItems = menuItems[parents[offs]-1][2];		
		var linkObj = menuItems[parents[offs]-1][3];
		if ((subMenuItems instanceof Array) && (offs+1)<parents.length) {
			var retArray = getSubMenu (subMenuItems, parents, offs+1, false);
			subMenuItems = retArray[0];
			linkURL = retArray[1];
			linkObj = retArray[2];
		}

		return new Array (subMenuItems, linkURL, linkObj);
	}
	return new Array (menuItems, "", null);
}

/* Create Javascript menu array from menu structure */
function createMenuItemsFromULStruct (obj) {
	var pos = 0;
	var items = new Array ();
	obj = obj.firstChild;
	while (obj) {
		if (obj.nodeName=='LI') {
			var linkObj = obj.firstChild;
			if (linkObj && linkObj.nodeName=='A') {					
				var text   = linkObj.innerHTML;
				// Replace html entities
				text = text.replace ("&amp;", "&");
				var linkURL    = linkObj.href;
				items[pos] = new Array (text, linkURL, "", linkObj);
				var subObj = linkObj.nextSibling; // UL node
				if (subObj && subObj.nodeName=='UL') {
					items[pos][2] = createMenuItemsFromULStruct (subObj);
				}				
				pos++;
			}
		}
		obj = obj.nextSibling;
	}
	return items;
}

// Default configurations vars
menuCreateTime = 100; // ms
menuCloseTime = 300;
menuOffsetX = -5;
menuOffsetY = 0;
menuOffsetX2 = 0;
menuOffsetY2 = 0;

/* Internal vars */
menuList = Array ();
menuHorItemCnt = 0;

function Menu (target, name, x, y, items, isHorizontal)
{
	this.target = target;
	this.menuName = name;
	this.menuX = x;
	this.menuY = y;
	this.menuCreateTime = menuCreateTime;
	this.menuCloseTime = menuCloseTime;
	this.menuOffsetX = menuOffsetX;
	this.menuOffsetY = menuOffsetY;
	this.menuOffsetX2 = menuOffsetX2;
	this.menuOffsetY2 = menuOffsetY2;
	this.menuItems = items;
	this.isHorizontal = isHorizontal;

	// Status vars
	this.menuListOpen = new Array ();
	this.menuItemIsSelected = false;
	this.menuCreateX = 0;
	this.menuCreateY = 0;
	this.menuCreateWidth = 0;
	this.menuCreateParents = new Array ();
	this.menuTimer = null;

	// Methods
	this.onMenuItemMouseOver = function(evt) 
	{
		var td = (evt.target) ? evt.target : evt.srcElement;
		setClass ("add", td, "hover", "");
		var i = 0;
		var name = td.id;
		var parents = name.split ("-");
		var menu = null;
		if (parents.length==2)
			menu = menuList[parents[0]];
		parents = name.split ("_");

		if (menu!=null && parents.length>1) {
			name = createParentName (menu.menuName, parents, -1);
			
			var table = document.getElementById (name);
			if (table)
			{
				var pos = (parents[parents.length-1]-1);
				
				var x = 0;
				var y = 0;
				var width = 0;
				if (parents.length==2 && menu.isHorizontal)  
				{
					// Sub menu for horizontal menu
					x = table.offsetLeft + td.offsetLeft  + menu.menuOffsetX2;					
					y = table.offsetTop  + td.offsetTop   + td.offsetHeight + menu.menuOffsetY2;


				}
				else
				{
					// Sub menu for vertical menu
					
					if (parents[1]==menuHorItemCnt)  {
						x = table.offsetLeft - menuOffsetX;
						y = table.offsetTop  + td.offsetTop   - menu.menuOffsetY;
					
					}
					else {
					
						x = table.offsetLeft + table.offsetWidth + menu.menuOffsetX;
						y = table.offsetTop  + td.offsetTop   + menu.menuOffsetY;
					}
				}
				
				menu.menuCreateX = x;
				menu.menuCreateY = y;
				menu.menuCreateParents = parents;
				menu.menuCreateWidth = width;
				if (menu.menuTimer) {
					clearTimeout(menu.menuTimer);
					menu.menuTimer = null;
				}
				menu.menuItemIsSelected = true;
				menu.menuTimer = setTimeout(function () { menu.timedCreateMenu() }, menu.menuCreateTime);
				
			}
		}
	}
	
	this.timedCreateMenu = function ()
	{
		var i=0;
		
		if (this.menuItemIsSelected)
		{
			var fJustExist = false;
			var dontDeleteName = createParentName (this.menuName, this.menuCreateParents,0)
			var length = this.menuListOpen.length;
			for (i=(this.menuCreateParents.length-2);i<length;i++) 
			{
				if (this.menuListOpen[i]) {
					if (this.menuListOpen[i].id==dontDeleteName) {
						fJustExist = true;
					}
					else 
					{
						var name = this.menuListOpen[i].id;
						unmarkParentItem (this.menuName, name);				
						this.target.removeChild (this.menuListOpen[i]);
						this.menuListOpen[i]=null;
					}
				}	
			}
			if (!fJustExist) {
				this.createMenu (this.target, this.menuCreateX, this.menuCreateY, this.menuCreateParents);	
			}
		}
	}
	
	this.timedCloseOpenMenus = function ()
	{
		if (this.menuItemIsSelected==false) {
			var length = this.menuListOpen.length;
			for (var i=length-1;i>=0;i--) {
				if (this.menuListOpen[i])
				{
					var name = this.menuListOpen[i].id;
					unmarkParentItem (this.menuName, name);
					this.target.removeChild (this.menuListOpen[i]);
					this.menuListOpen[i]=null;
				}
			}
		}
	}
	

	this.onMenuItemMouseOut = function (evt) {
	
		var td = (evt.target) ? evt.target : evt.srcElement;
		setClass ("remove", td, "hover", "");
		// Check if mouse coords are outside of parent div
		mouseCoords = getMouseCoords (evt);

		// Get true x/y of parent		
		var parentLeft=0,parentTop=0;
		var parentNode = td.parentNode;
		while (parentNode) {
			parentLeft+=parentNode.offsetLeft;
			parentTop+=parentNode.offsetTop;
			parentNode = parentNode.parentNode;
		}

		if (!(mouseCoords[0]>parentLeft && 
			    mouseCoords[0]<(parentLeft+td.parentNode.offsetWidth) && 
			    mouseCoords[1]>parentTop && 
			    mouseCoords[1]<(parentTop + td.parentNode.offsetHeight)))
		{

			var name = td.parentNode.id;
			var parents = name.split ("_");
			var menu = null;
			menu = menuList[parents[0]];
			if (menu!=null) {
			
				menu.menuItemIsSelected=false;
		
				if (menu.menuTimer)
				{
					clearTimeout(menu.menuTimer);
					menu.menuTimer = null;
				}
				menu.menuTimer = setTimeout(function () { menu.timedCloseOpenMenus() }, menu.menuCloseTime);
			}
		}		
	}
	
	this.onMenuMouseOver = function (evt) {
	
		var table = (evt.target) ? evt.target : evt.srcElement;
		var name = table.id;
		var parents = name.split ("_");
		var menu = null;
		menu = menuList[parents[0]];
		if (menu!=null) {
			if (menu.menuTimer)
			{
				clearTimeout(menu.menuTimer);
				menu.menuTimer = null;
			}		
		}
	}

	this.onMenuMouseOut = function (evt) {
	
		var table = (evt.target) ? evt.target : evt.srcElement;
		var name = table.id;
		var parents = name.split ("_");
		var menu = null;
		menu = menuList[parents[0]];
		if (menu!=null) {
		
			menu.menuItemIsSelected=false;
	
			if (menu.menuTimer)
			{
				clearTimeout(menu.menuTimer);
				menu.menuTimer = null;
			}
	
			menu.menuTimer = setTimeout(function () { menu.timedCloseOpenMenus() }, menu.menuCloseTime);
		}
		
	}
	
	
	this.onMenuItemClick = function (evt) 
	{
		var td = (evt.target) ? evt.target : evt.srcElement;
		var name = td.id;
		var parents = name.split ("-");
		var menu = null;
		if (parents.length==2)
			menu = menuList[parents[0]];
		parents = name.split ("_");
		if (menu!=null)
		{
			var linkURL = getSubMenu (menu.menuItems, parents,1)[1];
			var linkObj = getSubMenu (menu.menuItems, parents,1)[2];

			if (linkObj && linkObj.onclick)
				linkObj.onclick (linkObj);
			else
			if (linkURL.indexOf("javascript")==-1)
				window.location.href=linkURL;
			else
			if (linkURL!='') 
				eval (linkURL);
		}
	}
	
	this.createMenu = function (target, x, y, parents)
	{
	
		var name = createParentName (this.menuName, parents, 0);
		if (document.getElementById (name))
			return;
		var subMenu = getSubMenu (this.menuItems, parents,1)[0];
		
		if (subMenu instanceof Array)
		{ 
			// mark parent item
			var parentItem = document.getElementById 
				(createParentName (this.menuName+"-item", parents, 0));
			if (parentItem)
			{
				setClass ("add", parentItem, "active", "");
			}
			
			// Create new sub menu
			var table = document.createElement("div");
			table.id = name;
			if (!parents && this.isHorizontal) 
				table.className = this.menuName+"_horizontal";
			else
				table.className = this.menuName;
						
			table.style.position = "absolute";
			table.style.left = x+"px";
			table.style.top = y+"px";
			
			if (this.menuCreateWidth!=0)
				table.style.width = this.menuCreateWidth+"px";
			
			addEvent (table,'mouseout', this.onMenuMouseOut, false);
			addEvent (table, 'mouseover', this.onMenuMouseOver, false);
			
			target.appendChild(table);
			
			if (!parents && this.isHorizontal) 
			{
				menuHorItemCnt = subMenu.length;
				for (var j = 0; j < subMenu.length; j++)
				{
					// Horizontal items
					var td = document.createElement ("span");
					td.className = "item";
					name =  createParentName (this.menuName+"-item", parents, 0);		
					name+=("_"+(j+1));
					td.id = name;
					
					
					addEvent (td,'mouseover', this.onMenuItemMouseOver, false);
					addEvent (td,'mouseout', this.onMenuItemMouseOut, false);
					addEvent (td,'mousedown', this.onMenuItemClick, false);
					var text = document.createTextNode (subMenu[j][0]);
					if (subMenu[j][1] instanceof Array)
						td.className =  td.className + " hasItems";
			
					// Check marked style
					if (subMenu[j][3]) {
						if (setClass('check', subMenu[j][3], 'marked','')) {
							td.className = td.className + " marked";
						}
					}
					td.appendChild(text);
					table.appendChild(td);
				}
				
			}
			else
			{
				if (parents && parents.length==2)
					setClass ("add", table, this.menuName+"_first_sub", "");
				else
					setClass ("add", table, this.menuName+"_sub", "");
				setTransparency (table, menuOpaque);
				// Vertical items
				for (var j = 0; j < subMenu.length; j++)
				{
					var td = document.createElement ("div");
					td.className = "item";
					
					name =  createParentName (this.menuName+"-item", parents, 0);		
					name+=("_"+(j+1));
					td.id = name;
					
					addEvent (td,'mouseover', this.onMenuItemMouseOver, false);
					addEvent (td,'mouseout', this.onMenuItemMouseOut, false);
					addEvent (td,'mousedown', this.onMenuItemClick, false);
					
					
					var text = document.createTextNode (subMenu[j][0]);

					if (subMenu[j][1] instanceof Array)
						td.className =  td.className + " hasItems";
					
					// Check marked style
					if (subMenu[j][3]) {
						if (setClass('check', subMenu[j][3], 'marked','')) {
							td.className = td.className + " marked";
						}
					}
					
					
					td.appendChild(text);
					
					table.appendChild(td);

					// Set correct x position
					if (parents[1]==menuHorItemCnt && parents.length>2) {
	
						table.style.left=(x-table.offsetWidth)+"px";
	
					}

					
				}
				
				
				// Set correct with of items
				var fullWidth = table.offsetWidth;
				if (table.currentStyle) {
					fullWidth-=parseInt (table.currentStyle.paddingRight);
					fullWidth-=parseInt (table.currentStyle.paddingLeft);
					fullWidth-=getBorderWidth (table, 'Right');
					fullWidth-=getBorderWidth (table, 'Left');
				}
				var obj = table.firstChild;
				while (obj!=null) {
					var fullWidth2 = fullWidth;
					if (obj.currentStyle) {
						fullWidth2-=parseInt (obj.currentStyle.paddingRight);
						fullWidth2-=parseInt (obj.currentStyle.paddingLeft);
					
					}					
					obj.style.width = fullWidth2;
					obj = obj.nextSibling;
				}
				// table.style.width=fullWidth;
				
			}
			if (parents) {
				this.menuListOpen[parents.length-2]=table;
			}
		}
	}
	
	// Create menu
	this.createMenu (target, x, y);

	menuList[name]=this;
}

