/******************************************************************************
 Script for menu creation/decoration.

 @author Pavel Horal (pavel.horal@orchitech.cz)
*******************************************************************************/

/**
 * Menu decorating object.
 */
function Menu(rootNode) {

    /**
     * Root menu node.
     */
    var rootNode = rootNode;

    /**
     * Style for hidden sub menus.
     */
    var hiddenStyle = {
            "visibility": "hidden",
            "height": "1px",
            "overflow": "hidden"
    };

    /**
     * Style for visible sub menus.
     */
    var visibleStyle = {
            "visibility": "visible",
            "height": "auto",
            "overflow": "visible"
    };

    /**
     * Decorates child menu nodes with propriate event handlers, animations, etc.
     * @param parentNode Parent node of menu element.
     */
    function decorateMenu(parentNode) {
        var menuNode = getMenuNode(parentNode);
        decorateMenuNode(null, menuNode, 0);
    }

    /**
     * Recursivly find first child UL node.
     * @param parentNode
     * @return DOM UL Node or null.
     */
    function getMenuNode(parentNode) {
        var childs = parentNode.childNodes;
        for (var i = 0; i < childs.length; i++) {
            if (childs[i].nodeName == "UL") {
                return childs[i];
            } else if (childs[i].nodeName) {
                var child = getMenuNode(childs[i]);
                if (child) {
                    return child;
                }
            }
        }
        return null;
    }

    /**
     * Decorate menu with event handlers.
     * @param menuNode
     * @param level Menu level.
     */
    function decorateMenuNode(parentItem, menuNode, level) {
        var menuItems = menuNode.childNodes;
        for (var i = 0; i < menuItems.length; i++) {
            if (menuItems[i].nodeName == "LI") {
                var menuItem = menuItems[i];
                var subMenu = getMenuNode(menuItem);
                if (subMenu) {
                    setMenuItemStyle(menuItem, subMenu, level);
                    if (!dojo.isIE || dojo.isIE > 6) {
                        setMenuItemEventAnimations(menuItem, subMenu, level);
                    } else {
                        addIframeBase(menuItem, subMenu);
                    }
                    setMenuItemEventHandlers(parentItem, menuItem, subMenu);
                    decorateMenuNode(menuItem, subMenu, level + 1);
                    dojo.style(subMenu, hiddenStyle);
                }

            }
        }
    }

    /**
     * Add IFRAME element so that menu can be displayed over select boxes.
     * This is necessary only for Internet Explorer 6.
     * @param menuItem
     * @param subMenu
     */
    function addIframeBase(menuItem, subMenu) {
         var iframe = document.createElement("IFRAME");
         iframe.src = dojo.baseUrl + "resources/blank.html";
         menuItem.insertBefore(iframe, subMenu);
         dojo.style(iframe, {
            "width": subMenu.offsetWidth + "px",
            "height": subMenu.offsetHeight + "px",
            "top": subMenu.offsetTop + "px",
            "left": subMenu.offsetLeft + "px",
            "position": "absolute",
            "display": "none"
         });
    }

    /**
     * Get IFRAME element for given menu item.
     * @return
     */
    function getIframe(menuItem) {
         var nodes = menuItem.childNodes;
         for (var i = 0; i < nodes.length; i++) {
             if (nodes[i].nodeName == "IFRAME") {
                 return nodes[i];
             }
         }
         return null;
    }

    /**
     * Decorate menu with CSS properties.
     * @param menuItem
     * @param subMenu
     * @param level
     */
    function setMenuItemStyle(menuItem, subMenu, level) {
        dojo.style(menuItem, "position", "relative");
        if (level == 0) {
            dojo.style(subMenu, {
                "left": '-1px',
                "top": menuItem.offsetHeight + 'px'
            });
        } else {
            dojo.style(subMenu, {
                "left": menuItem.offsetWidth + 'px',
                "top": '-1px'
            });
        }
    }

    /**
     * Add menu event animations.
     * @param menuItem
     * @param subMenu
     * @param level
     */
    function setMenuItemEventAnimations(menuItem, subMenu, level) {
        dojo.style(subMenu, "opacity", 0);
        menuItem.inAnimation = dojo.fadeIn({
            node: subMenu,
            duration: 200,
            onBegin: function() {
                setMenuItemStyle(menuItem, subMenu, level);
                dojo.style(subMenu, visibleStyle);
            }
        });
        menuItem.outAnimation = dojo.fadeOut({
            node: subMenu,
            duration: 200,
            onEnd: function() { dojo.style(subMenu, hiddenStyle); },
            onStop: function() { dojo.style(subMenu, "opacity", "1"); }
        });
    }

    /**
     * Add event handlers to given menu item.
     * @param parentItem
     * @param menuItem
     * @param subMenu
     * @param level
     */
    function setMenuItemEventHandlers(parentItem, menuItem, subMenu) {
        menuItem.onmouseover = function() {
            menuItem.mouseOver = true;
            menuMouseOver(menuItem, subMenu);
        };
        menuItem.onmouseout = function() {
            menuItem.mouseOver = false;
            setTimeout(
                function() {
                    if (!menuItem.mouseOver) {
                        menuMouseOut(menuItem, subMenu);
                    }
                },
                50
            );
        };
    }

    /**
     * OnMouseOver event handler.
     * @param menuItem
     * @param subMenu
     */
    function menuMouseOver(menuItem, subMenu) {
        if (menuItem.outAnimation && menuItem.outAnimation.status() == "playing") {
            menuItem.outAnimation.stop(false);
        } else if (menuItem.inAnimation) {
            menuItem.inAnimation.play(null, true);
        } else {
            var iframe = getIframe(menuItem);
            if (iframe) {
                iframe.style.display = "block";
            }
            dojo.style(subMenu, visibleStyle);
        }
    }

    /**
     * OnMouseOut event handler.
     * @param menuItem
     * @param subMenu
     */
    function menuMouseOut(menuItem, subMenu) {
        if (menuItem.outAnimation) {
            menuItem.outAnimation.play(null, true);
        } else {
            var iframe = getIframe(menuItem);
            if (iframe) {
                iframe.style.display = "none";
            }
            dojo.style(subMenu, hiddenStyle);
        }
    }

    decorateMenu(rootNode);
}

/*
 * Automatic on-load decoration.
 * You may comment latter line and call menu decoration right after complete
 * menu is loaded.
 * If active be sure to include Dojo toolkit before this file.
 */
dojo.addOnLoad(function() { Menu(dojo.byId('webMenu')); });

