/**
 * jqMenu - jQuery plugin
 * @version: 1.0 (2011/07/07)
 * @requires jQuery v1.5.2 or later 
 * @author Richard Vacchino Marceau / Alexandre Beaulieu

 * @version: 1.1 (2011/08/22)
 * @author Alexandre Beaulieu
 * @description:
    - Add a fixed menu that open from borders of page (top and bottom)
 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
**/


(function($) {
	
	// Globals
	var opts = new Array();	
    var state = 0;
    var lastClick = "";
	
	$.fn.jqMenu = $.fn.jqMenu = function(options){
		
		// Intiallisation
		init = function(el){
		
			//Options
			opts[el.id] = $.extend({}, $.fn.jqMenu.defaults, options); //opts[el.id].width);
			
			
			switch(opts[el.id].type)
			{
				case 'mega':
					if(opts[el.id].effect == 'slide') {
						$.megaSlide(el);
					}	
				break;
				
				case 'list':
				  $.list(el);
				break;

                case 'open':
                    switch(opts[el.id].position)
        			{
        				case 'bottom':
        				    $.bottom(el);
        				break;
        
                        case 'top':
        				    $.top(el);
        				break;
        				  
        				default:
        				    $.bottom(el);
        			}
                break;
				  
				default:
				  $.slide(el);
			}
			
		};
		
		
		// Mega dropdown menu
		$.megaSlide = function(el) {
		
			var h  =  opts[el.id].height;
			var w  =  opts[el.id].width;
			var l  =  opts[el.id].speed;
			var iw =  opts[el.id].initialWidth; 	// initialWidth
			var bc =  opts[el.id].buttonClass; 		// Class of the button
			var ac =  opts[el.id].activeClass; 		// Class for active button
			var dc =  opts[el.id].dropDownClass; 	// Class of the dropDown to animate
			
			var delay =  opts[el.id].delay;
			var sub = '.'+opts[el.id].dropDownClass; 
			
			//close the sub element
			$('#'+el.id+' .'+opts[el.id].dropDownClass).height(0);
			$('#'+el.id+' .'+opts[el.id].dropDownClass).width(iw);
			
			
			
			$('#'+el.id+' li.'+bc).hover(function() {
			
				var position = $(this).offset()
				
				$(this).addClass(ac);
				$(this).siblings().removeClass(ac);
				$(this).stop();
				$(this).siblings().children(sub).stop();
				$(this).siblings().children(sub).stop().height(0);
				$(this).siblings().children(sub).stop().width(iw);
				
				if($(this).children(sub).length > 0) {
				
					$(this).children(sub).stop()
					
					
					if (position.left + w >= $(document).width()) {
					
						$(this).children(sub).css({
							left : 'auto',
							right: 0
						});
						
					}
					else {
					
							$(this).children(sub).css({
								left : 0,
								right: 'auto'
							});
					}
					
					$(this).children(sub).stop().delay(delay).animate({'height':h},l,function(){
							$(this).animate({'width':w},l)
					});
				}
				
			},function(){
				$(this).siblings().stop().children(sub).height(0);
				$(this).siblings().removeClass(ac);
				
				if($(this).children(sub).length > 0){
				
					$(this).children(sub).stop().delay(delay).animate({'width':iw},l,function(){
					
							$(this).animate({'height':0},l,function(){
							
								$(this).parent().removeClass(ac);
								
							});
							
					});
				}
				else {
				
					$(this).removeClass(ac);
					
				}
					
			});
		}
		
		
		// UL list drop down menu
		$.list = function(el) {
		
			var l  =  opts[el.id].speed;
			var ac =  opts[el.id].activeClass; 		// Class for active button
			var d  =  opts[el.id].delay;
			
			// Hide submenu
			$('#'+el.id).find('li ul').hide().css("opacity", 0);

			var tUl = $('#'+el.id).find('li')
			
			tUl.each(function() {
				
				var se = $(this)
				var timer;
				
				$(this).hover(function() {
					se.addClass(ac);
					se.children('ul').stop().show().animate({"opacity":1}, l);
					clearTimeout(timer);
					
				},function() {
				
					timer = setTimeout(function(){
    					se.removeClass(ac);
						se.children('ul').stop().animate({"opacity":0}, l, function() {
                            $(this).hide();
                        });
					},d)
					
				})
				
			})
			
			
		}
		
        // Default movement. Open the list in a linear way
		$.bottom = function(dl) {
			var l  =  opts[dl.id].speed;             // speed of the animation
			var bc =  opts[dl.id].buttonClass;       // Class for remote button
			var dc =  opts[dl.id].dropDownClass;     // Class of the dropDown to animate
			var ho =  opts[dl.id].heightOpen;     // Class of the dropDown to animate
			var ac =  opts[dl.id].activeClass;     // Class of the dropDown to animate
			var cc =  opts[dl.id].closeClass;     // Class of the dropDown to animate
			
			var sub = '.'+opts[dl.id].dropDownClass; 
			
            $('.'+cc+":not(:animated)").click(function() {
                if(state==1) {
                    if( $(this).siblings('ul').children().hasClass(ac)==true ) {
                        
                        state = 2;
                            $('.'+cc).fadeOut(l);
                        aid = $(this).siblings('ul').children('li.'+ac).children().attr('id');
                        $(this).siblings('ul').children('li.'+ac).removeClass(ac);
                        $('.'+aid).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"bottom": "0px"}, l, function(){
                            state = 0;
                            $('.'+aid).css({"display":"none"});
                        });
                    }
                }
                
			});
            			
			$('.'+dl.className+' .'+bc+":not(:animated)").click(function() {
                
                var currentId = $(this).parent().children("a").attr('id');    
                if(state == 0) {
                    $('.'+cc).fadeIn(l);
                    if( $(this).parent().hasClass(ac)==false ) { 
                        $('.'+currentId).fadeTo(10,1);
                        state = 2;
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": ho + "px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"bottom": ho + "px"}, l, function(){
                            state=1;                                            
                        });
                    }
                } else if(state==1) {
                    if( $(this).parent().hasClass(ac)==true ) {
                        state = 2;
                        $('.'+cc).fadeOut(l);
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"bottom": "0px"}, l, function(){
                            state = 0
                            $('.'+currentId).css({"display":"none"});
                        });
                    } else if ($(this).parent().hasClass(ac)==false) {
                        state = 2;
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"bottom": "0px"}, l, function(){
                            $('.'+currentId).siblings().css({"display":"none"});
                            $('.'+currentId).fadeTo(10,1);
                            $(this).parent().children('.'+dc+":not(:animated)").animate({"height": ho + "px"}, l);
                            $(this).animate({"bottom": ho + "px"}, l, function(){
                                state=1;   
                                                                         
                            });

                        });

                    }
                }
                
			});
		}

        // Open the list, then fade in. Fade out, then close the list
        $.top = function(dl) {
			var l  =  opts[dl.id].speed;             // speed of the animation
			var bc =  opts[dl.id].buttonClass;       // Class for remote button
			var dc =  opts[dl.id].dropDownClass;     // Class of the dropDown to animate
			var ho =  opts[dl.id].heightOpen;     // Class of the dropDown to animate
			var ac =  opts[dl.id].activeClass;     // Class of the dropDown to animate
			var cc =  opts[dl.id].closeClass;     // Class of the dropDown to animate
			
			var sub = '.'+opts[dl.id].dropDownClass; 
			
            $('.'+cc+":not(:animated)").click(function() {
                if(state==1) {
                    if( $(this).siblings('ul').children().hasClass(ac)==true ) {
                        
                        state = 2;
                            $('.'+cc).fadeOut(l);
                        aid = $(this).siblings('ul').children('li.'+ac).children().attr('id');
                        $(this).siblings('ul').children('li.'+ac).removeClass(ac);
                        $('.'+aid).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"top": "0px"}, l, function(){
                            state = 0;
                            $('.'+aid).css({"display":"none"});
                        });
                    }
                }
                
			});
            			
			$('.'+dl.className+' .'+bc+":not(:animated)").click(function() {
                
                var currentId = $(this).parent().children("a").attr('id');    
                if(state == 0) {
                    $('.'+cc).fadeIn(l);
                    if( $(this).parent().hasClass(ac)==false ) { 
                        $('.'+currentId).fadeTo(10,1);
                        state = 2;
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": ho + "px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"top": ho + "px"}, l, function(){
                            state=1;                                            
                        });
                    }
                } else if(state==1) {
                    if( $(this).parent().hasClass(ac)==true ) {
                        state = 2;
                        $('.'+cc).fadeOut(l);
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"top": "0px"}, l, function(){
                            state = 0
                            $('.'+currentId).css({"display":"none"});
                        });
                    } else if ($(this).parent().hasClass(ac)==false) {
                        state = 2;
                        $(this).parent().toggleClass(ac);
                        $(this).parent().siblings().removeClass(ac);
                        
                        $('.'+currentId).parent('.'+dc+":not(:animated)").animate({"height": "0px"}, l);
                        $(this).parents('.'+dl.className+":not(:animated)").animate({"top": "0px"}, l, function(){
                            $('.'+currentId).siblings().css({"display":"none"});
                            $('.'+currentId).fadeTo(10,1);
                            $(this).parent().children('.'+dc+":not(:animated)").animate({"height": ho + "px"}, l);
                            $(this).animate({"top": ho + "px"}, l, function(){
                                state=1;   
                                                                         
                            });

                        });

                    }
                }
                
			});
		}

		this.each (
			function(){ init(this); }
		);	
	};
	
	
	
	// default values
	$.fn.jqMenu.defaults = {
		type:           'mega',     // (mega, list, open) Type of menu 
        position:       'bottom',	// bottom, top
		speed: 			300,		// speed of the animation
		initialWidth:   10, 		// Width before enlargement
		width: 			520, 		// width of submenu
		height: 		600, 		// height of submenu
		delay: 			200, 		// delay before desapearence
		effect: 		'slide', 	// slide, fade, etc.
		dropDownClass: 	'sub', 		//Class for the dropdown elements
		activeClass:    'open',     // Class active for the button
		heightOpen: 	250,        // height of the menu when it opens with type: open
        closeClass:     'close',    // Class of the close button
		buttonClass: 	'bt' 		// Class for the button
		
	};
	
})(jQuery);
