function llx3_Menu() {
    var This = this;
    var MenuInfos = new Array();
    this.effect = "";


    this.showMenu = function (link, menuElement, position, effect, selectedcss) {
        This.addMenu(link, menuElement, position, effect, selectedcss).showMenu();
    }

    this.addMenu = function (link, menuElement, position, effect, selectedcss) {
        for (var i = 0; i < MenuInfos.length; i++) { if ((MenuInfos[i].link == link) && (MenuInfos[i].menuContainer == menuElement)) return MenuInfos[i]; }
        var m = GetMenu(link);
        if (m != null) return m;
        var mi = new MenuInfo();
        mi.link = link;
        mi.effect = effect;
        mi.menuContainer = menuElement;
        mi.position = position;
        if (selectedcss) mi.hoverClassName = selectedcss;
        mi.defaultClassName = link.className;
        MenuInfos.push(mi);
        link.onmouseout = mi.hideMenu;
        if (menuElement) {
            menuElement.onmouseout = mi.hideMenu;
            menuElement.onmouseover = mi.showMenu2;
            menuElement.style.position = "absolute";
        }
        return mi;
    }

    function MenuInfo() {
        var ThisMI = this;
        this.link = null;
        this.menuContainer = null;
        this.isOpen = false;
        this.effect = "";
        var cTimeout = 0;
        this.position = "bottom";
        var effectIntv = 0;
        var effectCount = 0;
        this.hoverClassName = "";
        this.defaultClassName = "";

        this.showMenu = function () {
            clearTimeout(cTimeout);
            ThisMI.link.className = ThisMI.hoverClassName;
            if (ThisMI.menuContainer != null) {
                switch (ThisMI.effect) {
                    case "fade":
                        $(ThisMI.menuContainer).fadeIn(200);

                        break;
                    default:
                        ThisMI.menuContainer.style.display = "block";
                        break;
                }
                switch (ThisMI.position) {
                    case "right":
                        ThisMI.menuContainer.style.top = "0px";
                        ThisMI.menuContainer.style.left = ThisMI.link.offsetWidth + "px";
                        break;
                    default:
                        ThisMI.menuContainer.style.left = (ThisMI.link.offsetWidth / 2 - ThisMI.menuContainer.offsetWidth / 2) + "px";
                } 
            }
            for (var i = 0; i < MenuInfos.length; i++) {
                if ((MenuInfos[i] != ThisMI) && (IsLinkChild(MenuInfos[i].menuContainer, this.link) == false)) { MenuInfos[i].hideMenuNow(); }
            }
        }
        this.showMenu2 = function () {
            clearTimeout(cTimeout);
        }
        this.hideMenu = function () {
            clearTimeout(cTimeout);
            if (ThisMI.menuContainer) {
                cTimeout = setTimeout(execHideMenu, 500);
            } else {
                cTimeout = setTimeout(execHideMenu, 1);
            }
        }
        this.hideMenuNow = function () {
            execHideMenu();
        }

        function execHideMenu() {
            ThisMI.link.className = ThisMI.defaultClassName;
            if (ThisMI.menuContainer != null) {
                switch (ThisMI.effect) {
                    case "fade":
                        $(ThisMI.menuContainer).fadeOut(200);
                        break;
                    default:
                        ThisMI.menuContainer.style.display = "none";
                        break;
                }
            }
        }
    }

    function GetMenu(link) {
        for (var i = 0; i < MenuInfos.length; i++) { if (MenuInfos[i].link == link) return MenuInfos[i]; }
        return null;
    }


    function IsLinkChild(parent, child) {
        if (parent == null) return false;
        var children = parent.getElementsByTagName("A");
        for (var i = 0; i < children.length; i++) { if (children[i] == child) return true; }
        return false;
    }

}
