// JavaScript Document: New Menus.js
//
//		Very simple menus.
//
// Revision History:
//	2006-08-18	ML	New file.
//	2006-09-16	ML	Added "getCssAttrValue()".
//
var numofitems = 6;					// Number of top level menu items. ML: should come from .css.
var emod;							// The event model.

//menu constructor
function menu( allitems, thisitem, startstate )
	{ 
  	var callname= "gl" + thisitem;
  	var divname="subglobal" + thisitem;  
  	this.numberofmenuitems = allitems;
  	this.caller = document.getElementById( callname );
  	this.thediv = document.getElementById( divname );
 	this.thediv.style.visibility = startstate;
	// Easier to handle submenus if each menu item has a number.
	this.thediv.thisitem = thisitem;
	// Initialize number of submenu items to 0. Not an ideal solution because it means you must construct
	// menu items before you construct the submenu items.
 	this.thediv.numberofmenuitems = 0;
	}

// submenu constructor
function submenu( parent, submenu, allitems, thisitem, startstate )
		// parent, submenu, # of submenu items, this item, initial state.
	{ 
  	// ML: Don't like resetting the numberof menuitems on every call, but this will have to do for now.
	var callname= parent;
  	var divname = submenu + "_" + thisitem;  
  	this.numberofmenuitems = allitems;
  	this.caller = document.getElementById( callname );
	// Update the calling menu item's number of [sub]menu items.
  	this.caller.numberofmenuitems = allitems;
	this.thediv = document.getElementById( divname );
 	this.thediv.style.visibility = startstate;
	this.thediv.thisitem = thisitem;
	}

// Menu methods
function ehandler( event, theobj )
	{
	var mhead_bg_color = 0xffffff;
	var subdiv;						// Used for storing submenu item info.
	
	// Get the "backgroundColor" attribute of the CSS "#masthead" style. This assumes that the 
	// menu items live in the masthead section of the page.
	// ML: Would be more general to have an explicit "unselected" color in the .css.
	mhead_bg_color = getCssAttrValue( "#masthead", "backgroundColor" );
	
	// event.type indicates the type of event, e.g. "mouseover".
	// theobj.caller.id identifies the global menu (or submenu) item that triggered the event.
	for ( var i = 1; i <= theobj.numberofmenuitems; i++ )
		{
		// Hide any subglobal menus that might be visible.
		// The "eval" is necessary to create the string object.
		var shutdiv = eval( "menuitem" + i + ".thediv" );
		shutdiv.style.visibility = "hidden";
		
		// Hide any submenus.
		for ( var j = 1; j <= shutdiv.numberofmenuitems; j++ )
			{
			subdiv = eval( "submenuitem" + shutdiv.thisitem + "_" + j );
			subdiv.thediv.style.visibility = "hidden";
			}
		// Reset all global menu items to "unselected" color. 
		var glitem = document.getElementById( "gl" + i );
		glitem.style.backgroundColor = mhead_bg_color;
		}
	
	// Make the correct subglobal menu visible.
	theobj.thediv.style.visibility = "visible";
	// Make the submenu items visible.
	for ( j = 1; j <= theobj.thediv.numberofmenuitems; j++ )
		{
		subdiv = eval( "submenuitem" + theobj.thediv.thisitem + "_" + j );
		subdiv.thediv.style.visibility = "visible";
		}
	
	// Change the background color of the correct global menu item (0xD4EFEE).
	// ML: should move all browser-dependent code to separate .js file.
	// ML: All color info should come from .css file.
	if (navigator.appName == "Netscape")
		{
		// When running JavaScript, Netscape browsers use the string value to do a table lookup,
		// so we can't use a literal hex value. All browsers seem to handle literal hex values in .css
		// files correctly.
		theobj.caller.style.backgroundColor = "ivory";
		}
	else
		theobj.caller.style.backgroundColor = 0xF0F0F0;
	}

// ML: A quick hack. I think if the cursor is over a submenu, you don't need to hide other submenus, as you 
// ML: can take care of that when the cursor moves to another menu item or leaves the masthead.
function subMenuEvent( event, theobj )
	{
	var mhead_bg_color = 0xffffff;
	var subdiv;						// Used for storing submenu item info.
	
	// Get the "backgroundColor" attribute of the CSS "#masthead" style. This assumes that the 
	// menu items live in the masthead section of the page.
	// ML: Would be more general to have an explicit "unselected" color in the .css.
	mhead_bg_color = getCssAttrValue( "#masthead", "backgroundColor" );
	
	// event.type indicates the type of event, e.g. "mouseover".
	// theobj.caller.id identifies the global menu (or submenu) item that triggered the event.

	// Make the correct subglobal menu visible.
	theobj.thediv.style.visibility = "visible";
	// Make the submenu items visible.
	for ( j = 1; j <= theobj.thediv.numberofmenuitems; j++ )
		{
		subdiv = eval( "submenuitem" + theobj.thediv.thisitem + "_" + j );
		subdiv.thediv.style.visibility = "visible";
		}
	
	// Change the background color of the correct global menu item (0xD4EFEE).
	// ML: should move all browser-dependent code to separate .js file.
	// ML: All color info should come from .css file.
	if (navigator.appName == "Netscape")
		{
		// When running JavaScript, Netscape browsers use the string value to do a table lookup,
		// so we can't use a literal hex value. All browsers seem to handle literal hex values in .css
		// files correctly.
		theobj.caller.style.backgroundColor = "ivory";
		}
	else
		theobj.caller.style.backgroundColor = 0xF0F0F0;
	}

function closesubnav(event)
	{
	// ML: Instead of getting mousemove events for whole body, should just define areas for menus and submenus.
	if ( ( event.clientY < 18 ) || ( event.clientY > 300 ) )
		{
		for ( var i=1; i <= numofitems; i++ )
			{
			// Hide any subglobal menus that might be visible.
			var shutdiv = eval('menuitem'+i+'.thediv');
			shutdiv.style.visibility='hidden';
			}
		}
	return true;
	}

function getMenuHoverBgColor()
	{
	}

function getCssAttrValue( g_style, g_attribute )
//
// Returns requested attribute of a style or "null", if not found. NOTE: "null" return value does not necessarily
// indicate an error; it may just be the value of the attribute.
// ML: Should do some error checking on the values of the args, but I'm sure what to check, except that they're both
// ML: character strings.
	{
	var ret_attr = null;	// Used to hold the constructed reference to the attribute to return.
	var done = false;
	
	for ( var i = 0; i < document.styleSheets.length && !done; i++)
		{
		if (navigator.appName == "Microsoft Internet Explorer")
			{
			// Microsoft browsers.
			for ( var j = 0; j < document.styleSheets[i].rules.length && !done; j++ )
				{
				if (document.styleSheets[i].rules[j].selectorText == g_style)
					{
					ret_attr = eval( 'document.styleSheets[i].rules[j].style.' + g_attribute );
					done = true;		// We're done.
					}
				}
			}
		else
			{
			// Other browsers.
			for ( var j = 0; j < document.styleSheets[i].cssRules.length && !done; j++ )
				{
				if (document.styleSheets[i].cssRules[j].selectorText == g_style)
					{
					ret_attr = eval( 'document.styleSheets[i].cssRules[j].style.' + g_attribute );
					done = true;		// We're done.
					}
				}
			}
		}
	return( ret_attr );
	}

// Test code
function onclickH(e)
	{
    var alert_string = "Event model: "+emod+"\n";

	switch (emod)
		{
		case "NN4":
			alert_string += "pageX: "+e.pageX+"\n";
			alert_string += "pageY: "+e.pageY+"\n";
			alert_string += "target.href: "+e.target.href+"\n";
			alert_string += "target.text: "+e.target.text+"\n";
			alert_string += "type: "+e.type+"\n";
			break;
		case "W3C":
			alert_string += "clientX: "+e.clientX+"\n";
			alert_string += "clientY: "+e.clientY+"\n";
			alert_string += "target.href: "+e.target.href+"\n";
			alert_string += "target.text: "+e.target.text+"\n"; 
			alert_string += "type: "+e.type+"\n";
			break;
		case "IE4+":
			e = window.event;
			alert_string += "clientX: "+e.clientX+"\n";
			alert_string += "clientY: "+e.clientY+"\n";
			alert_string += "srcElement.href "+e.srcElement.href+"\n";
			alert_string += "srcElement.innerText "+e.srcElement.innerText+"\n";
			alert_string += "type: "+e.type+"\n";
		}
/*	alert(alert_string);	*/
	return true;
	}

//
// Test code: Events are different in Netscape-based browsers.
function onloadH(e)
	{
	// Original code from webmonkey is wrong. For IE, "e" is defined, but "e.eventPhase" is not. I think this new version is correct, 
	// but I have only tested it w/ IE 6 (IE4+), Firefox 1.5 (NN4), & Opera 9.0 (W3C).
	// mod = (e) ? (e.eventPhase) ? "W3C" : "NN4" : (window.event) ? "IE4+"  : "unknown";
	if (window.event)
		{
		if (e)
			{
			if (e.eventPhase)
				emod = "W3C";
			else
				emod = "IE4+";
			}
		else
			"unknown";
		}
	else
		emod = "NN4";
	if (emod == "NN4")
		document.captureEvents(Event.CLICK);
	document.onclick = onclickH;

	return true;
	}
