function G6Menu (ID, MenuMaker)
{
	var ARG_LENGTH = 2;
	this.MM = MenuMaker;
	this.ID = ID;

	this.Level = 0;
	this.IsOpen = 0;

	this.Dad = (MenuMaker == null) ? this : null;
	
	this.SubMenu = new Array ();
	this.SubMenuByName = new Object ();

	this.SubMenuCBE = null; // The CBE for the div containing the submenu.
	this.SubMenuID = null; // The Div ID of the submenu holder.
	this.ItemCBE = null; // The CBE for the individual menu item.
	this.ItemID = null; // The Div ID of the item.


	if (this.IsMenu = (arguments.length > ARG_LENGTH))
	{
		for (var i = ARG_LENGTH, n; i < arguments.length; i++)
		{
			n = i - ARG_LENGTH;
			this.SubMenu.push(arguments[i]);
			this.SubMenu[n].Num = n;
			if (ID != "auto")
			{
				this.SubMenuByName[this.SubMenu[n].ID] = this.SubMenu[n];
			}
		}
	}
	
	// Public Methods:
	
	this.Init = function (Mom)
	{
		var SM;
		if (Mom)
		{
			this.Mom = Mom; // Mom is the parent object
		} else {
			this.Mom = null;
		}
		
		// Make sure each menu knows who the root menu is.
		if (!this.Dad)
		{
			this.Dad = Mom.Dad;
		}
		
		// If the ID is "auto" it will be generated automatically:
		if (this.ID == "auto")
		{
			// Generate an ID of form: "ID########"
			this.ID = "ID" + Math.round(10000000 * Math.random ());
		}

		//alert (this.IsMenu + " " + this.MM);

		
		if (this.IsMenu)
		{
			var L = this.SubMenu.length;
			
			for (var i = 0; i < L; i++)
			{
				
				SM = this.SubMenu[i];

				SM.Level = this.Level + 1;
				SM.Init (this);
			}	
		}
		
		
		if (this.Preselected)
		{
			if (Mom)
			{
				Mom.Preselect ();
			}
			
			// Tell the Dad that the bottom level preselected item is
			// this one.  There can only be one, and that one will be
			// the lowest level.
			if (!this.Dad.PreselectedItem)
			{
				this.Dad.PreselectedItem = this;
			}
		}

		if (this.MM)
		{
			if (this.MM.Init)
			{
				this.MM.Init (this);
			}
		
			if (this.IsMenu)
			{
				this.MM.Make ();
				
			}
		} else {
			// Install post-CBE initialization timeout so that variables 
			// can be properly configured for CBE
			
			if (!window.G6MenuLoaderArray)
			{
				window.G6MenuLoaderArray = new Array ();
			}
			
			window.G6MenuLoaderArray.push (this);
			
			//var T = this;
			//var TO_CBE;
			//this.TO_CBE = TO_CBE = window.setTimeout (function () { T.InitCBE (); window.clearTimeout (TO_CBE); }, 1);
		}
	}
		
	this.Preselect = function  ()
	{
		this.Preselected = 1;
	}



	// Private Methods:

	this.InitCBE = function ()
	{
		this.Dad.CreateCBEObjects ();
		document.cbe.addEventListener('mousemove', this.MouseOver, false, this);
		//alert ("InitCBE called");
		this.Revert ();
	}
	

	this.CreateCBEObjects = function ()
	{
		// Start the recursion:

		for (var L = this.SubMenu.length, i = 0, SM; i < L; i++)
		{
			SM = this.SubMenu[i];
			if (SM.IsMenu)
			{
				SM.CreateCBEObjects ();
			}
		}
		
		if (this.IsMenu)
		{
			// If this is not a top-level menu:
			if (this.MM)
			{
				
				this.SubMenuCBE = document.getElementById(this.SubMenuID).cbe;
				//alert (this.SubMenuID);
				this.SubMenuCBE.MenuTarget = this;
				
				// Each menu made has a sub div tag for each item in order 
				// to determine what Y coordinant to draw the submenu from.
				// However to detect whether the mouse is over the current active
				// menu, the sub divs need to have their MenuTarget set to their
				// parent div or point to their respective submenu in order to
				// open up the menu.
				
				for (L = this.SubMenu.length, i = 0, SM; i < L; i++)
				{
					SM = this.SubMenu[i];
					SM.ItemCBE = document.getElementById(SM.ItemID).cbe;
					if (SM.IsMenu)
					{
						SM.ItemCBE.MenuTarget = SM;
					} else {
						SM.ItemCBE.MenuTarget = this;
					}
					
				}
				
				if (!this.Dad.AllCBE)
				{
					this.Dad.AllCBE = new Array ();
				} 
				this.Dad.AllCBE.push(this.SubMenuCBE); // Add the div to the base tree.

			} else {
				// This is the top:
				for (L = this.SubMenu.length, i = 0, SM; i < L; i++)
				{
					//alert (this.SubMenu[i].ID + " " + this.SubMenu[i].Label);
					SM = this.SubMenu[i];
					SM.ItemCBE = document.getElementById(SM.Label).cbe;
					if (SM.IsMenu)
					{
						SM.ItemCBE.MenuTarget = SM;
					} else {
						SM.ItemCBE.MenuTarget = this;
					}
				}
			}
			
		}

	}		




	this.MouseOver = function  (Target)
	{
		var T = Target.cbeTarget.MenuTarget;
		var AD = this.Dad.AllCBE;
		var IsMenu = 0;
		
		// If T == Menu.  The target would not have a MenuTarget if
		// it were not a menu
		
		if (T)
		{
			// Clear any timeouts:
			this.TimedRevertStop ();
			
			if (T != this.Dad.ActiveMenu)
			{
				this.Dad.ActiveMenu = T;
				T.Open ();
			} 
		} else {
			// If not, begin to revert to the default state:
			if (this.Dad.ActiveMenu && !this.TO)
			{
				this.Dad.TimedRevertBegin ();
			}
		}
	}

	this.TimedRevertBegin = function ()
	{
		var T = this;
		var TO;
		this.TO = TO = window.setTimeout (function () { T.Revert (); window.clearTimeout (TO); }, 1000);
	}

	this.TimedRevertStop = function ()
	{
		if (this.TO)
		{
			window.clearTimeout (this.TO);
			this.TO = 0;
		}
	}

	this.Open = function ()
	{
		// Hide everything:
		this.HideAll ();
		// Show the menus that are to be opened:
		this.Show ();
		// Update their positions, etc.
		this.Dad.Render ();
	}

	this.Revert = function ()
	{
		this.Dad.ActiveMenu = null;
		this.HideAll ();
		if (this.Dad.Preselected)
		{
			this.Dad.PreselectedItem.Show ();
		}
		this.Dad.Render ();
	}

	this.HideAll = function ()
	{
		this.Dad.Hide ();
		//this.Dad.ShowPreselected ();
	}

	// Show the tree up to target item:
	this.Show = function ()
	{
		this.IsOpen = 1;
		if (this.IsMenu && this.MM)
		{
			this.MM.Show ();
		}
		
		if (this.Mom != null)
		{
			this.Mom.Show ();
		}
	}

	// Hide target menu and all submenus:
	this.Hide = function ()
	{
		for (var L = this.SubMenu.length, i = 0, SM; i < L; i++)
		{
			SM = this.SubMenu[i];
			if (SM.IsMenu)
			{
				SM.Hide ();
			}
		}
		if (this.IsMenu && this.MM)
		{
			this.MM.Hide ();
		}
		this.IsOpen = 0;
	}

	this.Render = function ()
	{
		if (this.IsMenu && this.IsOpen)
		{
		
			if (this.MM)
			{
				this.MM.Render ();
			}
			for (var L = this.SubMenu.length, i = 0; i < L; i++)
			{
				this.SubMenu[i].Render ();
			}
		}
	}
}

function G6MenuLoad ()
{
	cbeInitialize("DIV", "SPAN"); 
	if (window.windowOnload) 
	{
		window.windowOnload();
	}
	
	for (var i = 0; i < window.G6MenuLoaderArray.length; i++)
	{
		window.G6MenuLoaderArray[i].InitCBE ();
	}
}



window.onload = G6MenuLoad;

// If you override the onload somewhere else, add the G6MenuLoad to it.



var G6_RIGHT 				= 0;
var G6_BOTTOM 				= 1;
var G6_TOP					= 2;
var G6_LEFT					= 3;

function NullLink (Title, ItemLink)
{
	this.Title = Title;
	this.ItemLink = ItemLink;
}


function StandardBlockMenu (Title, ItemLink, Position, Label)
{
	this.Position = Position;
	this.Title = Title;
	this.ItemLink = ItemLink;
	if (Label)
	{
		this.Label = Label;
	}
	
	this.Init = function (Data)
	{
		this.Data = Data;
		this.Data.Label = this.Label;
	}
	
	this.Make = function ()
	{
		var S = "", ItemLink, SM, ItemID;
		var ID = this.Data.ID + Math.round(10000000000 * Math.random ());
		this.Data.SubMenuID = ID;
		S += "<div id='" + ID + "' style='visibility: hidden; position: absolute;  z-index: " + this.Data.Level + ";'>";
		S += "<table border='0' cellspacing='0' cellpadding='0'  class='ESMenuTable'>";
		S += "<tr><td>";
		for (var L = this.Data.SubMenu.length, i = 0; i < L; i++)
		{
			SM = this.Data.SubMenu[i];
			
			ItemID = (ID + "_" + i);
			SM.ItemID = ItemID;
			SM.ClassName = "MenuLevel1";
			ItemLink = (SM.MM.ItemLink == null) ? "#" : SM.MM.ItemLink;
			S += "<div id='" + ItemID + "' class='MenuLevel1'>";
			S += "<table border='0' cellspacing='0' cellpadding='0' width='100%'>";
			S += 
				"<tr>" + 
					"<td width='8'><img src='images/spacer.gif' alt='' width='8' height='8' border='0'></td>" +
					"<td nowrap>" +
						"<a href='" + ItemLink + "'>" + SM.MM.Title + 
						"</a>" +
					"</td>" +
					"<td width='12'><img src='images/spacer.gif' alt='' width='12' height='8' border='0'></td>" +
				"</tr>";
			S += "</table></div>";
	
		}
		
		S += "</td></tr>";
		S += "</table></div>";
		document.write (S);
	}
	
	this.Show = function ()
	{
		this.Data.SubMenuCBE.show ();
	}

	this.Hide = function ()
	{
		this.Data.SubMenuCBE.hide ();
		for (var i = 0, SM; i < this.Data.SubMenu.length; i++)
		{
			SM = this.Data.SubMenu[i];
			SM.ItemCBE.ele.className = SM.ClassName;
		}
			
	}

	this.Render = function ()
	{
		var MomSubMenu = this.Data.Mom.SubMenuCBE ? this.Data.Mom.SubMenuCBE : this.Data.ItemCBE;
		switch (this.Position)
		{
			case G6_RIGHT:
				this.Data.SubMenuCBE.moveTo 
				(
					this.Data.ItemCBE.pageX () + this.Data.ItemCBE.width (), 
					MomSubMenu.pageY ()
				);
			break;
			case G6_LEFT:
				this.Data.SubMenuCBE.moveTo 
				(
					this.Data.ItemCBE.pageX () - this.Data.SubMenuCBE.width (), 
					MomSubMenu.pageY ()
				);
			break;
			case G6_TOP:
				this.Data.SubMenuCBE.moveTo 
				(
					MomSubMenu.pageX (), 
					this.Data.ItemCBE.pageY () - this.Data.SubMenuCBE.height ()
				);
			break;
			case G6_BOTTOM:
				this.Data.SubMenuCBE.moveTo 
				(
					MomSubMenu.pageX (), 
					this.Data.ItemCBE.pageY () + this.Data.ItemCBE.height ()
				);
			break;
		}
		
		this.Highlight ();
		
	}
	
	this.Highlight = function ()
	{

		for (var i = 0, SM; i < this.Data.SubMenu.length; i++)
		{
			SM = this.Data.SubMenu[i];
			if (SM.Preselected)
			{
				SM.ItemCBE.ele.className = SM.ClassName + "Preselected";
			} else if (SM.IsOpen) 
			{
				SM.ItemCBE.ele.className = SM.ClassName + "Highlighted";
			}
		}

		
		//this.Data.ItemCBE.ele.className = this.Data.ClassName + "Highlighted";
		//if (this.Data.Preselected && this.Preselect)
		//{
		//	this.Preselect ();
		//}
		
	}
	
	//this.Preselect = function ()
	//{
	//	for (var i = 0, SM; i < this.Data.SubMenu.length; i++)
	//	{
	//		SM = this.Data.SubMenu[i];
	//		SM.ItemCBE.ele.className = SM.ClassName + "Highlighted";
	//		this.Data.ItemCBE.ele.className = this.Data.ClassName + "Preselected";
	//	}
	//}
}



