// .decueue fix
( function( $ ) {
        $.dequeue = function( a , b ){
                return $(a).dequeue(b);
        };

 })( jQuery );

jQuery.fn.hypergeneMenu = function() {
    
    var menu = this[0];
    var activeUL;
    var timer;
    var activationTimer;
    
    var showSubMenu = function() {
        //this = <ul>
        // list items
        $(this).addClass('expanded');
        
        
        var li = $(this).find("> li");
        
        // sub menu open, change state so UL will rerender
        $(this).data("menu", "open");
        
        // hide UL (<a> sibling)
        $(this).hide();
        
        // hide all sub menus
        $(this).each(hideSubMenus);
        
        // remove class menu left from selected
        var selected_a_submenu = $(li).find("> a").filter(".option.selected.menu")[0];
        var selected_a = $(li).find("> a").filter(".option.selected")[0];
        
        if (selected_a_submenu) {
            var left = $(li).find("> a").filter(".option.selected.menu.left")[0];
            var right = $(li).find("> a").filter(".option.selected.menu.right")[0];
            
            if (left) $(selected_a_submenu).data("float", "left");
            else if(right) $(selected_a_submenu).data("float", "right");

            //$(selected_a_submenu).each(removeClassSelectedSub);
            $(selected_a_submenu).each(removeMouseEvents);
        }
        else if (selected_a) {
            $(selected_a).each(removeClassSelected);
        }
        
        // rerender UL sibling menus (first child to #menu)
        $(this).parent().each(renderMenuULSibling);

            
        // show ul
        $(this).show();       
              
        // show all li siblings
        $(this).data("siblings", "visible"); 
        $(li).each(animateLIWidth);
    };

    
    var animateLIWidth = function() {
        // this = <li>
        $(this).hide().show(300);
    };





    // show submenu animation
    var overA = function() {
        // return
        // this = <a>
        if($(this).parent().parent().attr('class').indexOf('right') === -1) {
            return
        }        
        if (menuState == "activated") {
            // reRender UL sibling
            
            var ul = $($(this).parent()[0]).find("> ul")[0];


            if ($(ul).data("siblings") == "hidden") {
                // hide submenu
                $(ul).hide().each(showSubMenu);
            }            
        }
    };
    
    
    
    // find parent <ul> with #menu parent, rerender sibling ul
    var renderMenuULSibling = function() {
        // this = <li
        if ($($(this)[0]).parent()[0].id == "menu") {
            activeUL = this;
        }
        
        if ($(this)[0].id == "menu") {
            $(this).find("> ul").not(activeUL).each(setupUL);
        } else {
            $(this).parent().each(renderMenuULSibling);
        }
    }


    var removeClassSelected = function() {
        //this = <a>
        $(this).data("class", "selected");
        $(this).removeClass("selected");
    }

    var removeClassSelectedSub = function() {
        //this = <a>
        $(this).data("class", "selected menu " + $(this).data("float"));
        $(this).removeClass("selected menu " + $(this).data("float"));
    };
    
    var resetClass = function() {
        if ($(this).data("class")){
            $(this).addClass($(this).data("class"));
        }
    };
    
    var removeMouseEvents = function() {
        //this = <a>
		$(this).unbind('mouseover mousemove', overA);
    };
    
    var addMouseEvents = function() {
        //this = <a>
		$(this).bind('mouseover mousemove', overA);
    };

    var hideSubMenus = function() {
        //this = <ul>
        // change state on all submenus, so all rerender for breadcrum

        
        $(this).data("menu", "open");    
        $(this).find("> li").find("> ul").hide()
        // recursive call
        $(this).find("> li").find("> ul").each(hideSubMenus);
    };

  
    var setupA = function() {
        //this = <a>
        // setup only <a> with class=".option.selected"

        // show <a>'s parent <li>
        var parent_li = $(this).parent()[0];     

        // show <li>'s parent <ul>
        var parent_ul = $(parent_li).parent()[0];
        $(parent_ul).show();
                
        deactivateMenu();
        // build breadcrum, never animate first li
        if ($(parent_ul).parent()[0].id == "menu"){
            $(parent_li).show(10, checkMenu); 
        } else {
            $(parent_li).hide().show(200, checkMenu);
        }

        
        // Add mouse events if Submenu(UL) exists
        if ($($(this).parent()[0]).find("> ul")[0]) {
            // add mouse events
            $(this).each(addMouseEvents);
        }
        
    };
    
    
    var checkMenu = function() {
        // this = <a>
        if(activationTimer) window.clearTimeout(activationTimer);
        activationTimer = window.setTimeout(activateMenu, 250);
    }

  
    
    var setupLI = function() {
        //this = <li>
        // if($(this).parent().attr('class').indexOf('right')!== -1) {
        //     $(this).hide();
        // }
        // 
        if($(this).parent().parent().parent().attr('class').indexOf('left') === -1) {
            // console.log('YEA')
            $(this).parent().hide();
        }
        $($(this).parent()[0]).data("siblings", "hidden");
        
        $(this).find("> a").each(resetClass);
        $(this).find("> a").filter(".option.selected").each(setupA);
        
        // recursive call, setup all submenus
        $(this).find("> ul").each(setupUL);
    };



    var setupUL = function(){
        //this = <ul>        
        var ul_state = $(this).data("menu") || "open";
            
        if (ul_state == "open") {
            // menu changed, will rerender, deactivate menu
            $(this).data("menu", "closed");

            // if($(this).attr('class').indexOf('right')!== -1) {
            //     $(this).hide();
            // }
            // if($(this).attr('class').indexOf('left')!== -1) {
            //     $(this).show();
            // }

            // for each LI
            $(this).find("> li").each(setupLI);      
        }
        else {
            // recursive call, continue checking for open ULs
            $(this).find("> li").find("> ul").each(setupUL);   
        }
        
            
    };
    
    function deactivateMenu() {
        menuState = "deactivated";
    }
    
    function activateMenu() {
        menuState = "activated";
    }
    
    var renderMenu = function() {
        //$(menu).find('ul').removeClass('expanded');
        var options = $(menu).find("> ul");
        options.each(setupUL);
    };
    
    var startTimer = function (){
    	timer = window.setTimeout(renderMenu, 1000);
    };

    var resetTimer = function (){
    	if(timer) window.clearTimeout(timer);
    };
    
    var menuState;
    var activationTimer = false;
    var timer = false;
    
    // render menu, 
    $(menu).width(950).height(24); // 20
    
    // deactivate menu A, activated after breadcrum rendered
    deactivateMenu();
    renderMenu();
    // bind mouseout -> reset menu
    $(menu).bind("mouseout", startTimer);
    $(menu).bind("mouseover", resetTimer);

    // $(menu).find('li').mouseover(function() { 
    //     if(!$(this).hasClass('option') && !$(this).children('a').hasClass('toplevel')) {
    //         $(this).addClass('selected')
    //     }
    // })
    // $(menu).find('li').mouseout(function() { 
    //     if(!$(this).hasClass('option') && !$(this).children('a').hasClass('toplevel')) {
    //         $(this).removeClass('selected')
    //     }
    // })   
    $(menu).find('li').mouseover(function() { 
        if(!$(this).hasClass('leaf')  && !$(this).children('a').hasClass('toplevel')) { 
            $(this).addClass('orange')
        }
    })
    $(menu).find('li').mouseout(function() { 
        if(!$(this).hasClass('leaf') && !$(this).children('a').hasClass('toplevel')) {
            $(this).removeClass('orange')
        }
    })
    
    $('#toplevel_left').mouseover(function() {
        if(!$(this).hasClass('active'))
            $(this).addClass('hover')
    })
    $('#toplevel_left').mouseout(function() {
        if(!$(this).hasClass('active'))        
            $(this).removeClass('hover')
    })    
    $('#toplevel_right').mouseover(function() {
        if(!$(this).hasClass('active'))        
            $(this).addClass('hover')
    })
    $('#toplevel_right').mouseout(function() {
        if(!$(this).hasClass('active'))        
            $(this).removeClass('hover')
    })    


    return this;
};