		/*************************************************** colors **************************************************/
		STD_HORIZONTALPOPUPMENU_BG_COL	= '#FFFFFF';
		STD_HORIZONTALPOPUPMENU_COL 		= '#FFFFFF';

		/*************************************************** menu stuff **************************************************/
		/** Internet Explorer? */
    var IE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf( 'Opera' ) == -1;

    /** document object model supported? */
    var DOM = !!document.getElementById;

    /** interval after which all menus are closed if the menu is not used anymore */
    var HIDE_AFTER = 3000;

    /** arrow image */
    var ARROW_IMAGE = null;

    /** the z-Index of the displayed arrow */
    var ARROW_ZINDEX = '2';

    /** size of the displayed arrow */
    var ARROW_SIZE = 7;

    /** the color of the displayed arrow */
    var ARROW_COLOR = '#C0C0FF';

    /** the width of the icon */
    var ICON_WIDTH = 24;

    /** the height of the icons */
    var ICON_HEIGHT = 24;

    /** the timer that hides the menu after a interval */
    var m_Timer = null;

    /**
     * The MenuRegistry holds all Menus in a map for each registered link.
     */
    function MenuRegistry() {
        this.m_Links = new Array();
        this.m_Children = new Array();
        this.m_HoveredLinks = new Array();

        this.appendChild = MenuRegistry_appendChild;
        this.addHoveredLink = MenuRegistry_addHoveredLink;
        this.createHoveredLinks = MenuRegistry_createHoveredLinks;
        this.create = MenuRegistry_create;
        this.revalidate = MenuRegistry_revalidate;
        this.hideAll = MenuRegistry_hideAll;
        this.startTimer = MenuRegistry_startTimer;
        this.stopTimer = MenuRegistry_stopTimer;
    		}

    /**
     * Appends a menu to the menu registry.
     * @param child the menu
     */
    function MenuRegistry_appendChild( child ) {
    		this.m_Children[this.m_Children.length] = child;
    		}

    /**
     * Adds a hovered link.
     * @param hoveredLink the hovered link
     */
    function MenuRegistry_addHoveredLink( hoveredLink ) {
        this.m_HoveredLinks[this.m_HoveredLinks.length] = hoveredLink;
    		}

    /**
     * Creates the hovered links.
     */
    function MenuRegistry_createHoveredLinks() {
        var i;
        for ( i=0; i < this.m_HoveredLinks.length; i++ ) this.m_HoveredLinks[i].create();
  		  }

    /**
     * Adds mouse over events to all registered link.
     */
    function MenuRegistry_create() {
        var i, j, left, top;
        var links = document.getElementsByTagName( 'A' );
        var arrow;

        for ( i=0; i < links.length; i++ ) {
            for ( j=0; j < this.m_Children.length; j++ ) {
                if ( links[i].href.indexOf( this.m_Children[j].getUrl() ) != -1 && links[i].parentLink && links[i].parentLink.className == 'PopupMenuItem' ) {
                    links[i].menu = this.m_Children[j];
                    links[i].oldmenumouseover = links[i].onmouseover;
                    links[i].onmouseover = function() {
                        if ( this.oldmenumouseover ) this.oldmenumouseover();
                        window.menuRegistry.hideAll();
                        window.menuRegistry.stopTimer();
                        this.menu.show( this );
                    		};
                    links[i].oldmenumouseout = links[i].onmouseout;
                    links[i].onmouseout = function() {
                        if ( this.oldmenumouseout ) this.oldmenumouseout();
                        window.menuRegistry.startTimer();
                    		};

                    left = getAbsoluteLeft( links[i].hover );
                    top = getAbsoluteTop( links[i].hover );

                    if ( this.m_Children[j].getDirection() == 'HORIZONTAL' && top > 10 ) {
                        arrow = createArrow( ARROW_IMAGE, ARROW_ZINDEX, ARROW_SIZE, ARROW_COLOR );
                        arrow.style.left = getAbsoluteLeft( links[i].hover ) + links[i].hover.offsetWidth - ARROW_SIZE - 7;
                        arrow.style.top = getAbsoluteTop( links[i].hover ) + links[i].hover.offsetHeight / 2 - ARROW_SIZE / 2;
                        document.body.appendChild( arrow );
                        links[i].arrow = arrow;
                    		}

                    this.m_Links[this.m_Links.length] = links[i];
                		}
            		}
        		}
    		}

    /**
     * Revalidates the layout of the menubar.
     **/
    function MenuRegistry_revalidate() {
        var i;
        for ( i=0; i < this.m_Links.length; i++ ) {
            if ( this.m_Links[i].arrow ) {
                this.m_Links[i].arrow.style.left = getAbsoluteLeft( this.m_Links[i].hover ) + this.m_Links[i].hover.offsetWidth - ARROW_SIZE - 7;
                this.m_Links[i].arrow.style.top = getAbsoluteTop( this.m_Links[i].hover ) + this.m_Links[i].hover.offsetHeight / 2 - ARROW_SIZE / 2;
            		}
        		}
    		}

    /**
     * Hides all opened menus.
     */
    function MenuRegistry_hideAll() {
        var i;
        for ( i=0; i < this.m_Children.length; i++ ) this.m_Children[i].hide();
 			  }

    /**
     * Starts the timer.
     */
    function MenuRegistry_startTimer() {
        m_Timer = window.setTimeout( 'window.menuRegistry.hideAll();', HIDE_AFTER );
    		}

    /**
     * Stops the timer.
     */
    function MenuRegistry_stopTimer() {
        if ( m_Timer != null ) window.clearTimeout( m_Timer );
        m_Timer = null;
		    }

    /**
     * The menu is shown on a mouseover event.
     */
    function Menu( className ) {
        this.m_Icon = '';
        this.m_Url = '';
        this.m_Target = '';
        this.m_Text = '#';
        this.m_Children = new Array();
        this.m_Shown = false;
        this.m_Table = null;
        this.m_Link = null;
        this.m_IsMenu = false;
        this.m_Parent = null;
        this.m_Direction = 'HORIZONTAL';
        this.m_Adjustment = 'VERTICAL';
				
        this.m_MenuClassName = className;
        this.m_ItemClassName = 'PopupMenuItem';

        this.setIcon = Menu_setIcon;
        this.getIcon = Menu_getIcon;
        this.setUrl = Menu_setUrl;
        this.getUrl = Menu_getUrl;
        this.setTarget = Menu_setTarget;
        this.getTarget = Menu_getTarget;
        this.setText = Menu_setText;
        this.getText = Menu_getText;
        this.setParent = Menu_setParent;
        this.setLink = Menu_setLink;
        this.getLink = Menu_getLink;
        this.setDirection = Menu_setDirection;
        this.getDirection = Menu_getDirection;
        this.setAdjustment = Menu_setAdjustment;
        this.getAdjustment = Menu_getAdjustment;
        this.setMenuClassName = Menu_setMenuClassName;
        this.getMenuClassName = Menu_getMenuClassName;
        this.setItemClassName = Menu_setItemClassName;
        this.getItemClassName = Menu_getItemClassName;

        this.isShown = Menu_isShown;
        this.isMenu = Menu_isMenu;
        this.isHorizontal = Menu_isHorizontal;
        this.appendChild = Menu_appendChild;
        this.show = Menu_show;
        this.hide = Menu_hide;
        this.hideAllChildren = Menu_hideAllChildren;
        this.create = Menu_create;
        this.registerEvents = Menu_registerEvents;
    		}

    /**
     * Sets the icon.
     * @param icon the icon
     */
    function Menu_setIcon( icon ) {
        this.m_Icon = icon;
    		}

    /**
     * Returns the icon.
     * @return the icon
     */
    function Menu_getIcon() {
        return this.m_Icon;
    		}

    /**
     * Sets the url.
     * @param url the url
     */
    function Menu_setUrl( url ) {
        this.m_Url = url;
    		}

    /**
     * Returns the url.
     * @return the url
     */
    function Menu_getUrl() {
        return this.m_Url;
    		}

    /**
     * Sets the target.
     * @param target the target
     */
    function Menu_setTarget( target ) {
        this.m_Target = target;
    		}

    /**
     * Returns the target.
     * @return the target
     */
    function Menu_getTarget() {
        return this.m_Target;
    		}

    /**
     * Sets the text.
     * @param text the text
     */
    function Menu_setText( text ) {
        this.m_Text = text;
    		}

    /**
     * Returns the text.
     * @return the text
     */
    function Menu_getText() {
        return this.m_Text;
    		}

    /**
     * Sets the link html element.
     * @param link the link
     */
    function Menu_setLink( link ) {
        this.m_Link = link;
    		}

    /**
     * Returns the link html element.
     * @return the link
     */
    function Menu_getLink() {
        return this.m_Link;
    		}

    /**
     * Sets the direction. HORIZONTAL or VERTICAL.
     * @param direction the direction
     */
    function Menu_setDirection( direction ) {
        this.m_Direction = direction;
    		}

    /**
     * Returns the direction.
     * @return the direction
     */
    function Menu_getDirection() {
        return this.m_Direction;
    		}

    /**
     * Sets the adjustment.
     * @param adjustment the adjustment
     */
    function Menu_setAdjustment( adjustment ) {
        this.m_Adjustment = adjustment;
    		}

    /**
     * Returns the adjustment.
     * @return the adjustment
     */
    function Menu_getAdjustment() {
        return this.m_Adjustment;
    		}

    /**
     * Sets the menu class name.
     * @param className the menu class name
     */
    function Menu_setMenuClassName( className ) {
        this.m_MenuClassName = className;
    		}

    /**
     * Returns the menu class name.
     * @return the menu class name
     */
    function Menu_getMenuClassName() {
        return this.m_MenuClassName;
    		}

    /**
     * Sets the item class name.
     * @param className the item class name
     */
    function Menu_setItemClassName( className ) {
        this.m_ItemClassName = className;
    		}

    /**
     * Returns the item class name.
     * @return className the item class name
     */
    function Menu_getItemClassName( className ) {
        return this.m_ItemClassName;
    		}

    /**
     * Returns if the menu is currently shown.
     * @return Menu is shown?
     */
    function Menu_isShown() {
        return this.m_Shown;
    		}

    /**
     * Returns if the menu is really a menu (has at least one child).
     * @return has the menu at least one child
     */
    function Menu_isMenu() {
        return this.m_IsMenu;
    		}

    /**
     * Appends a menu item to the menu.
     * @param child the menu item
     */
    function Menu_appendChild( child ) {
        this.m_Children[this.m_Children.length] = child;
        child.setParent( this );
        this.m_IsMenu = true;
    		}

    /**
     * Sets the parent menu.
     * @param parent the parent menu
     */
    function Menu_setParent( parent ) {
        this.m_Parent = parent;
    		}

    /**
     * Is the menu horizontal.
     * @return Menu horizontal?
     */
    function Menu_isHorizontal() {
        return this.m_Direction == 'HORIZONTAL';
    		}

    /**
     * Creates and shows the menu.
     * @param the link that called the show()
     */
    function Menu_show( link ) {
        if ( this.m_Shown ) return;

        var left, top;
        if ( this.m_Table == null ) this.m_Table = this.create();
        left = getAbsoluteLeft( link.hover );
        top = getAbsoluteTop( link.hover );
        if ( left == -1 || top == -1 ) return;

        if ( this.m_Direction == 'HORIZONTAL' && top > 10 ) left += link.hover.offsetWidth;
        else top += link.hover.offsetHeight;

        this.m_Table.style.left = left;
        this.m_Table.style.top = top;

        document.body.appendChild( this.m_Table );
        this.m_Shown = true;

        window.menuRegistry.createHoveredLinks();

        this.registerEvents();
		    }

    /**
     * Always hides the menu.
     */
    function Menu_hide() {
        if ( this.m_Shown && this.m_Table != null ) {
            var i;
            for ( i=0; i < this.m_Children.length; i++ ) {
                if ( this.m_Children[i].isMenu() && this.m_Children[i].isShown() ) this.m_Children[i].hide();
                if ( this.m_Children[i].getLink() && this.m_Children[i].getLink().hoverContainer ) document.body.removeChild( this.m_Children[i].getLink().hoverContainer );

                if ( this.m_Children[i].getLink() && this.m_Children[i].getLink().arrow ) document.body.removeChild( this.m_Children[i].getLink().arrow );
            		}

            document.body.removeChild( this.m_Table );
            this.m_Shown = false;
            this.m_Table = null;
        		}
    		}

    /**
     * Hides all child menus of the menu.
     */
    function Menu_hideAllChildren() {
        var i;
        for ( i=0; i < this.m_Children.length; i++ ) {
            if ( this.m_Children[i].isMenu() && this.m_Children[i].isShown() ) this.m_Children[i].hide();
 		       	}
    		}

    /**
     * Creates the html element for the menu.
     */
    function Menu_create() {
        var popupRow, popupCell, row, cell, img, link;
        var cellIdx = 0;
        var popupTable = document.createElement( 'TABLE' );
        popupTable.className = this.getMenuClassName();
        popupTable.style.position = 'absolute';

        if ( this.m_Adjustment == 'HORIZONTAL' ) popupRow = popupTable.insertRow( 0 );

        for ( i=0; i < this.m_Children.length; i++ ) {
            if ( this.m_Adjustment == 'VERTICAL' ) {
                popupRow = popupTable.insertRow( i );
                popupCell = popupRow.insertCell( 0 );
            		}
            else popupCell = popupRow.insertCell( i );

            popupCell.className = this.getMenuClassName();
            if ( i == this.m_Children.length-1 ) popupCell.id = 'PopupMenuBottom';
            else if ( i == 0 ) popupCell.id = 'PopupMenuTop';

            var table = document.createElement( 'TABLE' );
            table.border = '0';
            table.cellSpacing = '0';
            table.cellPadding = '2';

            cellIdx = 0;
            row = table.insertRow( 0 );

            if ( this.m_Children[i].getIcon() ) {
                cell = row.insertCell( cellIdx++ );
                img = document.createElement( 'IMG' );
                if ( IE && this.m_Children[i].getIcon().indexOf( '.png' ) != -1 ) {
                    img.src = 'pictures/spacer.gif';
                    img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.m_Children[i].getIcon() + "', sizingMethod='scale')";
                		}
                else img.src = this.m_Children[i].getIcon();

                img.width = ICON_WIDTH;
                img.height = ICON_HEIGHT;
                img.border = '0';
                cell.appendChild( img );
            		}

            cell = row.insertCell( cellIdx++ );
            cell.className = this.getItemClassName();

            link = document.createElement( 'A' );
            link.className = this.getItemClassName();
            link.href = this.m_Children[i].getUrl();
            link.target = this.m_Children[i].getTarget();

            link.appendChild( document.createTextNode( this.m_Children[i].getText() ) );

            cell.appendChild( link );

            this.m_Children[i].setLink( link );

            popupCell.appendChild( table );
        		}

        return popupTable;
    		}

    /**
     * Register the events for the childs.
     */
    function Menu_registerEvents() {
        var i, link, arrow;
        for ( i=0; i < this.m_Children.length; i++ ) {
            link = this.m_Children[i].getLink().childLink;
            link.parentMenu = this;
            link.oldmouseover = link.onmouseover;
            link.oldmouseout = link.onmouseout;

            if ( link.href == '#' ) link.onclick = function() { return false; };

            if ( this.m_Children[i].isMenu() ) {
                link.menu = this.m_Children[i];
                link.onmouseover = function() {
                    if ( this.oldmouseover ) this.oldmouseover();

                    this.parentMenu.hideAllChildren();
                    window.menuRegistry.stopTimer();
                    this.menu.show( this );
		                };
                link.onmouseout = function() {
                    if ( this.oldmouseout ) this.oldmouseout();

                    window.menuRegistry.startTimer();
		                };

                if ( this.m_Children[i].getDirection() == 'HORIZONTAL' ) {
                    arrow = createArrow( ARROW_IMAGE, ARROW_ZINDEX, ARROW_SIZE, ARROW_COLOR );
                    arrow.style.left = getAbsoluteLeft( link.hover ) + link.hover.offsetWidth - ARROW_SIZE - 5;
                    arrow.style.top = getAbsoluteTop( link.hover ) + link.hover.offsetHeight / 2 - ARROW_SIZE / 2;
                    document.body.appendChild( arrow );
                    this.m_Children[i].getLink().arrow = arrow;
                		}
            		}
            else {
                link.onmouseover = function() {
                    if ( this.oldmouseover ) this.oldmouseover();

                    this.parentMenu.hideAllChildren();
                    window.menuRegistry.stopTimer();
		                };
                link.onmouseout = function() {
                    if ( this.oldmouseout ) this.oldmouseout();
                    window.menuRegistry.startTimer();
    		            };
		            }
        		}
    		}
