(function($) {

    $.fn.ddMenu = function()
    {
        return this.each(function() {
            var $this = this;
            
            this.prevNode = null;
            this.show = function(node)
            {
                if (!node.isOpened && !node.isAnimating)
                {
                    node.isOpened = true;
                    node.isAnimating = true;
                    $(node).addClass('hover').children('ul').animate({
                        opacity: 'show',
                        height: 'show'
                    }, 330, function() { 
                        node.isAnimating = false;
                    });                
                }
            };
            this.hide = function(node)
            {
                $(node).removeClass('hover').removeClass('hover').children('ul').stop(true, true).slideUp(100);
                node.isOpened = false;
            };
            
            $('li > ul', this).hide();
            $(this).children('li').hover(
                function()
                {
                    var node = $(this);
                    var scope = this;
                
                    if (this.isWaiting)
                    {
                        window.clearTimeout(this.timer);
                        this.isWaiting = false;
                        return;
                    }
                    
                    if ($this.prevNode && $this.prevNode.isWaiting)
                    {
                        if ($this.prevNode.isAnimating)
                        {
                            $($this.prevNode).stop(true, true);
                            $this.prevNode.isAnimating = false;
                        }
                        $this.hide($this.prevNode);
                        window.clearTimeout($this.prevNode.timer);
                        $this.prevNode.isWaiting = false;
                    }
                    
                    $this.show(this);
                },
                function()
                {
                    var node = $(this);
                    var scope = this;
                    $this.prevNode = this;
                    
                    if (this.isAnimating)
                    {
                        node.stop(true, true);
                        this.isAnimating = false;
                        $this.hide(scope);
                        
                        return;
                    }
                    
                    if (!this.animating && !this.isWaiting)
                    {
                        this.isWaiting = true;
                        this.timer = window.setTimeout(function() {
                            $this.hide(scope);
                            scope.isWaiting = false;
                        }, 660);
                    }
                }
            );
            
        });
    };

})(jQuery);
