(function($){
    
    // settings
    var waitBeforeClose = 400; // wait before close; milliseconds
    var onlyOneMenuOpened = true; // only one menu can be visible at same time
    var openEffect = false; // slide|fade|show or false
    var closeEffect = false; // slide|fade|hide or false
    
    var menusPool = new Array();
	
	$.fn.initRivMenu = function()
	{
	    var container = $(this);
	    
	    container.find('.placeholder').each(function(){
	        var activator = $(this).find('.activator');
	        var menu = $(this).find('.menu');
	        
	        if (menu.length > 0) {
    	        var menu = new Menu(activator, menu, container);
    	        menusPool.push(menu);
	        }
	        
	        $(this).find('.link').bind('mouseover', function(){
	            closeAllMenus();
	        });
	    });
	    
	    $(document).click(closeAllMenus);
	}
	
	var closeAllMenus = function()
    {
        for (i in menusPool) {
            if (menusPool[i].opened) {
                menusPool[i].closeMenu();
            }
        }
    }
	
	with (Menu = function(activator, menu, container){
	    this.activator = activator;
	    this.menu = menu;
	    this.container = container;
	    
	    this.init();
	}) {
	    prototype.activator = null;
	    prototype.menu = null;
	    prototype.container = null;
	    
	    prototype.allowClose = false;
	    prototype.opened = false;
	    prototype.fixOpened = false;
	    
	    prototype.init = function()
	    {   
	        var t = this;
	        this.activator
    	        .bind('mouseenter.rivmenu', function(){
    	            t.allowClose = false;
    	            t.openMenu();
    	        })
    	        .bind('mouseleave.rivmenu', function(){
    	            t.allowClose = true;
    	            t.setCloseTimer();
    	        })
    	        .bind('click', function(e){
    	            var href = $(e.target).attr('href');
    	            if (!href || href == '#') {
    	                e.preventDefault();
                        t.fixOpened = true;
    	            }  	            
    	        })
	    }
	    
	    prototype.openMenu = function()
	    {
	        if (onlyOneMenuOpened) {
	           closeAllMenus();
	        }
	        
	        var activatorPosition = this.activator.position();	        
	        var menuTop = activatorPosition.top + this.activator.outerHeight();
            var menuLeft = activatorPosition.left;
                        
            this.menu
                .css('position', 'absolute')
                .css('top', menuTop)
                .css('left', menuLeft)
                .css('z-index', 1000)
            
            if (!this.menu.data('initialized')) {
                var t = this;
                this.menu
                    .bind('mouseenter.rivmenu', function(){
                        t.allowClose = false;
                    })
                    .bind('mouseleave.rivmenu', function(){
                        t.allowClose = true;
                        t.setCloseTimer();
                    })
                    .data('initialized', true);
            }
                
            if (openEffect != false) {
                switch (openEffect) {
                    case 'slide':
                        this.menu.slideDown('fast');
                        break;
                    case 'fade':
                        this.menu.fadeIn('fast');
                        break;
                    default:
                        this.menu.show('fast');
                        break;
                }
            } else {
                this.menu.toggle(true);
            }
                
            this.activator.addClass('opened');
            this.opened = true;
	    }
	    
	    prototype.closeMenu = function()
        {
	        if (this.allowClose) {
	           this.menu.css('z-index', 900);
	           
	           if (closeEffect != false) {
	                switch (closeEffect) {
	                    case 'slide':
	                        this.menu.slideUp('fast');
	                        break;
	                    case 'fade':
	                        this.menu.fadeOut('fast');
	                        break;
	                    default:
	                        this.menu.hide('fast');
	                        break;
	                }
	            } else {
	                this.menu.toggle(false);
	            }
	           
               this.activator.removeClass('opened');
               this.opened = false;
               this.fixOpened = false;
            }	        
        }
	    
	    prototype.setCloseTimer = function()
	    {
	        if (!this.fixOpened) {
    	        var t = this;
    	        var to = setTimeout(function(){
    	            t.closeMenu();
    	        }, waitBeforeClose);
	        }
	    }
	    
	}
	
})(jQuery);