
function naviHover(sRootElementID, blTabbing, blIframing, blHiding, iClipIframe)
{
    if (sRootElementID.search(/[^a-z0-9]/i) != -1) {
        alert('Underscore or non-alphanumeric symbols found in Root-ID: ' + sRootElementID);

        return;
    }
    var oRootElement = document.getElementById(sRootElementID);
    if (!oRootElement
        || typeof document.getElementsByTagName == 'undefined'
        || typeof oRootElement.childNodes == 'undefined') {

        return;
    }

    var blMousing = typeof window.execScript != 'undefined';
    blIframing = typeof window.execScript != 'undefined'
                 && typeof document.createEventObject != 'undefined' && blIframing ? true : false;
    blHiding = typeof window.execScript != 'undefined'
               && typeof document.createEventObject == 'undefined' && blHiding ? true : false;
    iClipIframe = iClipIframe ? iClipIframe : 0;
    var aObjectsToHide = new Array();
    if (blIframing || blHiding) {
        var i, ii, aTemp = new Array();
        aTemp[0] = document.getElementsByTagName('SELECT');
        //aTemp[1] = document.getElementsByTagName('OBJECT');
            /* IE = <param name="wmode" value="transparent">
               MOZ, OP 8 = wmode="transparent" */
        for (i=0; i < aTemp.length; i++) {
            for (ii=0; ii < aTemp[i].length; ii++) {
                aObjectsToHide[aObjectsToHide.length] = aTemp[i][ii];
            }
        }
        if (!aObjectsToHide.length) {
            blIframing = false;
            blHiding = false;
        }
    }
    blTabbing = blTabbing ? true : false;
    var oPreviousElement = null;
    var oLastElement = null;

    function getRefCoordinates(oElement)
    {
        var iLeft = 0;
        var iTop  = 0;
        var iWidth = oElement.offsetWidth || 0;
        var iHeight = oElement.offsetHeight || 0;
        var oTemp;
        while (oElement && oElement.nodeName != 'BODY' && oElement.nodeName != 'HTML') {
            iLeft += oElement.offsetLeft+oElement.clientLeft;
            iTop += oElement.offsetTop+oElement.clientTop;
            if (oElement.nodeName == 'UL') {
                oTemp = oElement;
            }
            oElement = oElement.offsetParent;
        }
        if (oTemp) {
            iLeft -= oTemp.clientLeft;
            iTop -= oTemp.clientTop;
        }

        return [iLeft, iTop, iWidth, iHeight];
    }

    function createIFrame(oLIElement, iLIElemID)
    {
        var oULElement = oLIElement.getElementsByTagName('UL')[0];
        if (oULElement) {
            var aCds = getRefCoordinates(oULElement);
            document.getElementsByTagName('BODY')[0].insertAdjacentHTML('beforeEnd'
                , '<iframe id="' + iLIElemID + '_iframe" scrolling="no" frameborder="0"'
                    + 'style="position:absolute;left:' + aCds[0] + 'px;top:' + aCds[1]
                    + 'px;width:' + (aCds[2]-iClipIframe) + 'px;height:' + (aCds[3]-iClipIframe)
                    + 'px;"></iframe>');
        }
    }

    function removeIFrame(iLIElemID)
    {
        var oElement = document.getElementById(iLIElemID + '_iframe');
        if (oElement) {
            document.getElementsByTagName('BODY')[0].removeChild(oElement);
        }
    }

    function setClassName(oElement, sClassName)
    {
        if (typeof oElement.className != 'undefined') {
            oElement.className = sClassName;
        } else if (typeof oElement.setAttribute != 'undefined') {
            oElement.setAttribute('class', sClassName);
        }
    }

    function getClassName(oElement)
    {
        if (typeof oElement.className != 'undefined') {
            return oElement.className;
        } else if (typeof oElement.getAttribute != 'undefined') {
            return oElement.getAttribute('class');
        } else {
            return '';
        }
    }

    function getParams(oElement, blParent)
    {
        var sID = oElement.getAttribute('id');
        var aTemp = sID.split('_');
        var aParams = new Array();
        aParams['sID'] = sID;
        aParams['sRootID'] = aTemp[0];
        aParams['iL0Menu'] = parseInt(aTemp[1]);
        aParams['iLevel'] = parseInt(aTemp[2]);
        aParams['iSibling'] = parseInt(aTemp[3]);
        if (blParent) {
            aParams['iParentElement'] = parseInt(oElement.getAttribute('sParentElement'));
        }

        return aParams;
    }

    function closeMenu(oElement)
    {
        if (!oElement) {
            return;
        }
        var aParams = getParams(oElement, true);
        var i, sLoopParentID, oLoopElement = oElement, aLoopParams = aParams;
        for (i=aParams['iLevel']; i >= 0; i--) {
            setClassName(oLoopElement, '');
            if (blIframing) {
                removeIFrame(aLoopParams['sID']);
            }
            if (aLoopParams['iLevel'] == 0) {
                break;
            }
            sLoopParentID = aLoopParams['sRootID'] + '_' + aLoopParams['iL0Menu'] + '_'
                            + (aLoopParams['iLevel']-1) + '_' + aLoopParams['iParentElement'];
            oLoopElement = document.getElementById(sLoopParentID);
            aLoopParams = getParams(oLoopElement, true);
        }
        if (blHiding) {
            for (i=0; i < aObjectsToHide.length; i++) {
                aObjectsToHide[i].style.visibility = 'visible';
            }
        }
        oPreviousElement = null;
    }

    function openMenu(oElement)
    {
        if (!oElement) {
            return;
        }
        var i, aCurParams = getParams(oElement);
        if (oPreviousElement) {
            var aPrevParams = getParams(oPreviousElement, true);
            if (aCurParams['sID'] == aPrevParams['sID']
                || (getClassName(oElement) && aCurParams['iLevel'] < aPrevParams['iLevel'])) {

                return;
            }
            if (aCurParams['iLevel'] <= aPrevParams['iLevel']) {
                setClassName(oPreviousElement, '');
                if (blIframing) {
                    removeIFrame(aPrevParams['sID']);
                }
            }
            if (aCurParams['iLevel'] < aPrevParams['iLevel']) {
                var sLoopParentID, oLoopParent, aLoopParams = aPrevParams;
                for (i=aPrevParams['iLevel']; i > aCurParams['iLevel']; i--) {
                    sLoopParentID = aLoopParams['sRootID'] + '_' + aLoopParams['iL0Menu'] + '_'
                                    + (aLoopParams['iLevel']-1) + '_' + aLoopParams['iParentElement'];
                    oLoopParent = document.getElementById(sLoopParentID);
                    setClassName(oLoopParent, '');
                    aLoopParams = getParams(oLoopParent, true);
                    if (blIframing) {
                        removeIFrame(aLoopParams['sID']);
                    }
                }
            }
        }
        setClassName(oElement, sRootElementID + '_hover');
        if (blIframing) {
            createIFrame(oElement, aCurParams['sID']);
        }
        if (blHiding) {
            for (i=0; i < aObjectsToHide.length; i++) {
                aObjectsToHide[i].style.visibility = 'hidden';
            }
        }
        oPreviousElement = oElement;
    }

    function getParentListElement(oElement)
    {
        while (oElement) {
            oElement = oElement.parentNode;
            if (oElement && oElement.nodeName == 'LI') {
                break;
            }
        }

        return oElement;
    }

    function swapBlur()
    {
        if (blTabbing) {
            if (this == oLastElement) {
                var oElement = getParentListElement(this);
                closeMenu(oElement);
            }
        }
    }

    function swapFocus()
    {
        if (blTabbing) {
            var oElement = getParentListElement(this);
            openMenu(oElement);
        }
    }

    function swapOut(oEvent)
    {
        if (typeof oEvent != 'undefined' && oEvent.stopPropagation) {
            oEvent.stopPropagation();
        } else if (typeof window.event != 'undefined') {
            window.event.cancelBubble = true;
        }
        if (blMousing && typeof window.event != 'undefined') {
            var oElement = window.event.toElement;
            if (oElement) {
                var blClose = true;
                while (oElement && oElement.nodeName != 'BODY') {
                    if (typeof oElement.getAttribute != 'undefined'
                        && oElement.getAttribute('id') == sRootElementID) {

                        blClose = false;
                        break;
                    }
                    oElement = oElement.parentNode;
                }
                if (blClose) {
                    closeMenu(oPreviousElement);
                }
            }
        }
    }

    function swapOver(oEvent)
    {
        if (typeof oEvent != 'undefined' && oEvent.stopPropagation) {
            oEvent.stopPropagation();
        } else if (typeof window.event != 'undefined') {
            window.event.cancelBubble = true;
        }
        if (!blMousing && blTabbing && oPreviousElement) {
            closeMenu(oPreviousElement);
        }
        if (blMousing) {
            openMenu(this);
        }
    }

    function swapClick()
    {
        if ((blMousing || blTabbing) && oPreviousElement) {
            closeMenu(oPreviousElement);
        }
    }

    function handleListElements(oElement, iLevelCnt, iParentCnt)
    {
        var i, ii, oTabbingElement, oChildNode;
        for (i=0; i < oElement.childNodes.length; i++) {
            if (oElement.childNodes[i].nodeName == 'LI') {
                oChildNode = oElement.childNodes[i];
                if (blMousing || blTabbing) {
                    oChildNode.setAttribute('id', sRootElementID + '_' + iMenuL0Cnt + '_' + iLevelCnt + '_' + i);
                    oChildNode.setAttribute('sParentElement', iParentCnt);
                    oChildNode.onmouseover = swapOver;
                }
                if (blMousing) {
                    oChildNode.onmouseout = swapOut;
                }
                if (blTabbing) {
                    oTabbingElement = oChildNode.getElementsByTagName('A')[0];
                    if (oTabbingElement) {
                        oTabbingElement.onfocus = swapFocus;
                        oTabbingElement.onblur = swapBlur;
                        oLastElement = oTabbingElement;
                    }
                }
            }
            for (ii=0; ii < oElement.childNodes[i].childNodes.length; ii++) {
                handleListElements(oElement.childNodes[i].childNodes[ii], 1+iLevelCnt, i);
            }
            if (iLevelCnt == 0) {
                iMenuL0Cnt++;
            }
        }
    }
    var iMenuL0Cnt = 0;
    handleListElements(oRootElement, 0, 0);

    if (typeof document.addEventListener != 'undefined') {
        document.addEventListener('click', swapClick, false);
    } else if (typeof document.attachEvent != 'undefined') {
        document.attachEvent('onclick', swapClick);
    } else if (typeof document.onclick == 'function') {
		var fOnClick = document.onclick;
        document.onclick = function(oEvent)
        {
            fOnClick(oEvent);
            swapClick(oEvent);
        }
	} else {
        document.onclick = swapClick;
	}
}
