

//============================================================================
// Constants = Values that are dependent on other settings
var POPSUBMENU_GRAPHIC_HEIGHT = 7;
var POPSUBMENU_GRAPHIC_WIDTH = 7;
var POPSUBMENU_GRAPHIC_MARGIN = 10;
var POPMENU_ZINDEX_DEFAULT = 30;

//============================================================================
// Constants = Values that are independent of other settings
var POPMENU_ID = "PopMenu";
var POPMENUITEM_ID = "MenuItem";
var POPMENU_SUBIMG_ID = "SubImg";
var POPMENU_NSFRAME_ID = "NSFrame";
var POPSUBMENU_OVERLAP = 5;
var POPSUBMENU_DROP = 5;
var TEST_POPMENUITEM_ID = "PopMenuTest";
var TRUE = 0;
var FALSE = 1;

//============================================================================
// Global variables and their defaults
var g_PopBgColor = "#FFFFCC";
var g_PopSelBgColor = "#CCFFFF";
var g_PopBorderSize = 1;
var g_strPopMenuGraphicsDir = "graphics/";
var g_PopActionDestSelf = false;

//============================================================================
// Functions to be called during the program

/*----------------------------------------------------------------------------
Description: Set the directory to get graphics from
Parameters : a_strGraphicsDir inputs the directory to get graphics from
----------------------------------------------------------------------------*/
function initPopMenuGraphics( a_strGraphicsDir )
{
	g_strPopMenuGraphicsDir = a_strGraphicsDir;
}

/*----------------------------------------------------------------------------
Description: Creates a pop up menu 
Parameters : a_strTitle inputs the name of the menu
Returns	   : A pop menu object
Comments   : The title appears in any parent popup menus
----------------------------------------------------------------------------*/
function createPopMenu( a_strTitle )
{
	// Setup the menu container
	if( !this.PopMenuContainer )
		this.PopMenuContainer = new Array();
		
	// Create a new menu and return it
	this.PopMenuContainer[ this.PopMenuContainer.length ] = new createPopMenuObject( a_strTitle, this.PopMenuContainer.length );
	return this.PopMenuContainer[ this.PopMenuContainer.length - 1 ];
}

/*----------------------------------------------------------------------------
Description: Creates the popup menu object to be used
Parameters : a_strText inputs the text for this container
			 a_nIndex inputs this objects place in the menu list
----------------------------------------------------------------------------*/
function createPopMenuObject( a_strText, a_nIndex )
{
	this.popMenuItems = new Array();		// Array of menu items
	this.Text = a_strText;					// Text to display
	this.Action = "";						// Action to take when this item is clicked on
	this.addPopMenuItem = addPopMenuItem;   // Add a menuitem to this object function
	this.parent = "";						// Track who the parent is
	this.closeWindow = TRUE;				// The closing of the window can be halted once started
	this.Index = a_nIndex;					// Menu number
	this.width = 0;							// The width of the container
	this.setPopMenuWidth = setPopMenuWidth;	// Function to change the width
}

/*----------------------------------------------------------------------------
Description: Adds a menu item to a pop up menu list
Parameters : a_strText inputs the menu title or a submenu object
			 a_strAction inputs the action to take when this menu item is clicked
Comments  : Action is programmed as a website
----------------------------------------------------------------------------*/
function addPopMenuItem( a_strText, a_strAction )
{
	// Check if it is a submenu
	if( a_strText.popMenuItems )
	{
		// Menuitem is a submenu
		this.popMenuItems[ this.popMenuItems.length ] = a_strText;
		a_strText.Action = a_strAction;
		a_strText.parent = this;
	}
	else
		this.popMenuItems[ this.popMenuItems.length ] = new createPopMenuItemObject( a_strText, a_strAction, this );
}

/*----------------------------------------------------------------------------
Description: Creates an object for a menu item
Parameters : a_strText inputs the title of the menu item
			 a_strAction inputs the action for the menu item to take when clicked
			 a_popMenuParent inputs the container of this menu item
----------------------------------------------------------------------------*/
function createPopMenuItemObject( a_strText, a_strAction, a_popMenuParent )
{
	this.Text = a_strText;				// Text to display
	this.Action = a_strAction;			// Action to take when this item is clicked on
	this.parent = a_popMenuParent;		// Parent of this menu item
}

/*----------------------------------------------------------------------------
Description: Performs step to create and setup the pop up menus
Parameters : a_BgColor inputs the background color
			 a_SelBgColor inputs the select color when mouse is over a menu item
			 a_nBorderSize inputs the size of the container border
Comments   : Colors had to be passed because of NS quirk
----------------------------------------------------------------------------*/
function initPopMenu( a_BgColor, a_SelBgColor, a_nBorderSize )
{
	// Setup globals
	g_PopBgColor = a_BgColor;
	g_PopSelBgColor = a_SelBgColor;
	g_PopBorderSize = a_nBorderSize;

	// Create and position menus
	writePopMenuHTML();
	posPopMenuItems();
}

/*----------------------------------------------------------------------------
Description: Puts together the html to create the popup menus
Comments   : Outputs HTML to the main window
----------------------------------------------------------------------------*/
function writePopMenuHTML()
{
	// Because some values are readonly once set we need to compute values now and 
	// set them in the html.  We create a temp popmenu which is used to get style
	// values for computations. Align graphic right to use up entire space
	var strOutput = '<DIV ID="' + TEST_POPMENUITEM_ID + '" CLASS="PopMenuItemStyle">';
	strOutput += '<IMG SRC="' + g_strPopMenuGraphicsDir + 'Empty.gif" WIDTH=' + POPSUBMENU_GRAPHIC_WIDTH + ' HEIGHT=' + POPSUBMENU_GRAPHIC_HEIGHT + ' BORDER=0 ALT="" ALIGN="RIGHT" VALIGN="MIDDLE"><font color="#FFFFFF">test</font></DIV>';
	document.write( strOutput );
	
	// Hide the test
	if( document.all )


		this[ TEST_POPMENUITEM_ID ].style.visibility = "hidden";
	else
		document[ TEST_POPMENUITEM_ID ].visibility = "hidden";
		
	// Create the pop menus in the list
	strOutput = "";
	for( var nIndex = 0; nIndex < this.PopMenuContainer.length; nIndex++ )
	{
		// Get the menu to be created
		var menuCurrent = this.PopMenuContainer[ nIndex ];
		
		// Create the menu container
		strOutput += '<DIV ID="' + POPMENU_ID + nIndex + '" CLASS="PopMenuContainerStyle">';
		
		// Loop through the menu items
		for( var nItemIndex = 0; nItemIndex < menuCurrent.popMenuItems.length; nItemIndex++ )
		{
			// Base for each submenu; added empty gif for NS to fill in the whole area
			strOutput += '<DIV ID="' + POPMENU_ID + nIndex + POPMENUITEM_ID + nItemIndex + '" CLASS="PopMenuItemStyle">';
			strOutput += '<IMG SRC="' + g_strPopMenuGraphicsDir + 'Empty.gif" WIDTH=' + POPSUBMENU_GRAPHIC_WIDTH + ' HEIGHT=' + POPSUBMENU_GRAPHIC_HEIGHT + ' BORDER=0 ALT="" ALIGN="RIGHT">';
			strOutput += '&nbsp;&nbsp;' + menuCurrent.popMenuItems[ nItemIndex ].Text + '</DIV>';
			
			// Add graphic
			if( menuCurrent.popMenuItems[ nItemIndex ].popMenuItems )
				strOutput += '<DIV ID="' + POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex + '" CLASS="PopMenuGraphicStyle"><IMG SRC="' + g_strPopMenuGraphicsDir + 'SubMenu.gif" WIDTH=' + POPSUBMENU_GRAPHIC_WIDTH + ' HEIGHT=' + POPSUBMENU_GRAPHIC_HEIGHT + ' BORDER=0 ALT=""></DIV>';
		} 
				
		// End menu container
		strOutput += "</DIV>";
	} 

	// Output the menu
	document.write( strOutput );
}

/*----------------------------------------------------------------------------
Description: Positions the menu elements on the screen
----------------------------------------------------------------------------*/
function posPopMenuItems()
{
	// Find out height of menu items
	var nHeight;
	var nWidth = 0;
	if( document.all )
	{
		nHeight = this[ TEST_POPMENUITEM_ID ].offsetHeight;
		nWidth = this[ TEST_POPMENUITEM_ID ].offsetWidth;
	}
	else
	{
		nHeight = document[ TEST_POPMENUITEM_ID ].clip.height;
		nWidth = document[ TEST_POPMENUITEM_ID ].clip.width;
	}
		
	// Go through menus and pos menu items
	for( var nIndex = 0; nIndex < this.PopMenuContainer.length; nIndex++ )
	{
		// Get the menu 
		var menuCurrent = this.PopMenuContainer[ nIndex ];
		var menuDiv;
		if( document.all )
			var menuDiv =  this[ POPMENU_ID + nIndex ].style;
		else
			var menuDiv = document[ POPMENU_ID + nIndex ];
			
		// Hook the container into the menu
		menuDiv.popMenuInfo = menuCurrent;
		
		// Container values
		var nItemWidth = nWidth;
		if( menuCurrent.width != 0 )
			nItemWidth = menuCurrent.width;
		
		var nContHeight = nHeight * menuCurrent.popMenuItems.length + ( g_PopBorderSize * 2 );
		var nContWidth = nItemWidth + ( g_PopBorderSize * 2 );
		
		menuDiv.height = nContHeight;
		menuDiv.width = nContWidth;
		
		// NS requires a second container separate from the first for back table to exist
		if( !document.all )
		{
			// HTML is written here so calculations can be done to set frame to correct size
			var nFrameHeight = (nHeight * menuCurrent.popMenuItems.length) - 6; // NS Magic number 
			var nFrameWidth = nItemWidth - 6;									// NS Magic number 

			// Write out the background frame; frame needs table since NS only shows area that is used
			document.write( '<DIV ID="' + POPMENU_NSFRAME_ID + nIndex + '" CLASS="PopMenuContainerStyle"><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=' + nFrameWidth + '><TR><TD HEIGHT=' + nFrameHeight + '></TD></TR></TABLE></DIV>' );

			// Set the frame values
			document[ POPMENU_NSFRAME_ID + nIndex ].height = nContHeight;
			document[ POPMENU_NSFRAME_ID + nIndex ].width = nContWidth;
			document[ POPMENU_NSFRAME_ID + nIndex ].clip.height = nHeight * menuCurrent.popMenuItems.length + ( g_PopBorderSize * 2 );	// Add one for NS		
		
			// Different setting for NS menu div
			menuDiv.clip.height = nHeight * menuCurrent.popMenuItems.length + ( g_PopBorderSize * 2 ) + 1;  								// Add one for NS
		}

		// Loop through the menu items
		for( var nItemIndex = 0; nItemIndex < menuCurrent.popMenuItems.length; nItemIndex++ )
		{
			// Set the menu item values 
			var menuItemDiv;
			if( document.all )
			{
				menuItemDiv = this[ POPMENU_ID + nIndex + POPMENUITEM_ID + nItemIndex ];
				menuItemDiv.style.backgroundColor = g_PopBgColor;
				menuItemDiv.style.top = nHeight * nItemIndex;
				menuItemDiv.style.width = nItemWidth;
			}
			else
			{
				menuItemDiv = document[ POPMENU_ID + nIndex ].document[ POPMENU_ID + nIndex + POPMENUITEM_ID + nItemIndex ];
				menuItemDiv.top = nHeight * nItemIndex;
				menuItemDiv.bgColor = g_PopBgColor;
				menuItemDiv.clip.width = nItemWidth;				
				
				// NS requires a capture of the event to work
				menuItemDiv.captureEvents( Event.MOUSEUP );
			}

			// Setup event handlers
			menuItemDiv.onmouseover = popMenuItemMouseOver;
			menuItemDiv.onmouseout = popMenuItemMouseOut;
			menuItemDiv.onmouseup = popMenuItemMouseUp;
			
			// Hook the menu information into the div
			menuItemDiv.popMenuInfo = menuCurrent.popMenuItems[ nItemIndex ];
			menuItemDiv.ItemIndex = nItemIndex;
			
			// Position submenu graphic
			if( menuCurrent.popMenuItems[ nItemIndex ].popMenuItems )
			{
				// Get submenu div
				var divSubMenuGraphic;
				if( document.all )
				{
					divSubMenuGraphic = this[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ].style;
					this[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ].onmouseover = popMenuItemMouseOver;
					this[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ].onmouseout = popMenuItemMouseOut;
					this[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ].popMenuInfo = menuCurrent.popMenuItems[ nItemIndex ];
					this[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ].ItemIndex = nItemIndex;
				}
				else
				{
					divSubMenuGraphic = menuDiv.document[ POPMENU_ID + nIndex + POPMENU_SUBIMG_ID + nItemIndex ];
					divSubMenuGraphic.onmouseover = popMenuItemMouseOver;
					divSubMenuGraphic.onmouseout = popMenuItemMouseOut;
					divSubMenuGraphic.popMenuInfo = menuCurrent.popMenuItems[ nItemIndex ];
					divSubMenuGraphic.ItemIndex = nItemIndex;
				}
				
				// Setup graphic on the div
				divSubMenuGraphic.height = POPSUBMENU_GRAPHIC_HEIGHT;
				divSubMenuGraphic.clip.height = POPSUBMENU_GRAPHIC_HEIGHT;
				divSubMenuGraphic.width = POPSUBMENU_GRAPHIC_WIDTH;
				divSubMenuGraphic.visibility = "inherit";
				divSubMenuGraphic.zIndex = 40;
								
				// The div that holds the graphic has a margin
				divSubMenuGraphic.top = (nHeight * nItemIndex) + 1 + ((nHeight - POPSUBMENU_GRAPHIC_HEIGHT) / 2);
				divSubMenuGraphic.left = nItemWidth - POPSUBMENU_GRAPHIC_WIDTH - POPSUBMENU_GRAPHIC_MARGIN + 1;
			}
		}
	} 
}

/*----------------------------------------------------------------------------
Description: Handle a mouse over on a menu item
Comments   : Changes bgcolor of menu item and shows sub menu
----------------------------------------------------------------------------*/
function popMenuItemMouseOver()
{
	// Set this window not to close
	this.popMenuInfo.parent.closeWindow = FALSE;
	
	// Check if there is a parent; the menuitem has a parent which is the container, we want the containers parent
	if( this.popMenuInfo.parent.parent.popMenuItems )
		this.popMenuInfo.parent.parent.closeWindow = FALSE;

	// Change color and get information for the submenu routine
	// Todo: Calculate offsets
	var nTop;
	var nLeft;
	var nZIndex;
	if( document.all )
	{
		var divText = window[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENUITEM_ID + this.ItemIndex ];
		divText.style.backgroundColor = g_PopSelBgColor;
		nTop = divText.offsetParent.offsetTop + divText.offsetTop + POPSUBMENU_DROP;
		nLeft = divText.offsetParent.offsetLeft + divText.offsetWidth - POPSUBMENU_OVERLAP;
		
		nZIndex = window[ POPMENU_ID + this.popMenuInfo.parent.Index ].style.zIndex;
	}
	else
	{
		var divText = window.document[ POPMENU_ID + this.popMenuInfo.parent.Index ].document[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENUITEM_ID + this.ItemIndex ];
		divText.document.bgColor = g_PopSelBgColor;
		nLeft = divText.pageX + divText.clip.width - POPSUBMENU_OVERLAP;
		nTop = divText.pageY + POPSUBMENU_DROP;
		
		nZIndex = window.document[ POPMENU_ID + this.popMenuInfo.parent.Index ].zIndex;
	}

	// Check if it is a submenu
	if( this.popMenuInfo.popMenuItems )
	{
		showPopMenu( this.popMenuInfo, nLeft, nTop, nZIndex );
		this.popMenuInfo.closeWindow = FALSE;
		if( document.all )
			window[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENU_SUBIMG_ID + this.ItemIndex ].style.backgroundColor = g_PopSelBgColor;
		else
			window.document[ POPMENU_ID + this.popMenuInfo.parent.Index ].document[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENU_SUBIMG_ID + this.ItemIndex ].bgColor = g_PopSelBgColor;		
	}
}

/*----------------------------------------------------------------------------
Description: Show the pop menu referenced at the specified location
Parameters : a_popMenu inputs the popmenu object to show
			 a_nXPos inputs the x location to place the window
			 a_nYPos inputs the y location to place the window
			 a_nZIndex inputs the zIndex of the parent menu
----------------------------------------------------------------------------*/
function showPopMenu( a_popMenu, a_nXPos, a_nYPos, a_nZIndex )
{
	// Set this window not to close
	a_popMenu.closeWindow = FALSE;

	// for some reason the zIndex setting is getting lost
	if( a_nZIndex == 0 || a_nZIndex == null )
		a_nZIndex = POPMENU_ZINDEX_DEFAULT;
	
	// Get the menu object
	var divMenu;
	var divNSFrame;
	if( document.all )
	{
		divMenu = this[ POPMENU_ID + a_popMenu.Index ].style;
		divMenu.top = a_nYPos;
		divMenu.left = a_nXPos;
	}
	else
	{
		// Add bordersize since frame is not on this div
		divMenu = document[ POPMENU_ID + a_popMenu.Index ];
		divMenu.top = a_nYPos + g_PopBorderSize;
		divMenu.left = a_nXPos + g_PopBorderSize;

		// This div has frame
		divNSFrame = document[ POPMENU_NSFRAME_ID + a_popMenu.Index ];
		divNSFrame.top = a_nYPos;
		divNSFrame.left = a_nXPos;
		divNSFrame.zIndex = a_nZIndex + 1;
		divNSFrame.visibility = "visible";
	}
			
	// Display the div and put it on top
	divMenu.zIndex = a_nZIndex + 1;	
	divMenu.visibility = "visible";
}

/*----------------------------------------------------------------------------
Description: Hide the pop menu
Parameters : a_popMenu inputs the popMenu object to hide or the index of the menu
----------------------------------------------------------------------------*/
function hidePopMenu( a_popMenu )
{
	var divMenu;
	var divNSFrame;
	
	// Check what type of value was passed, object or index
	if( a_popMenu.popMenuItems )
	{
		// Get the menu object
		if( document.all )
			divMenu = this[ POPMENU_ID + a_popMenu.Index ].style;
		else
		{
			divMenu = document[ POPMENU_ID + a_popMenu.Index ];
			divNSFrame = document[ POPMENU_NSFRAME_ID + a_popMenu.Index ];
		}
	}
	else // index was passed
	{
		// Get the menu object
		if( document.all )
			divMenu = this[ POPMENU_ID + a_popMenu ].style;
		else
		{
			divMenu = document[ POPMENU_ID + a_popMenu ];
			divNSFrame = document[ POPMENU_NSFRAME_ID + a_popMenu ];
		}	
	}
	
	// Check whether this window should close
	if( divMenu.popMenuInfo.closeWindow == TRUE )
	{
		// Close window
		divMenu.visibility = "hidden";
	
		if( !document.all )
			divNSFrame.visibility = "hidden";
				
		// Close the parent window
		if( divMenu.popMenuInfo.parent.popMenuItems )
		{
			hidePopMenu( divMenu.popMenuInfo.parent );
		}
		else
		{
			hidePopMenuCallBack( divMenu.popMenuInfo );
		}
	}
}

/*----------------------------------------------------------------------------
Description: Handles mouse up on a menu item event
Comments   : Displays the website of the menuitem action
----------------------------------------------------------------------------*/
function popMenuItemMouseUp()
{
	// Check for an action and perform
	if( this.popMenuInfo.Action != "" )
		if( g_PopActionDestSelf == true )
			window.open( this.popMenuInfo.Action, "_self" );
		else
			window.open( this.popMenuInfo.Action, "_blank" );
}

/*----------------------------------------------------------------------------
Description: Sets the width of this particular pop menu
Parameters : a_nMenuWidth inputs the width to set the menu
Comments   : You can only set the width lower not higher
----------------------------------------------------------------------------*/
function setPopMenuWidth( a_nMenuWidth )
{
	this.width = a_nMenuWidth;
}

/*----------------------------------------------------------------------------
Description: Sets the pop action destination to self window or new window
Parameters : a_fSameWindow inputs to put html in current window or another window
Commments  : True is same window; false is a new window
----------------------------------------------------------------------------*/
function setPopActionDestSelf( a_fSameWindow )
{
	g_PopActionDestSelf = a_fSameWindow;
}

/*----------------------------------------------------------------------------
Description: Handles mouse out on a menu item events
Comments   : Changes bgcolor of menu item back, closes submenu
----------------------------------------------------------------------------*/
function popMenuItemMouseOut()
{
	// Change color
	if( document.all )
		window[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENUITEM_ID + this.ItemIndex ].style.backgroundColor = g_PopBgColor;
	else
	{
		window.document[ POPMENU_ID + this.popMenuInfo.parent.Index ].document[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENUITEM_ID + this.ItemIndex ].bgColor = g_PopBgColor;
	}

	// Check if there is a parent; the menuitem has a parent which is the container, we want the containers parent
	if( this.popMenuInfo.parent.parent.popMenuItems )
		this.popMenuInfo.parent.parent.closeWindow = TRUE;
		
	// Check if it is a submenu
	if( this.popMenuInfo.popMenuItems )
	{
		if( document.all )
			window[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENU_SUBIMG_ID + this.ItemIndex ].style.backgroundColor = g_PopBgColor;
		else
			window.document[ POPMENU_ID + this.popMenuInfo.parent.Index ].document[ POPMENU_ID + this.popMenuInfo.parent.Index + POPMENU_SUBIMG_ID + this.ItemIndex ].bgColor = g_PopBgColor;		

		this.popMenuInfo.closeWindow = TRUE;
		setTimeout( "hidePopMenu( " + this.popMenuInfo.Index + " );", 100 );
	}
	else
		// Close this menu item only if no child, child will attempt to close parent
		setTimeout( "hidePopMenu( '" + this.popMenuInfo.parent.Index + "' );", 100 );
		
	// Close this menu item
	this.popMenuInfo.parent.closeWindow = TRUE;
}
