/*	******************************

	PLUGIN - Specialized Menu
	Author: Jack Lukic - KNI 
	Notes: Dynamic menu system for specialized.com
		
	// Settings	
		
	setting: default value - explanation
	 
	collapse: true - whether to use accordion style menus
	hideTimer: 1500 - time between mousing off menu and the menu closing
	showSpeed: 600 - time in milliseconds for showing a menu
	showEasing: easeOutExpo - type of easing to use for showing an item
	hideSpeed: 300 - time in milliseconds for showing a menu
	hideEasing: easeOutQuad - type of easing to use for showing an item
	
	levelSelector: ul - selector for a grouping of items (any jQuery/xpath selector)
	elementSelector: li - selector for a single item (any jQuery/xpath selector)
	
	menuSelector - .list - class name given to entire menu container
	blockerSelector - .disable - adding this class name to any link inside menu disables the link from being followed
	
	// initialize using jQuery object
	
	var options = {
		// custom options	
		collapse: false,
		hideTimer: 1500,
		levelSelector: '.group',
		menuSelector: '.page'
	}
	$('#thingy').menu(options);
		
********************************/


(function($) {
	
	jQuery.fn.extend({
		menu: function(params) {
			
			// iterate over each el passed in
			$(this).each(function() {
				
				// define default settings
				var settings = {					
					collapse: true,
					hideTimer: 500,
					showSpeed: 500,
					showEasing: 'easeOutExpo',
					hideSpeed: 300,
					hideEasing: 'easeOutQuad',					
					levelSelector: 'ul',
					elementSelector: 'li',					
					menuSelector: '.list',
					blockerSelector: '.disable',
					hideAfter: '0'
				};				
				jQuery.extend(settings, params);
				
				// cache jQuery objects
				var $menu = $(this);
				var $pulldownMenu = $menu.find(settings.menuSelector);
				// if menu is set to show & hide
				if(settings.hideAfter != 0 && parseInt(settings.hideAfter) > 0) {
					// show menu
					$menu
						.addClass('active')
						.find(settings.menuSelector)
							.slideDown(settings.showSpeed, settings.showEasing)
							.children(settings.levelSelector)
								.animate({opacity: 1}, settings.showSpeed);
					// set hide event
					var hideAfterTimer = setTimeout(function() {
						$menu
							.removeClass('active')
							.find(settings.menuSelector)
								.slideUp(settings.hideSpeed, settings.hideEasing);
					}, settings.hideAfter);
				}
								
				// attach launcher button handler for showing menu
				$menu
					.hover(function() {
						// Unset timer on interaction  if hideAfter settings was set
						if(typeof(hideAfterTimer) != 'undefined') {
							clearTimeout(hideAfterTimer);
						}
						// reset normal timer if set
						var timer = $menu.data('timer');
						if(typeof(timer) != 'undefined') {
							clearTimeout(timer);
							$menu.removeData('timer');
						}
						// generate content to instant on
						$menu
							.addClass('active')
							.find(settings.menuSelector)
								.slideDown(settings.showSpeed, settings.showEasing)
							.children(settings.levelSelector)
								.animate({opacity: 1}, settings.showSpeed);
					},function() {
						// create timer for delay closing of menu
						var timer = setTimeout(function() {
							$menu
								.removeClass('active')
								.removeData('timer')
								.find(settings.menuSelector)
									.slideUp(settings.hideSpeed, settings.hideEasing);											
						}, settings.hideTimer);
						// store timer in menu private data
						$menu.data('timer', timer);
					}
				);
				 
				$pulldownMenu.find(settings.levelSelector).each(function() {
					
					$menuLink = $(this).children(settings.elementSelector).children('a');
					
					// attach event handlers
					$menuLink
						.hover(function() {
							$(this).parent().addClass('hover');										 
						},function() {
							$(this).parent().removeClass('hover');
						})
						.click(function() {							
							var $subMenu = $(this).siblings(settings.levelSelector);
							// dont follow link if blocker selector exists or menu has another level 
							if( $(this).filter(settings.blockerSelector).exists() || $subMenu.exists() ) {
								
								// collapse other menus if settings dictate
								if(settings.collapse) {
									var $otherMenu = $(this).parent().siblings().children(settings.levelSelector);
									// if other menus are visible close and make inactive
									if( $otherMenu.exists() && $otherMenu.visible() && !$otherMenu.animated() ) {
										$otherMenu
											.siblings('a')
												.removeClass('active');
										$otherMenu
											.animate({opacity: 0}, {queue: false, speed: settings.hideSpeed} )
											.slideUp({queue: false, speed: settings.showSpeed} , settings.showEasing);
									}
								}
								
								// toggle show hide of menu
								if(!$subMenu.animated() ) {
									if( !$subMenu.visible() ) {
										$(this).addClass('active');
										$subMenu								
											.animate({opacity: 1}, {queue: false, speed: settings.showSpeed} )
											.slideDown({queue: false, speed: settings.showSpeed} , settings.showEasing);
									}
									else {
										$(this).removeClass('active');
										$subMenu
											.animate({opacity: 0}, {queue: false, speed: settings.hideSpeed} )
											.slideUp({queue: false, speed: settings.hideSpeed} , settings.hideEasing);
									}
								}
								return false;			
							}
						}
					);
					
				});
				
			});
			// return this for chaining
			return this;
			
			
		}
	});


	/*	******************************
			PLUGIN - Supplemental Conditionals
			Author: Jack Lukic - KNI (all plugins)
			Notes: Selector shortcuts used to simplify code 
		******************************	*/
	jQuery.fn.extend({
		// test if el is animated
    openTo: function(menuItemId) {    
    
			var settings = {					
			  collapse: true,
			  hideTimer: 500,
			  showSpeed: 500,
			  showEasing: 'easeOutExpo',
			  hideSpeed: 300,
			  hideEasing: 'easeOutQuad',					
			  levelSelector: 'ul',
			  elementSelector: 'li',					
			  menuSelector: '.list',
			  blockerSelector: '.disable',
			  hideAfter: '0'
			};    
 
      var parent = $('#nav_href_'+menuItemId).parent();
      while(parent.length > 0) {      
        /* If we hit the top of the menu then break out
        of the loop. */
        if(parent.attr("class") == "list") {
          break;
        }
        
        /* Change the CSS class for the parent
        elements children (a's) to active. */
        parent.children().removeClass();
        parent.children().addClass('active');
                                   
        /* Hide the subMenu. */
        parent
          .animate({opacity: 1}, {queue: false, speed: settings.showSpeed} )
	  		  .slideDown({queue: false, speed: settings.showSpeed} , settings.showEasing);
        
        /* Move up the menu to the next parent. */
        parent = parent.parent();         
      }     
    },
		animated: function() {
			if(this.filter(':animated').size() > 0) {
				return true;
			}
			else {
				return false;	
			}
		},
		// test if el is visible
		visible: function() {
			if(this.filter(':visible').size() > 0) {
				return true;
			}
			else {
				return false;	
			}
		},
		// test if el exists
		exists: function() {
			if(this.size() > 0) {
				return true;
			}
			else {
				return false;	
			}
		}
	});

})(jQuery);
