/* 
todo: close delay
todo: click button to open

http://www.sohtanaka.com/web-design/examples/drop-down-menu/#
http://www.noupe.com/tutorial/drop-down-menu-jquery-css.html
http://css-tricks.com/examples/DiggHeader/#
*/

(function($){
    $.fn.dropmenu = function(custom) {
        var defaults = {
            openAnimation: "slide",
            closeAnimation: "slide",
            openClick: false,
            openSpeed: 500,
            closeSpeed: 700,
            closeDelay:500,
            onHide: function(){},
            onHidden: function(){},
            onShow: function(){},
            onShown: function(){}
          };
        var settings = $.extend({}, defaults, custom);
        
        var menu = this;
        var currentPage = 0;
        var delayTimer = "";
        
        // Trigger init
        init();
        
        /**
         * Do preparation work
         */
        function init(){

            // Add open button and class to parent of a submenu
            var items = menu.find(":has(li,div) > a").append('<span class="arrow"></span>');
            $.each(items, function(i, val) {
                if(items.eq(i).parent().is("li")){
                    items.eq(i).next().addClass("submenu").parent().addClass("haschildren");
                }else{
                    items.eq(i).parent().find("ul").show();
                }
            });
            
            if(settings.openClick){
                menu.find(".submenu").css("display", "none");
                menu.find(":has(li,div) > a").parent().bind("mouseleave",handleHover).bind("mouseenter",function(){ window.clearInterval(delayTimer); });
                menu.find("a span.arrow").bind("click", handleHover);
            }else{
                menu.find(":has(li,div) > a").bind("mouseenter",handleHover).parent().bind("mouseleave",handleHover).bind("mouseenter",function(){ window.clearInterval(delayTimer); });
            }
            
            
        }
        
        /**
         * Handle mouse hover action
         */
        function handleHover(e){
            if(e.type == "mouseenter" || e.type == "click"){
                window.clearInterval(delayTimer);
                var current_submenu = $(e.target).parent().find(".submenu:not(:animated):not(.open)");
                if(current_submenu.html() == null){
                    current_submenu = $(e.target).parent().next(".submenu:not(:animated):not(.open)");
                }
                if(current_submenu.html() != null){
                    settings.onShow.call(current_submenu);
                    closeAllMenus();
                    current_submenu.prev().addClass("selected");
                    current_submenu.css("z-index", "90");
                    current_submenu.stop().hide();
                    openMenu(current_submenu);
                }
            }
            if(e.type == "mouseleave" || e.type == "mouseout"){
                current_submenu = $(e.target).parents(".submenu");
                if(current_submenu.length != 1){
                    var current_submenu = $(e.target).parent().parent().find(".submenu");
                    if(current_submenu.html() == null){
                        var current_submenu = $(e.target).parent().find(".submenu");
                        if(current_submenu.html() == null){
                            var current_submenu = $(e.target).parent().parent().parent().find(".submenu");
                        }
                    }
                }
                if(current_submenu.html() != null){
                    if(settings.closeDelay == 0){
                        current_submenu.parent().find("a").removeClass("selected");
                        closeMenu(current_submenu);
                    }else{
                        window.clearInterval(delayTimer);
                        delayTimer = setInterval(function(){
                            window.clearInterval(delayTimer);
                            closeMenu(current_submenu);
                        }, settings.closeDelay);    
                    }
                }
            }
        }
        
        function openMenu(object){
            switch(settings.openAnimation){
                case "slide":
                    openSlideAnimation(object);
                    break;
                case "fade":
                    openFadeAnimation(object);
                    break;
                default:
                    openSizeAnimation(object);
                    break;
            }
        }
        
        function openSlideAnimation(object){
            object.addClass("open").slideDown(settings.openSpeed, function(){ settings.onShown.call(this); });
        }
        
        function openFadeAnimation(object){
            object.addClass("open").fadeIn(settings.openSpeed, function(){ settings.onShown.call(this); });
        }
        
        function openSizeAnimation(object){
            object.addClass("open").show(settings.openSpeed, function(){ settings.onShown.call(this); });
        }
        
        function closeMenu(object){
            settings.onHide.call(object);
            switch(settings.closeAnimation){
                case "slide":
                    closeSlideAnimation(object);
                    break;
                case "fade":
                    closeFadeAnimation(object);
                    break;
                default:
                    closeSizeAnimation(object);
                    break;
            }
        }
        
        function closeSlideAnimation(object){
            object.slideUp(settings.closeSpeed, closeCallback);
        }
        
        function closeFadeAnimation(object){
            object.fadeOut(settings.closeSpeed, function(){ $(this).removeClass("open"); $(this).prev().removeClass("selected"); });
        }
        
        function closeSizeAnimation(object){
            object.hide(settings.closeSpeed, function(){ $(this).removeClass("open"); $(this).prev().removeClass("selected"); });
        }
        
        function closeAllMenus(){
            var submenus = menu.find(".submenu.open");
            $.each(submenus, function(i, val) {
                $(submenus[i]).css("z-index", "1");
                closeMenu($(submenus[i]));
            });
        }
        
        function closeCallback(object){
            $(this).removeClass("open"); 
            if($(this).prev().attr("class") == "selected") settings.onHidden.call(this);
            $(this).prev().removeClass("selected");
        }
            
        // returns the jQuery object to allow for chainability.
        return this;
    }
    
})(jQuery);

