(function($){

    var ns = $.navigation = $.navigation || {};
    var currentMenu = null;
    var currentItem = null;
    var speed = 300;
    var itemActivateTimeout;
    var itemDeactivateTimeout;
    var activatedClass = 'open';

    var getListItems = function(root) {
        return $(root).find('> li');
    };

    var getMenu = function(item) {
        return $(item).find('> .sub-navigation')[0];
    };

    var activateItem = function(item) {
        var menu = getMenu(item);
        if (!menu) return;

        if (!$(item).hasClass(activatedClass)) $(item).addClass(activatedClass);
        $(menu).show();

        currentMenu = menu;
        currentItem = item;
    };

    var deactivateItem = function(item) {
        var menu = getMenu(item);
        if (!menu) return;

        $(item).removeClass(activatedClass);
        $(menu).hide();

        if (currentMenu == menu) currentMenu = null;
        if (currentItem == item) currentItem = null;
    };

    var scheduleActivateItem = function(item) {
        if (itemActivateTimeout) window.clearTimeout(itemActivateTimeout);
        itemActivateTimeout = window.setTimeout(function(){
            if (item) activateItem(item);
        }, speed);
    };

    var scheduleDeactivateItem = function(item) {
        itemDeactivateTimeout = window.setTimeout(function(){
            if (item) deactivateItem(item);
        }, speed);
    };

    var itemMouseenterHandler = function(item) {
        if (itemDeactivateTimeout && currentItem == item) {
            window.clearTimeout(itemDeactivateTimeout);
        }
        scheduleActivateItem(item);
    };

    var itemMouseleaveHandler = function(item) {
        if (itemActivateTimeout) {
            window.clearTimeout(itemActivateTimeout);
        }
        scheduleDeactivateItem(item);
    };

    $.fn.extend({
        navigation : function() {
            var items = getListItems(this[0]);
            $(items).each(function(){
                $(getMenu(this)).hide();
                $(this).bind('mouseenter', function(){
                    return itemMouseenterHandler(this);
                }).bind('mouseleave', function(){
                    return itemMouseleaveHandler(this);
                });
            });
            return this;
        }
    });

})(jQuery);
