/*
===================================================
XHTML/CSS/DHTML Semantically correct drop down menu
===================================================
Author: Sam Hampton-Smith
Site: http://www.hampton-smith.com

Description:	This script takes a nested set of <ul>s
		and turns it into a fully functional
		DHTML menu. All that is required is
		the correct use of class names, and
		the application of some CSS.

Use:		Please leave this information at the
		top of this file, and it would be nice
		if you credited me/dropped me an email
		to let me know you have used the menu.
		sam AT hampton-smith.com
---------------------------------------------------
Credits:
    Inspiration/Code borrowed from Dave Lindquist (http://www.gazingus.org)
    Menu hide functionality was aided by some code I found on http://www.jessett.com/
    Enhancements and extensive rework by Ittrium, LLC (2004-2007)
*/
var currentAnchor = new Array();  // Chain of active menu anchors
var timerInterval = 500;
var xDownBias = 5; var yDownBias = -1;
var xSideBias = 2; var ySideBias = 2;

if ( !document.getElementById ) {
	document.getElementById = function() { return null; }
}
/* We expect an <A> nested in a <DIV> nested in a <LI> */
function initializeMenu( pMenuBlock, pMenuAnchor, pWorkOnWrapper, pRoot ) {
	if ( pMenuAnchor == null ) return;
    var activeItem = (pWorkOnWrapper) ? pMenuAnchor.parentNode.parentNode : pMenuAnchor;

    activeItem.myMenuBlock = pMenuBlock;
    activeItem.myAnchor = pMenuAnchor;
    activeItem.onWrapper = pWorkOnWrapper;

    activeItem.onmouseover = function() {
        var parentBlock = (this.onWrapper) ? this.parentNode : this.parentNode.parentNode.parentNode;
        if ( parentBlock == pRoot ) {
            // Possible change of top level menu, close the old chain immmediately
            if ( (currentAnchor.length > 0) && (currentAnchor[0] != this)) {
                killMenu( currentAnchor[0].myMenuBlock );
                currentAnchor.length = 0;
            }
        } else if ( currentAnchor.length > 0 ) {
            // Either my parent or a sibling should be last on the list
            var activeMenu = currentAnchor[currentAnchor.length-1].myMenuBlock;
            if ( parentBlock != activeMenu ) {
                // Hide my sibling
                killMenu( activeMenu );
            }
        }
        this.showMenu();
    }
    activeItem.onmouseout = function() {
        if ( this.onWrapper ) {
            makeActive( this, false );
        }
        if ( this.myMenuBlock != null ) {
            // My submenu may be disappearing, but give the cursor
            // a chance to select it...
            this.myMenuBlock.activeCounter -= 1;
            setTimeout( hideInactiveMenus, timerInterval );
        }
    }
    activeItem.showMenu = function() {
        if ( this.myMenuBlock != null ) {
            var parentBlock = (this.onWrapper) ? this.parentNode : this.parentNode.parentNode.parentNode;
            if ( parentBlock == pRoot ) {
                // Position as initial item
                var origin = new Array();
                if ( parentBlock.className == 'ddmenuV' ) {
                    // Vertical parent (position immediately to the right)
                    origin['left'] = this.offsetWidth
                                   + (this.onWrapper ? -xSideBias : xSideBias);
                    origin['top' ] = 0;
                } else {
                    // Horizontal parent (position beneath and slightly right)
                    origin['left'] = xDownBias;
                    origin['top'] =  this.offsetHeight + yDownBias;
                }
                origin = absoluteOrigin( origin, this );
                this.myMenuBlock.style.left = origin['left'] + "px";
                this.myMenuBlock.style.top = origin['top'] + "px";
            } else {
                // Position as pull right (immediately to the right, slightly down)
                this.myMenuBlock.style.left = (this.offsetLeft + this.offsetWidth
                                                + (this.onWrapper ? -xSideBias : xSideBias)) + "px";
                this.myMenuBlock.style.top = (this.offsetTop + ySideBias) + "px";
            }
            // Make my submenu visible
            this.myMenuBlock.style.visibility = "visible";
            this.myMenuBlock.activeCounter = 1;
            currentAnchor[currentAnchor.length] = this;
        }
        if ( this.onWrapper ) {
            makeActive( this, true );
        }
    }
    activeItem.onfocus = function() {
        this.onmouseover();
    }
    if ( pWorkOnWrapper ) {
        // Accept clicks on the wrapper
        activeItem.onclick = function( pEvent ) {
            var source = (typeof pEvent == "undefined") ? window.event.srcElement : pEvent.target;
            if ( (source == this) || (source.parentNode == this) ) {
                if ( (this.myAnchor.target == null) || (this.myAnchor.target == "") ) {
                    document.location = this.myAnchor.href;
                } else {
                    window.open( this.myAnchor.href, this.myAnchor.target );
                }
                return( false );
            }
        }
    }
    if ( pMenuBlock != null ) {
        pMenuBlock.activeCounter = 0;

        pMenuBlock.onmouseover = function() {
            this.showMenu();
        }
        pMenuBlock.onfocus = function() {
        }
        pMenuBlock.showMenu = function() {
            // Make this menu visible
            this.style.visibility = "visible";
            this.activeCounter += 1;
        }
        pMenuBlock.hideMenu = function() {
            // You can only hide the menu if it is at the END of the chain
            if ( (currentAnchor.length > 0) && (this == currentAnchor[currentAnchor.length-1].myMenuBlock) ) {
                this.activeCounter -= 1;
                if ( this.activeCounter <= 0 ) {
                    killMenu( this );
                }
            }
        }
        pMenuBlock.onmouseout = function() {
            this.activeCounter -= 1;
            setTimeout( hideInactiveMenus, timerInterval);
        }
    } else {
        //alert( "Empty Anchor" );
    }
}
function hideInactiveMenus() {
    // Scan the active list
    for( var x = currentAnchor.length-1; x >= 0; x-- ) {
        var aMenu = currentAnchor[x].myMenuBlock;
        if ( aMenu.activeCounter <= 0 ) {
            // Inactive menu can be eliminated
            killMenu( aMenu );
        }
    }
}
function killMenu( pMenu ) {
    // Hide the menu (and any open submenus)
    if ( pMenu != null ) {
        pMenu.style.visibility = "hidden";
        pMenu.activeCounter = 0;
        if ( pMenu.onWrapper ) {
            makeActive( pMenu, false );
        }
        for( var x=0; x < pMenu.childNodes.length; x++ ) {
            var childNode = pMenu.childNodes[ x ];
            if ( childNode.nodeName == "LI" ) {
                // Hide submenus ( <UL> nested within a <DIV> )
                var divList = childNode.getElementsByTagName("DIV");
                if ( divList.length > 0 ) {
                    var subMenus = divList.item(0).getElementsByTagName("UL");
                    for( var y=0; y < subMenus.length; y++ ) {
                        var subMenu = subMenus.item(y);
                        if ( subMenu.style.visibility != "hidden" ) {
                            killMenu( subMenu );
                        }
                    }
                }
            }
        }
        // Keep the anchor chain tidy
        if ( (currentAnchor.length > 0) && (currentAnchor[currentAnchor.length-1].myMenuBlock == pMenu) ) {
            currentAnchor.length = currentAnchor.length-1;
        }
    }
}
function absoluteOrigin( pOrigin, pElement ) {
	var left = pOrigin['left'] + pElement.offsetLeft;
	var top = pOrigin['top'] + pElement.offsetTop;
	pOrigin['left'] = left;
	pOrigin['top'] = top;

	var parent = pElement.offsetParent;
	if ( parent != document.body ) {
		pOrigin = absoluteOrigin( pOrigin, parent );
	}
    return( pOrigin );
}
function makeActive( pElement, pTurnOnOff ) {
    var alterClassName = pElement.className;
    if ( alterClassName.substring( alterClassName.length - 2 ) == "ON" ) {
        if ( !pTurnOnOff ) {
            // Turn it off, since it is actually on
            alterClassName = alterClassName.substring( 0, alterClassName.length -2 );
            pElement.className = alterClassName;
        }
    } else {
        if ( pTurnOnOff ) {
            // Turn it on, since it is actually off
            pElement.className = alterClassName + "ON";
        }
    }
}

function getMenus( pElementItem, pRoot, pWrapperTag, pWorkOnWrapper, pXBias, pYBias ) {
    if ( typeof pWrapperTag == "undefined" ) pWrapperTag = "LI";
    if ( typeof pWorkOnWrapper == "undefined" ) pWorkOnWrapper = true;
    if ( typeof pXBias != "undefined" ) { xDownBias = pXBias; xSideBias = pXBias; }
    if ( typeof pYBias != "undefined" ) { yDownBias = pYBias; ySideBias = pYBias; }

    // If we operate on the wrapper, less delay is needed since the wrapper
    // overlaps with the menu the mouse needs to enter
    if ( pWorkOnWrapper ) timerInterval = 100;

    var childList = pElementItem.childNodes;
	for( var x=0; x < childList.length; x++ ) {
        var childNode = childList[x];
		if ( childNode.nodeName == pWrapperTag ) {
            // Anchors/submenus buried in a div
            var divList = childNode.getElementsByTagName("DIV");
            if ( divList.length > 0 ) {
                childNode = divList.item(0);
                var menuAnchor = null;
                var menuBlock = null;

                // The anchor that takes us to the target
                var anchorList = childNode.getElementsByTagName("A");
                if ( anchorList.length > 0 ) {
                    var menuAnchor = anchorList.item(0);
                }
                // Nested menu within this menu item
                var menuBlocks = childNode.getElementsByTagName("UL");
                if ( menuBlocks.length > 0 ) {
                    // Initialize the submenu
                    menuBlock = menuBlocks.item(0);
                    getMenus( menuBlock, pRoot, "LI", pWorkOnWrapper );
                }
                initializeMenu( menuBlock, menuAnchor, pWorkOnWrapper, pRoot );
            }
		}
	}
}

