// created by: André Dietisheim (dietisheim@sphere.ch)
// created: 2002-04-22
// modified by: André Dietisheim (dietisheim@sphere.ch)
// modified: 2004-02-07
// version: 2.4.4

function Xmenu( sNavigationName, sNavigation, globals, styles, contents )
{
	if( !Xmenu.prototype.instances ) Xmenu.prototype.instances = new Array();
	Xmenu.prototype.instances[ Xmenu.prototype.instances.length ] = this; // store this instance in static Array

	this.index = Xmenu.prototype.instances.length - 1;

	this.sNavigationName = sNavigationName;
	this.sNavigation = sNavigation;
	this.iType = globals[ 0 ];
	this.iCloseDelay = globals[ 1 ] * 1000;
	this.bClick = globals[ 2 ];
	this.bMenuBelow = globals[ 3 ];
	this.bLeftAlign = globals[ 4 ];
	this.bKeepExpansionState = globals[ 5 ];
	this.bHighlightClickedNodes = globals[ 6 ];
	this.sSpacerUrl = globals[ 8 ];
	this.sCloser = globals[ 9 ];
	this.styles = styles;
	this.contents = contents;

	this.iContent = 0;
	this.tree = null;
	this.overNode = null;
	this.outNode = null;
	this.lastNode = null;
	this.absY = 0;
	this.timeout = null;
	this.bOpened = false;
	iParentLayerWidth = ( is.iemac5up )? 0 : globals[ 7 ][ 0 ]; // XparentLayer disturbs Xlayer-events on iemac5
	iParentLayerHeight = ( is.iemac5up )? 0 : globals[ 7 ][ 1 ];
	this.xlayerParent = new XlayerParent( "XlayerParent" + this.index, this.sSpacerUrl, null, iParentLayerWidth, iParentLayerHeight, null );

	this.tree = this.buildTree( 0, 0, false, null, "tree", null );

	this.nodeFound = null;
	this.navigationNode = null;
	if ( this.findNode( this.sNavigation, this.tree ) )
	{ // node indicated in request found
		this.navigationNode = eval( "this." + this.nodeFound );
	}

	//Vars added by ANDRE
	this.ForceHighLight = false;
}

Xmenu.prototype.VERTICAL = 0;
Xmenu.prototype.HORIZONTAL = 1;
Xmenu.prototype.COLLAPSING = 2;

Xmenu.prototype.buildTree = function( iAbsX, iAbsY, bSibling, sParent, sPath, myParent )
{	
		var node = this.buildNode( iAbsX, iAbsY, bSibling, sParent, sPath );
		node.parentnode = myParent;

		this.iContent++;
		if ( this.iContent < this.contents.length && node.iLevel < this.contents[ this.iContent ][ 2 ] )
		{ // child
			node.child = this.buildTree(  node.absX, node.absY, false, "this." + node.sPath, node.sPath + ".child", node );
		}
		if ( this.iContent < this.contents.length && node.iLevel == this.contents[ this.iContent ][ 2 ] )
		{ // sibling
			node.sibling = this.buildTree( node.absX, node.absY, true, node.sParent, node.sPath + ".sibling", myParent );
		}
		node.xlayer = this.addXlayer( this.xlayerParent, node, this.styles )
		
		return node;
}

Xmenu.prototype.buildNode = function( iAbsX, iAbsY, bSibling, sParent, sPath )
{
	var node = new Object();
	node.child = null;
	node.sibling = null;
	node.sParent = sParent;
	node.sPath = sPath;

	node.sText		= this.contents[ this.iContent ][ 0 ];
	node.target		= this.contents[ this.iContent ][ 1 ];
	node.iLevel		= this.contents[ this.iContent ][ 2 ];
	
	//---Added by ANDRE to store an expanded default!
	if (this.contents[ this.iContent ][ 3 ])
		node.iExpanded	= this.contents[ this.iContent ][ 3 ];
	else
		node.iExpanded = false;
	
	// To force highlight of a node
	node.ForceHighLight = this.ForceHighLight
	//---


	if ( this.iType == this.VERTICAL )
	{
		if ( !bSibling )
		{ // child
			if ( node.iLevel > 1 || ( node.iLevel == 1 && !this.bMenuBelow ) ) // level 1 && menu to the right || level 2,3, ...: add width + xOffset
				node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 2 ] + this.styles[ node.iLevel + 1 ][ 0 ];
			else // level 0, 1 || node 1 && menu below: add xOffset
				node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 0 ];

			if ( node.iLevel != 1 || ( node.iLevel == 1 && !this.bMenuBelow ) ) // level 0, 2, 3, ... : add yOffset
				node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 1 ];
			else // level 1: add height of last node + yOffset
				node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 1 ] + this.styles[ node.iLevel ][ 3 ];
		}
		else
		{ // sibling
			node.absX = iAbsX;
			node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 3 ];
		}
	}
	else if ( this.iType == this.HORIZONTAL )
	{
		if ( !bSibling )
		{ // child
			if ( node.iLevel > 1 || ( this.bMenuBelow && node.iLevel == 1 ) )
			{ // ( level 1 && menu below ), level 2, 3, 4, ...
				node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 1 ] + this.styles[ node.iLevel ][ 3 ];
				if ( !this.bLeftAlign ) // add height of last + yOffset, add xOffset
					node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 0 ];
				else
					node.absX = this.styles[ node.iLevel + 1 ][ 0 ] + this.cumulateOffsets( 0, node.iLevel ) + ( ( node.iLevel > 0 && !this.bMenuBelow )? this.styles[ 1 ][ 2 ] : 0 );
			}
			else
			{ // level 0, ( level 1 && menu on the right ) 
				node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 1 ];
				if ( !this.bLeftAlign ) // add yOffset, add width of last + xOffset
					node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 0 ] + ( ( node.iLevel > 0 )? this.styles[ node.iLevel + 1 ][ 2 ] : 0 );
				else
					node.absX = this.styles[ node.iLevel + 1 ][ 0 ] + this.cumulateOffsets( 0, node.iLevel ) + ( ( node.iLevel > 0 && !this.bMenuBelow )? this.styles[ 1 ][ 2 ] : 0 );
			}
		}
		else
		{ // sibling
			node.absY = iAbsY;
			node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 2 ];
		}
	}
	else if ( this.iType == this.COLLAPSING )
	{
		if ( !bSibling )
		{ // child
			node.absX = iAbsX + this.styles[ node.iLevel + 1 ][ 0 ];
			node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 1 ];
		}
		else
		{ // sibling
			node.absX = iAbsX;
			node.absY = iAbsY + this.styles[ node.iLevel + 1 ][ 3 ];
		}
	}
	return node;
}

Xmenu.prototype.cumulateOffsets = function( iStyleIndex, iMaxLevel )
{
	var iOffset = 0;
	for ( i = 0; i < iMaxLevel; i++ )
	{
		iOffset += this.styles[ i + 1 ][ iStyleIndex ];
	}
	return iOffset;
}

Xmenu.prototype.addXlayer = function( xparentLayer, node, styles )
{
	var parent =	null;
	var x =	"left";
	var y =	"top";
	var offsetX = node.absX;
	var offsetY = node.absY;
	var w =	styles[ node.iLevel + 1 ][ 2 ];
	var h = styles[ node.iLevel + 1 ][ 3 ];
	var clipTop = 0;
	var clipRight = w;
	var clipBottom = h;
	var clipLeft = 0;
	var zIndex =	node.iLevel;
	var visibility = false;
	var fading =	styles[ node.iLevel + 1 ][ 4 ];
	var events =	
	[ 
		Xlayer.prototype.MOUSEOVER, "Xmenu.prototype.instances[" + this.index + "].onmouseover( Xmenu.prototype.instances[" + this.index + "]." + node.sPath + ")",
		Xlayer.prototype.MOUSEOUT, "Xmenu.prototype.instances[" + this.index + "].onmouseout( Xmenu.prototype.instances[" + this.index + "]." + node.sPath + ")",
		Xlayer.prototype.CLICK, "Xmenu.prototype.instances[" + this.index + "].onclick( Xmenu.prototype.instances[" + this.index + "]." + node.sPath + ")"
	];						
	var sText =  node.sText;
	var bgcolor = styles[ node.iLevel + 1 ][ 5 ][ 0 ];
	var fgcolor =  styles[ node.iLevel + 1 ][ 5 ][ 1 ];
	var align =  styles[ node.iLevel + 1 ][ 5 ][ 2 ];
	var iTopTextBorder = styles[ node.iLevel + 1 ][ 5 ][ 3 ]
	var iRightTextBorder = styles[ node.iLevel + 1 ][ 5 ][ 4 ]
	var iBottomTextBorder = styles[ node.iLevel + 1 ][ 5 ][ 5 ]
	var iLeftTextBorder = styles[ node.iLevel + 1 ][ 5 ][ 6 ]

	// FIXED BY ANDRE
	if (node.target)
		var href = node.target.sSrc;
	else
		var href = null;
	
	var bold =  styles[ node.iLevel + 1 ][ 5 ][ 7 ];
	var fontface =  styles[ node.iLevel + 1 ][ 5 ][ 8 ];
	var fontsize =  styles[ node.iLevel + 1 ][ 5 ][ 9 ];
	if ( styles[ node.iLevel + 1 ][ 5 ][ 11 ] )
	{	// icon defined
		var icon = ( node.child || styles[ node.iLevel + 1 ][ 5 ][ 10 ] )? styles[ node.iLevel + 1 ][ 5 ][ 11 ] : this.sSpacerUrl;
		var icon_w = styles[ node.iLevel + 1 ][ 5 ][ 12 ];
		var icon_h = styles[ node.iLevel + 1 ][ 5 ][ 13 ];
		var iconBorder = styles[ node.iLevel + 1 ][ 5 ][ 14 ];
	}
	else
	{	// icon not defined
		var icon = null;
		var icon_w = 0;
		var icon_h = 0;
		var iconBorder = 0;
	}
	var src = null; // iframe: src

	// MODIFIED LINE BELOW BY ANDRE
	return new Xlayer( parent, xparentLayer, x, y, offsetX, offsetY, w, h, clipTop, clipRight, clipBottom, clipLeft, zIndex, visibility, bgcolor, fading, events, sText, bold, align, iTopTextBorder, iRightTextBorder, iBottomTextBorder, iLeftTextBorder, fgcolor, href, icon, icon_w, icon_h, iconBorder, fontface, fontsize, src, this.sSpacerUrl, this.iType, this, node, this.sCloser);
}

Xmenu.prototype.create = function()
{
	this.createXlayers( null );
	this.setVisibSiblings( this.tree, true );
}

Xmenu.prototype.createXlayers = function( tree )
{
	if ( !tree ) 
	{ // call without param -> take root node
		tree = this.tree;
	}

	//CHANGED BY ANDRE| Create the xlayer before!
	tree.xlayer.create();

	if ( tree.child )
	{
		this.createXlayers( tree.child );
	}
	if ( tree.sibling )
	{
		 this.createXlayers( tree.sibling );
	}

	//ADDED BY ANDRE FOR AUTO HIGHLIGHTING
	if (tree.target)
	{
		//alert(node.xlayer);
		if ( (tree.target.sSrc != '/en/') && document.location.href.search(tree.target.sSrc) != -1 )
		{
//			alert (document.location.href + " " + tree.target.sSrc);
			this.highlight( tree, true );
			this.SetForcehighlight( tree, true );

			//Highlight Node before
			if (tree.parentnode)
			{
				this.highlight( tree.parentnode, true );
				this.SetForcehighlight( tree.parentnode, true );
				
				//Only call this function if the parentnode has childs and the style is collpasing. 
				if (tree.parentnode.child && this.iType == this.COLLAPSING)
					this.collapse( tree.parentnode.child, tree.parentnode.lastNode, tree.parentnode);
			}
		}
	}
}

Xmenu.prototype.setOpenListener = function( openListener )
{
	this.openListener = openListener;
}

Xmenu.prototype.setCloseListener = function( closeListener )
{
	this.closeListener = closeListener;
}

Xmenu.prototype.setLinkClickListener = function( linkClickListener )
{
	this.linkClickListener = linkClickListener;
}

Xmenu.prototype.open = function()
{	
	if ( this.navigationNode != null )
	{
		this.openLastClicked();
	}
	else
	{
		this.setVisibSiblings( this.tree, true );
	}
	this.bOpened = true;
	this.openListener.onMenuOpen( this );
}

Xmenu.prototype.openLastClicked = function()
{
	node = this.navigationNode;
	this.lastNode = node;

	if ( node.child != null )
		this.setVisibSiblings( node.child, true );

	while ( node != null )
	{
		this.highlightClickedNode( node );
		if ( node.sParent != null )
		{
			this.setVisibSiblings( eval( node.sParent ).child, true );
			node = eval( node.sParent );
		}
		else
		{
			this.setVisibSiblings( this.tree, true );
			node = null;
		}
	}
}

Xmenu.prototype.findNode = function( sText, node )
{
	if ( this.nodeFound )
		return true;

	if ( node.child )
		this.findNode( sText, node.child );

	if ( node.sibling )
		this.findNode( sText, node.sibling );

	if ( sText == node.sText )
		this.nodeFound = node.sPath;

	if ( this.nodeFound ) 
		return true;
	else 
		return false;
}

Xmenu.prototype.close = function()
{
	if ( this.bOpened && !this.bKeepExpansionState )
	{
		this.setVisibChildren( this.tree, false );
		this.setVisibSiblings( this.tree, true );
		if ( this.iType == this.COLLAPSING )
			this.setCollapsePos( this.tree );
//		if ( this.bClick && this.lastNode )
//		{
			this.clearHighlightChildren( this.tree );
			this.lastNode = null;
//		}

		this.bOpened = false;
		this.closeListener.onMenuClose( this );
	}
}

Xmenu.prototype.onmouseover = function( node )
{
	this.overNode = node;
	if ( ( this.iType == this.VERTICAL || this.iType == this.HORIZONTAL ) && !this.bClick )
	{
		if ( !this.bOpened )
		{ // this menu will open
			this.bOpened = true;
			this.openListener.onMenuOpen( this );
		}
		if ( this.outNode )
			var outNode = this.outNode;
		else
			var outNode = this.tree;
		if ( outNode.iLevel > node.iLevel )
		{
			this.showBranch( node, this.outNode );
//			this.setVisibSiblings( eval( outNode.sParent + ".child" ), false );
//			this.setVisibSiblings( outNode.child, false );
		}
		else if ( outNode.iLevel == node.iLevel )
		{
			this.setVisibSiblings( outNode.child, false );
		}
		this.setVisibSiblings( node.child, true );
	}
	if ( this.checkClickPath( node ) )
	{ // current node is not the node that was clicked (or its parents)
		this.highlight( node, true );
	}
	return false;
}

Xmenu.prototype.onmouseout = function( node )
{
	if (node.ForceHighLight)
		return;

	if ( this.checkClickPath( node ) )
		this.highlight( node, false );

	if ( ( this.iType == this.VERTICAL || this.iType == this.HORIZONTAL ) && !this.bClick ) // close menu if no onmouseover until timeout
	{
		clearTimeout( this.timeout );
		this.timeout = setTimeout( "Xmenu.prototype.instances[" + this.index + "].checkOnmouseout()", this.iCloseDelay );
	}
	
	this.outNode = node;

	return false;
}

Xmenu.prototype.checkClickPath = function( node )
{
	if ( this.bHighlightClickedNodes )
	{
		lastNode = this.lastNode;
		while ( lastNode != null )
		{
			if ( lastNode == node ) // node clicked found
				return false;
			else // continue looking for it
				lastNode = eval( lastNode.sParent );
		}
		return true;
	}
	else
	{
		return true;
	}
}

Xmenu.prototype.checkOnmouseout = function()
{
	if ( this.overNode == this.outNode && !( this.bKeepExpansionState && this.bClick ) ) // onmouseover executed since delay?
		this.close();
}

Xmenu.prototype.onclick = function( node )
{	
	if ( node.target )
	{ // follow href
		node.target.open( node.sText, this.sNavigationName, this.sNavigation );
		this.sNavigation = node.sText;
		this.navigationNode = node; // store navigation node
		this.linkClickListener.onLinkClick( this ); // inform controller
	}
	else if (
		( ( this.iType == this.VERTICAL || this.iType == this.HORIZONTAL ) && this.bClick ) || this.iType == this.COLLAPSING )
	{
		this.highlight( node, true );
		if ( !this.bOpened )
		{ // this menu will open
			this.bOpened = true;
			this.openListener.onMenuOpen( this );
		}

		if ( this.iType == this.COLLAPSING )
			this.collapse( node, null, null );
		else if ( ( this.iType == this.VERTICAL || this.iType == this.HORIZONTAL ) && this.bClick )
			this.showBranch( node, this.lastNode );
		this.lastNode = node;

		//---added by ANDRE| Set Image to MINUS
		var myimg = document.getElementById( "img_" + node.xlayer.id );
		if (myimg)
		{
			if ( myimg.src.search(node.xlayer.sIcon) != -1 )
				myimg.src = node.xlayer.sCloser; 
			else
				myimg.src = node.xlayer.sIcon;
		}
		//---
	}
	return false;
}

Xmenu.prototype.showBranch = function( node, hideNode )
{
//	if ( this.bClick && hideNode == node && node.child && node.child.xlayer.isVisible() )
	if ( this.bClick && node.child && node.child.xlayer.isVisible() )
	{ // reclose branch
		this.setVisibChildren( node.child, false );
		this.clearHighlightChildren( node, false );
	}
	else
	{

//QUICK FIX BY ANDRE!
		if ( hideNode && this.iType != Xmenu.prototype.COLLAPSING )
		{ // hide old nodes
			this.setVisibChildren( this.tree, false );
			this.clearHighlightChildren( this.tree, false );
		}

		if ( node.child ) this.setVisibSiblings( node.child, true );
		while ( node )
		{ // show new nodes
			if ( this.bClick )
				this.highlightClickedNode( node, true );
			if ( node.sParent ) 
				this.setVisibSiblings( eval( node.sParent ).child, true );
			else
				this.setVisibSiblings( this.tree, true );
			node = eval( node.sParent );
		}
	}
}

Xmenu.prototype.clearHighlightChildren = function( node )
{
	if ( node ) 
	{
		if	( node.child )
			 this.clearHighlightChildren( node.child );
		if ( node.sibling )
			 this.clearHighlightChildren( node.sibling );
		this.highlight( node, false );
	}
}

Xmenu.prototype.collapse = function(node, myLastNode, myTree)
{
	//Enhanced by ANDRE to be able to collapse parentnodes
	if (!myLastNode)
		thisLastNode = this.lastNode;
	else
		thisLastNode = myLastNode;
	if (!myTree)
		thisTree = this.tree;
	else
		thisTree = myTree;
	
	this.showBranch( node, thisLastNode );
	this.setCollapsePos( thisTree );
}

Xmenu.prototype.setCollapsePos = function( node )
{
	if ( node == this.tree ) // start looping
		this.absY = this.tree.xlayer.y;
	
	// ADDED BY ANDRE!
	if (!node.xlayer.lyr)
		return;	//Break in this case!
			
	if ( node.xlayer.isVisible() )
	{
		node.xlayer.setPos( node.xlayer.x, this.absY );
		this.absY += node.xlayer.h;
	}

	if ( node.child ) 
		this.setCollapsePos( node.child );
	if ( node.sibling ) 
		this.setCollapsePos( node.sibling );
}

Xmenu.prototype.SetForcehighlight = function( node, bHighlight )
{
//	this.ForceHighLight = bHighlight;
	node.ForceHighLight = bHighlight;
}

Xmenu.prototype.highlight = function( node, bHighlight )
{
	if (this.ForceHighLight && bHighlight == false)
		return; //Not in this case

	var index = ( bHighlight )? 6 : 5;	// style for mouseover or mouseout ?
	node.xlayer.setBgColor( this.styles[ node.iLevel + 1 ][ index ][ 0 ] );
	// nn4 crashes, iemac stops rendering
	if ( !is.nn4up && !is.iemac5up ) node.xlayer.setFgColor( this.styles[ node.iLevel + 1 ][ index ][ 1 ] );
}

Xmenu.prototype.highlightClickedNode = function( node )
{
	if ( node && this.bHighlightClickedNodes )
	{
		node.xlayer.setBgColor( this.styles[ 0 ][ 0 ] );
		if ( !is.nn4up && !is.iemac5up ) 
			node.xlayer.setFgColor( this.styles[ 0 ][ 1 ] );
	}
}

Xmenu.prototype.setVisibSiblings = function( node, bVisibility )
{
	if ( node )
	{
		if ( node.sibling )
			 this.setVisibSiblings( node.sibling, bVisibility );
		node.xlayer.setVisibility( bVisibility );
	}
}

Xmenu.prototype.setVisibChildren = function( node, bVisibility )
{
	if ( node )
	{
		if	( node.child )
			 this.setVisibChildren( node.child, bVisibility );
		if	( node.sibling )
			 this.setVisibChildren( node.sibling, bVisibility );
		node.xlayer.setVisibility( bVisibility );
	}
}

Xmenu.prototype.isNavigationNodeFound = function()
{
	return this.navigationNode != null;
}
