/*
  Menu.js - JavaScript Dynamic Menu Handler

  Version:      1.0.13
  Requires:     Browser.js
  Requires:     Mouse.js
  Requires:     Component.js
  Author:       David Oliveira <d.oliveira@mm.ciben.pt>
 */

	var
		Menus = new Array(),
		nextMenuId = 0;


	function Menu ( mode, parent, description, url, urltarget ) {

		// Properties

		this.id = nextMenuId;
		this.parent = parent;
		this.god = parent ? parent.god : nextMenuId;
		this.description = description;
		this.url = url;
		this.urltarget = urltarget;

		this.mode = mode;

		this.items = new Array();
		this.depnr = 0;
		this.opendepnr = 0;

		this.open = 0;
		this.mouseover = 0;

		this.fancyMenus = true;

		// Functions

		this.addItem = MENUAddItem;
		this.aI = MENUAddItem;
		this.Export = MENUExport;

		// Add to Menu table

		Menus[nextMenuId++] = this;

		// Increment parents depnr

		var par = this;
		while ( par.parent ) {
			par.parent.depnr++;
			par = par.parent;
		}

	}


	// Add menu item

	function MENUAddItem ( description, url, urltarget ) {

		return this.items[this.items.length] = new Menu ( '', this, description, url, urltarget );

	}


	// Export a menu to an HTML component

	function MENUExport ( comp, style ) {

		var
			depids = MenuDepIds(this),
			component = document.getElementById(comp),
			code = '';


		for ( var mnr = 0 ; mnr < depids.length ; mnr++ ) {

			var
				cmenu = Menus[depids[mnr]];

			// If this menu have no items, forget

			if ( !cmenu.items.length )
				continue;

			code += MENUExportItems(cmenu,style);

		}

		component.innerHTML += code;

		menuInit(this);

	}


	// Export menu items

	function MENUExportItems (menu,style) {

		switch (menu.mode) {
			case 'horizontal' :	return MENUExportModeHorizontal(menu,style);
			default :		return MENUExportModeNormal(menu,style);
		}

	}


	// Export menu items in horizontal mode

	function MENUExportModeHorizontal (menu,style) {

		var
			xclass = menuCSS(style,menu),
			code,
			width = ((menu.items.length > 1)?(" width="+(100/menu.items.length)+"%"):'');

		code = "<div class=\""+xclass+"\" id=\"mn_"+menu.id+"\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr>";
		for ( x = 0 ; x < menu.items.length ; x++ )
			code += "<td id=\""+(x?((x+1==menu.items.length)?'l':'o'):'f')+width+"\">"+MENUExportItem(menu.items[x])+"</td>";
		code += "</tr></table></div>";

		return code;

	}


	// Export menu items in normal mode

	function MENUExportModeNormal (menu,style) {

		var
			xclass = menuCSS(style,menu),
			code;

		code = "<div class=\""+xclass+"\" id=\"mn_"+menu.id+"\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
		for ( x = 0 ; x < menu.items.length ; x++ )
			code += "<tr><td nowrap=\"nowrap\" id="+(x?((x+1==menu.items.length)?'l':'o'):'f')+">"+MENUExportItem(menu.items[x])+"</td></tr>";
		code += "</table></div>";

		return code;

	}


	// Export a unique menu item

	function MENUExportItem (item) {

		var
			item_id = ("ln_"+item.id),
			url_target = (item.urltarget?(" target="+item.urltarget):''),
			hchilds = ((item.items.length && item.parent.parent)?' &gt;':'');

		return "<a href=\""+menuURL(item)+"\""+url_target+" id=\""+item_id+"\" onMouseOver=\"menuItemOver("+item.id+")\">"+item.description+hchilds+"</a>";

	}


	// Handle menu item over event

	function menuItemOver (id) {

		// Forget if its already openned

		var
			menu = Menus[id];

		if ( menu.open ) return 0;

		// If have open brothers, hide them and his childs

		var
			family = MenuDepIds(menu.parent);

		for ( var x = 1 ; x < family.length ; x++ ) {
			var fel = family[x];
			if ((fel != id) && (Menus[fel].open)) menuHide(fel);
		}

		menuPop(id);

	}


	// Show a menu

	function menuPop (id) {

		var
			menu = Menus[id];

		// Forget pop if have no dependent items

		if ( !menu.items.length )
			return 0;

		menu.open = 1;
		menu.parent.opendepnr++;

		var
			obj = document.getElementById('mn_'+id);

		// If its not the main menu

		if ( menu.parent ) {

			var
				pos = menuPosition(id);

			// Set position

			obj.style.left = pos[0];
			obj.style.top = pos[1];

		}

		// Show

		obj.style.position = 'absolute';
		obj.style.display = 'block';

	}


	// Hide a menu

	function menuHide (id) {

		var
			menu = Menus[id],
			obj = document.getElementById('mn_'+id);

		menu.open = 0;
		menu.parent.opendepnr--;
		if ( obj != null ) {
			if ( Menus[menu.god].fancyMenus )
				menuHideFancy(id);
			else
				obj.style.display = 'none';
		}
	}

	function menuHideFancy (id) {

		var
			obj = document.getElementById('mn_'+id);

		if ( document.all ) {
			obj.style.display = 'none';
			return 0;
		}
		else if ( (obj.style.MozOpacity != "") && (obj.style.MozOpacity < 0.2) ) {
			obj.style.MozOpacity = 1;
			obj.style.display = 'none';
			return 0;
		}
		else if ( obj.style.MozOpacity == "" )
			obj.style.MozOpacity = 0.8;
		else
			obj.style.MozOpacity -= 0.2;

		setTimeout("menuHideFancy('"+id+"')",50);

	}


	// Return an array with dependent id's

	function MenuDepIds ( start ) {

		var
			menulst = new Array(),
			ids = new Array();

		menulst[0] = start;

		for ( x = 0 ; x < menulst.length ; x++ ) {
			for ( y = 0 ; y < menulst[x].items.length ; y++ )
				menulst[menulst.length] = menulst[x].items[y];
			ids[ids.length] = menulst[x].id;
		}

		return ids;

	}


	// Return menu position

	function menuPosition (id) {

		var
			menu = Menus[id],
			parent = menu.parent,

			pos = new Array(2),

			obj = document.getElementById('mn_'+id),
			pobj = document.getElementById('mn_'+parent.id),
			lobj = document.getElementById('ln_'+id).offsetParent,

			pcoords = ComponentCoords(pobj),
			pdims = ComponentDims(pobj),
			lcoords = ComponentCoords(lobj),
			ldims = ComponentDims(lobj);

		if ( parent.mode == 'horizontal' ) {
			var xdiff = -1, ydiff = -1;
			pos[0] = lcoords[0]+xdiff;
			pos[1] = pcoords[1]+pdims[1]+ydiff;
		}
		else {
			var xdiff = -3, ydiff = -5;
			pos[0] = pcoords[0]+pdims[0]+xdiff;
			pos[1] = lcoords[1]+(ldims[1]/2)+ydiff;
		}

		return pos;

	}


	// Return the right menu css style

	function menuCSS (style,menu) {

		var
			main = (menu.parent?"other":"main");

		return ((style && style[main])?style[main]:"menu");

	}


	// Return the right url for a specific menu item

	function menuURL (menu) {

		return (menu.url?menu.url:'#');

	}


	// Initialize main menu

	function menuInit (menu) {

		var
			obj = document.getElementById('mn_'+menu.id),
			childs = MenuDepIds(menu);

		// Main menu to display block

		obj.style.display = 'block';

		// Childs to display none

		for ( var x = 1 ; x < childs.length ; x++ ) {

			if ( Menus[childs[x]].items.length )
				document.getElementById('mn_'+childs[x]).style.display = 'none';
		}

	}


	// Check mouse

	function menuCheckMouse ( ) {

		for ( var x = 0 ; x < Menus.length ; x++ ) {

			var menu = Menus[x];
			if ( !(menu.parent && menu.open) ) continue;

			var
				upper = menu,
				mouseOn = 0;

			while ( upper ) {
				if ( menuMouseOn(upper.id) ) {
					mouseOn = 1;
					break;
				}
				upper = upper.parent;
			}

			if ( !mouseOn && !menu.opendepnr )
				menuHide(menu.id);

		}



		setTimeout("menuCheckMouse()",100);

	}


	// Mouse on menu

	function menuMouseOn ( id ) {

		var
			mouse = MouseCoords(),
			obj = document.getElementById('mn_'+id);

		if ( obj == null ) return 0;

		var
			pos = ComponentCoords(obj),
			dim = ComponentDims(obj),
			margin = 0;

		return !((mouse[0] < pos[0]-margin) || (mouse[0] > pos[0]+dim[0]+margin) || (mouse[1] < pos[1]-margin) || (mouse[1] > pos[1]+dim[1]+margin));

	}


	// Hide all popups

	function menuHidePopups ( ) {

		for ( var x = 0 ; x < Menus.length ; x++ ) {
			var menu = Menus[x];
			if ( menu.parent && menu.open ) menuHide(menu.id);
		}

	}


	// Check if mouse is out of menus area

	menuCheckMouse();

