// menu.js -- Javascript DHTML Cascade Menu/List Object 
// Version 0.96 (23/01/2003)
// ------------------------------------------------------
// Copyright Webree.com Ltd, All rights reserved.
// Designed & Written by Matthew Tighe

// Menu Item Type Definition
// -------------------------
// The menu item type defines a single item in the menu, and
// how it relates to other items (which determines the menu structure).

/*	Const MENU_POPUP = 8				' Menu is a popup
	Const MENU_STATIC = 0				' Opposite of popup, menu is part of page

	Const MENU_HOVER_SUBMENU = 2048		' Show sub menus when hovered over

	Const MENU_ANCHOR_BOTTOM = 256		' Align menu to its anchor layer
	Const MENU_ANCHOR_RIGHT = 512
	Const MENU_ANCHOR_LEFT = 1024

	Const MENU_CLOSE_ITEM = 16			' Menu has a 'Close' item at end.
	Const MENU_LAYOUT_VERT = 0			' Menu has vertical layout of items
	Const MENU_LAYOUT_HORZ = 1			' Menu has horizontal layout of items
	Const MENU_RESIZE_CHILDREN = 32	    ' Resize child menus to match parent item
*/

function menuItem( nType, szCaption, szLink )
{
	this.length = 3;
	
	this.nType = nType;
	this.szCaption = szCaption;
	this.szLink = szLink;
}
function menuItem( nType, szCaption, szLink, nItemType )
{
	this.length = 4;
	
	this.nType = nType;
	this.szCaption = szCaption;
	this.szLink = szLink;
	this.nItemType = nItemType;
}

// magicMenu Type Definition
// -------------------------
// The magicMenu object is the basic object used to create a cascade menu.

function magicMenu( szName, szLayer, szStyle, szAnchor, nFlags )
{
	this.length = 16;  		 		// Number of properties in the object, not including this one.
		
	this.draw = _draw;				// Draw menu into its layer.

	this.show = _show;
	this.move = _move;
	this.moveToLayer = _moveToLayer;
	
	this.setAnchor = _setAnchor;	// Anchors a menu to a div.

	this.cellPadding = 2;
	this.cellSpacing = 0;
	this.closeIcon = "/icons/menuarrow.gif";
	this.subIcon = "/icons/menuarrow.gif";

	this.addItem = _addItem;		// Add an item to a menu.
	this.addSubMenu = _addSubMenu;	// Add a sub menu.
	this.addSeparator = _addSeparator
	this.selectItem = _selectItem;	// Selects an item (List).

	this.szName = szName;			// Name of this menu object (i.e. navMenu)
	this.szLayer = szLayer;
	this.nFlags = nFlags;
	this.nSelection = -1;
	this.nSelected = -1;			// Selected item (for Lists).

	this.szHeader = "";				// HTML for header of menu.
	this.szFooter = "";				// HTML for fotter of menu.
	this.szStyle = szStyle;			// Base menu style class name.

	// Event Handlers
	this.clickItem = _clickItem;
	this.overItem = _overItem;
	this.offItem = _offItem;
	
	this.bDrawn = false;
	
	this.mI = new Array();

	// Create the sprite for this menu.
	if( nFlags & 8 )
	{
		this.sprMenu = new magicSprite( szName + ".sprMenu", szLayer );
		this.sprMenu.setMouseEvents( null,menuMouseDownHandler,menuMouseMoveHandler);
	}
	else
		this.sprMenu = null;
	
	this.szAnchor = szAnchor;
	this.subMenuObj = null;
	this.itemSize = 0;

}

function menuMouseMoveHandler( e )
{
	if( e )
		e.cancelBubble = true;
	else if (event)
		event.cancelBubble = true;
			
	return(false);
}

function menuMouseDownHandler( e )
{
	if( e )
		e.cancelBubble = true;
	else if (event)
		event.cancelBubble = true;
			
	return(false);
}

function _selectItem( nIndex )
{
	if(this.nSelected == nIndex)
		return;

	if( this.bDrawn == true )
	{
		if( this.nSelected >= 0)
		{
			setLayerClass(getItemLayer(this.szLayer, this.nSelected), this.szStyle + "Item" );
		}
		if( this.subMenuObj != null)
			this.subMenuObj.show(false);
	}
	
	this.nSelected = nIndex;
	this.nSelection = nIndex; 
}

function _clickItem( nIndex )
{
	var obj;

	switch( this.mI[nIndex].nType )
	{
		case 0:
			document.location.href = this.mI[nIndex].szLink;
			break;
		case 1:
				if( (this.nFlags & 2048) == 0 )
				{
					this.selectItem( nIndex );
					this.subMenuObj = this.mI[nIndex].szLink;
					if( this.nFlags & 32 )
					{
						if( this.nFlags & 1 )		// HORIZ 
							this.mI[nIndex].szLink.sprMenu.resize( this.itemSize,''  );		// show the sub menu.
						else					
							this.mI[nIndex].szLink.sprMenu.resize( '', this.itemSize );		// show the sub menu.

					}
					this.mI[nIndex].szLink.show( true );		// show the sub menu.
				}		
			break;
	}
}
function getItemLayer(szLayer, nIndex)
{
	return( getLayerObj(szLayer +  '_' + nIndex) );
}

function _overItem( nIndex )
{

	var obj;
	if( this.nSelection == nIndex)
		return;

	if( this.nSelection >= 0 )
		this.offItem( this.nSelection );

	this.nSelection = nIndex;		
	if( nIndex >= 0 )
	{
		obj = getItemLayer(this.szLayer, nIndex);

		setLayerClass( obj, this.szStyle + "Highlight" );
		switch( this.mI[nIndex].nType )
		{
			case 0:
				if( this.subMenuObj != null )
				{
					this.selectItem( -1 );
					this.subMenuObj.show( false );
					this.subMenuObj = null;
				}
				break;

			case 1:

				// if SHOW_SUB_ON_HOVER or we have already click a submenu (but not this menu!!) 
				if( (this.nFlags & 2048) > 0 || (this.subMenuObj != null && this.nSelected != nIndex) )
				{
					this.selectItem( nIndex );
					this.subMenuObj = this.mI[nIndex].szLink;
					if( this.nFlags & 32 )
					{
						if( this.nFlags & 1 )		// HORIZ
							this.mI[nIndex].szLink.sprMenu.resize( this.itemSize,''  );		// show the sub menu.
						else					
							this.mI[nIndex].szLink.sprMenu.resize( '', this.itemSize );		// show the sub menu.
					}

					this.subMenuObj.nSelected = -1;						
					this.mI[nIndex].szLink.show( true );		// show the sub menu.
				}
				break;
		}
	}
}

function _offItem( nIndex )
{
	var obj;

	if( this.bDrawn == false)
		return;
		
	if( nIndex == this.nSelected )
		setLayerClass(getItemLayer(this.szLayer, nIndex), this.szStyle + "Highlight" );
	else
		setLayerClass(getItemLayer(this.szLayer, nIndex), this.szStyle + "Item" );

	this.nSelection = -1;
}

function _setAnchor( szLayer )
{
	this.szAnchor = szLayer;
}

function _addItem( szLink, szCaption )
{
	this.mI[ this.mI.length ] = new menuItem( 0, szCaption, szLink );
	this.sprMenu.height += 20;
}
function _addSeparator(){
	this.mI[ this.mI.length ] = new menuItem( 0, "", "", 1 );
	this.sprMenu.height += 20;
}

function _addSubMenu( szCaption, menuObj )
{
	var i;
	
	i = this.mI.length;
	
	this.mI[ i ] = new menuItem( 1, szCaption, menuObj);
	this.mI[ i ].szLink.setAnchor( this.szLayer + "_" + i );
		
	this.sprMenu.height += 20;	
		
	return( this.mI[ i ] );		// Return 'pointer' to the menu
}

function _show( bVis )
{
	var nOffsetX = 0, nOffsetY = 0, obj;
	
	if( this.subMenuObj != null)
	{
		this.subMenuObj.show( false );
		this.subMenuObj = null;
	}
		
	if( this.nFlags & 8 )			// You cannot "Show" as static menu, its already there.
		if( bVis == true )
		{
			if( this.szAnchor.length > 0 )
			{
				if( this.nFlags & 256 )		// BOTTOM ALIGN
					nOffsetY = getLayerDisplayHeight( getLayerObj( this.szAnchor ) );
					
				if( this.nFlags & 512 )		// RIGHT ALIGN
					nOffsetX = getLayerDisplayWidth( getLayerObj( this.szAnchor ) ) + 1;

				if( this.nFlags & 1024 )	// LEFT ALIGN
					nOffsetX = - (this.sprMenu.width);
				
				this.moveToLayer( getLayerObj( this.szAnchor ), nOffsetX, nOffsetY );	// BOTTOM EDGE
			}
			
			this.nSelected = -1;
			this.sprMenu.blend( 100 );
			this.draw();
		}
		else {
			this.sprMenu.blend( 0 );
		}
}

function _moveToLayer( obj, nOffsetX, nOffsetY )
{
	var x,y,width,height, scrWidth, scrHeight;

	if( obj != null )
	{
		x = getLayerXPos( obj );
		y = getLayerYPos( obj );
		
		width = getLayerDisplayWidth( obj );
		height = getLayerDisplayHeight( obj );

		scrWidth = getBrowserWidth();
		scrHeight = getBrowserHeight();

		x += nOffsetX;		

		if( ( x + width ) > (scrWidth+10) )
		{
			x -= nOffsetX;
			x -= this.sprMenu.width;
		}
		
		y += nOffsetY;

		this.sprMenu.move(  x , y , 100 );
	}
}

function _move( x, y)
{
	// we dont want the menu going below the window
	var menuHeight = this.sprMenu.height;
	var scrHeight = getBrowserHeight();

	var xy = getScrollXY();
	scrolly = xy[1];

	// if mousey + menuHeight > browser height
	if((y + menuHeight+20) > scrHeight) {
		y = scrolly + (scrHeight - menuHeight) - 20;
	}
	
	//prevent menu passing top, and left
	if(x<0){x=0;}
	if(y<0){y=0;}
	
	this.sprMenu.move( x, y, 100 );
}

function _draw()
{
	var szSource,i, cols, rowPrefix = '', rowPostfix = '', itemPrefix = '', itemPostfix = '';
	var colWidth;

	colWidth = (100 / this.mI.length);
	this.itemSize = colWidth + "%";

	szSource = '<table class="' + this.szStyle + '" width="100%" border="0" cellspacing="' + this.cellSpacing + '" cellpadding="' + this.cellPadding + '">' + rowPrefix;
	
	if( this.nFlags & 1)
	{	// HORIZ
	
		rowPrefix = '<tr>';
		itemPrefix = '<td width="' + colWidth + '%" ';
		itemPostfix = '</td>';
		rowPostfix = '</tr>';
	}
	else
	{	// VERT
		itemPrefix = '<tr><td ';
		itemPostfix = '</td></tr>';
	}
	
	var ItemType;
	for( i = 0; i < this.mI.length; i++ )
	{
	
		if(this.mI[i].nItemType){
			ItemType = this.mI[i].nItemType;
		}else{
			ItemType = -1;
		}
		
		switch(ItemType){
			case 1:
				szSource += itemPrefix + "><hr height=1 width=98% align=centre>" + itemPostfix;
				break;
				
			default:
				if( this.nSelected == i )
					szSource += itemPrefix + 'class="' + this.szStyle + 'Highlight" id="' + this.szLayer + '_' + i + '" onmouseover="' + this.szName + '.overItem(' + i + ');" onmouseout="' + this.szName + '.offItem(' + i + ');" onclick="' + this.szName + '.clickItem(' + i + ');">' + this.mI[i].szCaption;
				else
					szSource += itemPrefix + 'class="' + this.szStyle + 'Item" id="' + this.szLayer + '_' + i + '" onmouseover="' + this.szName + '.overItem(' + i + ');" onmouseout="' + this.szName + '.offItem(' + i + ');" onclick="' + this.szName + '.clickItem(' + i + ');">' + this.mI[i].szCaption;
		
				switch( this.mI[i].nType )
				{
					case 0:			// Link
						break;
					case 1:			// Sub menu
						szSource = szSource + '<img src="' + this.subIcon +'" width="16" align="absmiddle" height="16" border="0">';
						break;
				}
				szSource += itemPostfix;			
		}
	}
	
	if( this.nFlags & 16 )	// CLOSE_ITEM
		szSource += itemPrefix + 'class="' + this.szStyle + 'Close" align="center" onmouseover="' + this.szName + '.overItem(-1);"><a href="javascript:' + this.szName + '.show(false);"><img src="' + this.closeIcon + '" border="0"></a>' + itemPostfix;
	
	szSource += rowPostfix + "</table>";

	if( this.nFlags & 8 )
		this.sprMenu.setSource( szSource );
	else
		document.write( szSource );
	
	this.bDrawn = true;
}