// This line is to color code script in Visual Interdev <SCRIPT language="JScript">

/* Class js_MenuBar
	Arguments:
		intPixelLength = In the constructor, this will set the width of the menu buttons
	Notes:
		This is the main menu bar object.  It must be created on any page using the
		menu bar.  This requires an HTML table with one blank row to already be
		created on the HTML/ASP page it is to be added to as a place holder.
*/
function js_MenuBar( intPixelLength )
{
	/* JScript instance variable (to refer to instance in event handlers)*/
	var Self = this;
	/* Properties */
	this.Buttons = new Array();
	this.length = 0;
	this.PixelLength = intPixelLength;
	this.ActiveButton = null;
	this.MenuCluster = new js_MenuCluster();
	this.MenuTarget = null;
	this.MenuOffsetTop = 0;
	this.MenuOffsetLeft = 0;
	this.curLocation = "";
	this.StyleURL = "";
	/* Methods (prototype) */
	this.Build = Build;
	this.BuildCluster = BuildCluster;
	this.Add = Add;
	this.AddSpacer = AddSpacer;
	this.AddItemSpacer = AddItemSpacer;
	this.AddItemToMenu = AddItemToMenu;
	this.HighlightButton = HighlightButton;
	this.DeHighlightButton = DeHighlightButton;
	this.DeHighlightAll = DeHighlightAll;
	this.GetButtonFromInstance = GetButtonFromInstance;
	this.GetIndexFromButton = GetIndexFromButton;
	this.DocClick = DocClick;
	/* Methods (implement) */
	// Build ( table )
	//  Accepts an HTML table with one blank row as the argument.
	function Build( argTable )
	{
		var i;
		var objCell;
		
		Self.MenuTarget = getTarget();		
		Self.MenuCluster.Doc = Self.MenuTarget;
				
		for (i = 0; i < this.length; i++)
		{
			if (this.Buttons[i].name == "spacer")
			{
				objCell = argTable.rows(0).insertCell();
				objCell.innerText = " ";
				objCell.style.width = this.Buttons[i].width + "%";
				this.MenuCluster.AddSpacer();
			}
			else
			{
				objCell = argTable.rows(0).insertCell();
				objCell.width = this.PixelLength;
				objCell.className = "menu";
				objCell.innerHTML = this.Buttons[i].name;
				objCell.name = this.Buttons[i].name;
				objCell.id = this.Buttons[i].name;
				if (this.Buttons[i].tip)
					objCell.title = this.Buttons[i].tip;
				if (this.Buttons[i].status)
					objCell.alt = this.Buttons[i].status;
				if (this.Buttons[i].action)
					objCell.attachEvent( 'onclick', this.Buttons[i].action );

				objCell.attachEvent( 'onmouseover', HighlightButton );
			}
			this.Buttons[i].instance = objCell;
		}
		this.BuildCluster();
	}
	// BuildCluster ()
	//  This is called to create all of the DIVs that will be used as menus
	// on the main body or optionally a frame.  It just builds the HTML 
	// representation because if using frames, it's possible that the menus
	// could be destroyed by frame navigation, so they might need to be
	// rebuilt.
	function BuildCluster()
	{
		var i;
		
		for (i = 0; i < Self.length; i++)
		{
			if (Self.Buttons[i].name != "spacer")
			{
				Self.MenuCluster.AddDiv( i );
				Self.MenuCluster.Build( i );
			}
		}
		document.attachEvent( 'onclick', Self.DocClick );
		if (document.location != Self.MenuCluster.Doc.location)
		{
			Self.MenuCluster.Doc.attachEvent( 'onclick', Self.DocClick );
		}
		Self.curLocation = String (getTarget().location + getTarget().parentWindow.history.length);
	}
	// Add ( arguments )
	//  Takes button name, tool tip, status tip
	function Add( argName, argTip, argStatus, fPointer )
	{
		this.Buttons[this.length++] = new js_Button( argName, argTip, argStatus, fPointer, null );
		this.MenuCluster.Add( argName );
	}
	// AddSpacer ()
	//  This should be added at least once per menubar to keep the formatting
	// nice.  It would usually be done as the last item added, but if a 
	// menu button is wanted to be right justified on the menu bar, add it
	// after the spacer (maybe a logout button?).
	function AddSpacer( intPct )
	{
		this.Buttons[this.length++] = new js_Button( "spacer", null, null, null, intPct );
		this.MenuCluster.AddSpacer();
	}
	// AddItemToMenu ( argIndex, argName, argTip, argStatus, fPointer )
	//  Addes a menu item to the menu at position argIndex.  The next 4
	// arguments are basically the same as the Add function above.
	function AddItemToMenu( argIndex, argName, argTip, argStatus, fPointer )
	{
		this.MenuCluster.Menus[argIndex].Add( argName, argTip, argStatus, fPointer );
	}
	// AddItemSpacer ( argIndex )
	//  Adds an <HR> to a menu DIV to act as a spacer.  The argument is the
	// index.
	function AddItemSpacer( argIndex )
	{
		this.MenuCluster.Menus[argIndex].AddItemSpacer();
	}
	// HighlightButton ()
	//  No arguments as this is an event listener.
	function HighlightButton ()
	{
		var curButton = GetButtonFromInstance( window.event.srcElement );
		var curIndex = GetIndexFromButton( curButton );
		
		Self.MenuCluster.CloseAllMenus();

		Self.MenuTarget = getTarget();
		
		try {
			if (Self.curLocation != Self.MenuCluster.Doc.location + Self.MenuCluster.Doc.parentWindow.history.length)
			{
				Self.MenuCluster.Doc = getTarget();
				Self.BuildCluster();
			}
		}
		catch (e)
		{
			Self.BuildCluster();
		}
		
		if (Self.ActiveButton != curButton)
			DeHighlightAll();
				
		Self.ActiveButton = curButton;
			
		curButton.instance.className = "mouseover";
		
		if (curButton.status)
			window.status = curButton.status;
			
		// If there are no menus with this item, dehighlight when the mouse
		// goes off if it.
		if (Self.MenuCluster.Menus[curIndex].length < 1)
			curButton.instance.attachEvent( 'onmouseout', Self.DeHighlightButton );

		Self.MenuCluster.Menus[curIndex].instance.style.left = String( Self.MenuOffsetLeft + curButton.instance.offsetLeft );
		Self.MenuCluster.Menus[curIndex].instance.style.top = String( Self.MenuOffsetTop + Self.MenuCluster.Doc.body.scrollTop );
		if (Self.MenuCluster.Menus[curIndex].length > 0)
			Self.MenuCluster.Menus[curIndex].instance.style.display = "block";
	}
	// DeHighlightButton ()
	//  Another event listener added dynamically.  Dehighlights a button and
	// hides the menu (unless the menu is the target of the mousemovement).
	function DeHighlightButton ()
	{
		var curIndex = GetIndexFromButton( Self.ActiveButton );
				
		window.event.srcElement.className = "menu";

		window.status = "";
		Self.MenuCluster.Menus[curIndex].instance.style.display = "none";
				
		Self.ActiveButton = null;
	}
	// DeHighlightAll ()
	//  Changes all menu buttons' classes back to the default, "menu".
	function DeHighlightAll()
	{
		var i;
				
		for (i = 0; i < Self.length; i++)
		{
			if (Self.Buttons[i].name != "spacer")
				Self.Buttons[i].instance.className = "menu";
		}
		window.status = "";
		Self.MenuCluster.CloseAllMenus();
	}
	// GetButtonFromInstance (argument that evals to an instance)
	//  Get's the code object manifestation of the menu button table
	// cell using the table cell as a reference.
	function GetButtonFromInstance( argCell )
	{
		var i;

		for (i = 0; i < Self.length; i++)
		{
			if (argCell == Self.Buttons[i].instance)
				return Self.Buttons[i];
		}
		return null;
	}
	// GetIndexFromButton ( Button object )
	//  This function may be used to reliably obtain the buttons index
	// in the Buttons array (rather than saving the index as a property
	// of the MenuButton item, which may be less reliable).
	function GetIndexFromButton( argBtn )
	{
		var i;
				
		for (i = 0; i < Self.length; i++)
		{
			if (argBtn == Self.Buttons[i])
				return i;
		}
		return null;
	}
	// DocClick
	//  If any where on the window is clicked, close the menus.
	function DocClick()
	{
		Self.DeHighlightAll();
		Self.MenuCluster.CloseAllMenus();
	}
}
		
/* Class js_Button
	Arguments:
		argName = Text shown on menu button
		argTip = Tool tip to appear on mouse over
		argStatus = Message to appear in status bar
		fPointer = Pointer to a function to run when clicked
	Notes:
		This object is not too complex.  It's mostly a reference to the table
		cell that is its manifestation on the page.  
*/
function js_Button( argName, argTip, argStatus, fPointer, argPct )
{
	/* Properties */
	this.name = argName;
	this.tip = argTip;
	this.status = argStatus;
	this.instance = null;
	this.action = fPointer;
	this.width = argPct;
}

/* Class js_MenuCluster
	Arguments:
		None
	Notes:
		The Menu Cluster is a way to tie all of the DIV menu elements together
		in one package, exposing methods and properties to manipulate them.
*/
function js_MenuCluster( )
{
	/* JScript instance variable (to refer to instance in event handlers)*/
	var Self = this;
	/* Properties */
	this.Menus = new Array();
	this.ActiveMenu = null;
	this.length = 0;
	this.Doc = null;
	/* Methods (prototype) */
	this.Add = Add;
	this.AddDiv = AddDiv;
	this.AddSpacer = AddSpacer;
	this.Build = Build;
	this.CloseAllMenus = CloseAllMenus;
	/* Methods (implement) */
	function Add( argName )
	{
		this.Menus[this.length++] = new js_Menu( argName );
	}
	// AddDiv (argIndex)
	//  AddDiv creates the actual menu DIV element on the target document. 
	// Index refers to which menu to currently add.
	function AddDiv( argIndex )
	{
		var newDiv;
		//alert ("Add div called");	
		try {
			Self.Doc.body.insertAdjacentHTML( 
				"AfterBegin", "<DIV id='" + Self.Menus[argIndex].name + "' class='menu_closed'>" +
				"<TABLE id='table_" + Self.Menus[argIndex].name + "' cellpadding='0' cellspacing='0' border='0'><TABLE>" +
				"</DIV>" 
			);

			newDiv = this.Doc.getElementById( Self.Menus[argIndex].name );
					
			Self.Menus[argIndex].instance = newDiv;
			Self.Menus[argIndex].Table = newDiv.children(0);
		}
		catch (e) {
			window.location.reload();
		}
	}
	function AddSpacer()
	{
		this.Menus[this.length++] = null;
	}
			
	function Build( argIndex )
	{
		var i;
		var newCell;
				
		for (i = 0; i < Self.Menus[argIndex].length; i++)
		{
			Self.Menus[argIndex].Table.insertRow();
			newCell = Self.Menus[argIndex].Table.rows(i).insertCell();
			if (Self.Menus[argIndex].MenuItems[i].name == "spacer")
			{
				newCell.innerHTML = "<HR>";
			}
			else
			{
				newCell.innerHTML = "<NOBR>" + Self.Menus[argIndex].MenuItems[i].name + "</NOBR>";
				newCell.className = "menu_item";
				newCell.attachEvent( 'onmouseover', Self.Menus[argIndex].MenuItems[i].MouseOver );
				newCell.attachEvent( 'onmouseout', Self.Menus[argIndex].MenuItems[i].MouseOut );
				Self.Menus[argIndex].MenuItems[i].instance = newCell;
				if (Self.Menus[argIndex].MenuItems[i].tip)
					newCell.title = Self.Menus[argIndex].MenuItems[i].tip;
				if (Self.Menus[argIndex].MenuItems[i].action)
					newCell.attachEvent( 'onclick', Self.Menus[argIndex].MenuItems[i].action );
			}
		}
	}
			
	function CloseAllMenus()
	{
		var i;
				
		for (i = 0; i < Self.length; i++)
		{
			if (Self.Menus[i])
				Self.Menus[i].instance.style.display = "none";
		}
	}
}
		
/* Class js_Menu
	Arguments:
		argName = Name of the menu for reference.  Will usually be the name of
			the menu button.
	Notes:
		This is the singular item to be included in the MenuCluster menus collection.
		It includes pointers to its DIV element and table child.
*/
function js_Menu( argName )
{
	/* Properties */
	this.MenuItems = Array();
	this.name = argName;
	this.length = 0;
	this.instance = null;
	this.Table = null;
	/* Methods (prototype) */
	this.Add = Add;
	this.AddItemSpacer = AddItemSpacer;
	/* Methods (implement) */
	function Add( argName, argTip, argStatus, fPointer )
	{
		this.MenuItems[this.length++] = new js_MenuItem( argName, argTip, argStatus, fPointer );
	}
	function AddItemSpacer()
	{
		this.MenuItems[this.length++] = new js_MenuItem( "spacer", null, null, null );
	}
}
		
/* Class js_MenuItem
	Arguments:
		argName = Text to be shown on menu
		argTip = Tool tip
		argStatus = Message for status bar
		fPointer = Action to run when clicked
	Notes:
		This is the class for the menu option.
*/
function js_MenuItem( argName, argTip, argStatus, fPointer )
{
	/* JScript instance variable (to refer to instance in event handlers)*/
	var Self = this;
	/* Properties */
	this.name = argName;
	this.tip = argTip;
	this.status = argStatus;
	this.instance = null;
	this.action = fPointer;
	/* Methods (prototype) */
	this.MouseOver = MouseOver;
	this.MouseOut = MouseOut;
	/* Methods (implement) */
	function MouseOver()
	{
		Self.instance.className = "menu_item_highlight";
		if (Self.status)
			window.status = Self.status;
	}
	function MouseOut()
	{
		Self.instance.className = "menu_item";
	}
}

/* Helper functions */
    function getObj( theObj )
    {
      var thePos = { x:0, y:0 };
      do
      {
		thePos.x += theObj.offsetLeft;
		thePos.y += theObj.offsetTop;
		theObj = theObj.offsetParent;
      } while(theObj);
      return(thePos)
    }

	function getTarget()
	{
		return document;
	}
