$(function() {
    var $nav = $('ul#main-nav');
    var active;
    var actives = {};
    var timer;

    $nav.bind('mouseout', function() {
        timer = setTimeout(function() {
            $(' > li', $nav).each(function() {
                if (!isActive($(this).attr('id'))) {
                    $(this).removeClass('on').children('a').removeClass('on');
                    $('#sub-' + $(this).attr('id')).hide();
                }

                return this;
            });
        }, 1000);
    });
    var setActive = function(id, to) {
        id = id.replace(/(sub-)?nav-/, '');

        actives[id] = to;
    };
    var isActive = function(id) {
        id = id.replace(/(sub-)?nav-/, '');

        return actives[id];
    };

    $(' > li', $nav).each(function() {
        var self = $(this);

        self.hover(function() {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }

            if (active) {
                active.removeClass('on').children('a').removeClass('on');
                $('#sub-' + active.attr('id')).hide();
            }

            active = self;
            active.addClass('on').children('a').addClass('on');
            $('#sub-' + active.attr('id')).show();

            setActive($(this).attr('id'), true);
        }, function() {
            setActive($(this).attr('id'), false);
        });

        var child = $('ul', self);

        $('ul', self).each(function() {
            var child = $(this).clone().appendTo('body').css('position', 'absolute').hide();
            var pos   = $(this).offset();
            $(this).remove();

            child.css('left', pos.left).css('top', pos.top);

            $('li', child).hover(function() {
                setActive(child.attr('id'), true);
                $(this).addClass('on').children('a').addClass('on');
            }, function() {
                setActive(child.attr('id'), false);
                $(this).removeClass('on').children('a').removeClass('on');
            });
        });

        return this;
    });
});
