/**
 * @compagny : Archriss, web agency & ingénérie
 * @website : www.archriss.fr
 * @author : Jean-Philippe RIVET
 * @contact : jprivet@archriss.com
 * @copyriht : Tous droits réservés
 * @purpose : Ajout d'effets aux menus
 */

(function($){
	
	// Définition des méthodes dans l'espace de nommage unique
	var methods = {
		// exemple pour "options" : {param3: 'param3', param4: 'param4'}
		ini : function(options){
			
			// A la place de "$(this)" écrire ici "this", ce dernier étant déjà un objet jQuery.
			
			// Maintient de la chainabilité avec "return"
			return this.each(function(){
				
				// Initialisation de this
				var $this = $(this);
				
				// Récupération des données liées à l'objet en cours
				var data = $this.data('options');
				 
				// Si le plugin n'a pas été encore initialisé
				if (!data){
					
					// Paramètres par defaut
					var o = {
						target				: $this,
						effectOn			: 'slide',
						effectOff			: 'fade',
						effectOnOptions		: {},
						effectOffOptions	: {},
						effectOnDuration	: 'fast',
						effectOffDuration	: 'fast',
						effectOnCallback	: false,
						effectOffCallback	: false,
						effectType			: null,
						aPrevious			: false
					};
					
			        // Si les options existent...
					if(options){ 
				        $.extend(o, options);
				    }
					
					// Application des paramètres
					$(this).data('options', o);
					$(this).addClass('menueffect_dataoptions');
				}
   
				// Cache tous les sous-menus
				$this.find('ul:not(:first)').hide();
				
				// Application du survol de souris
				$this.find('li').menueffect('liEvent');
				
				// Application de la navigation à la tabulation
				$this.find('li a').menueffect('aEvent');		
			});
			
		},
		liEvent : function(){
			
			return this.each(function(){
				
				// Initialisation de this
				var $this = $(this);
				
				// Application des événements
				$this.mouseenter(function(){
					$(this).menueffect('liMouseEnter');
				}).mouseleave(function(){
					$(this).menueffect('liMouseLeave');
				});
				
			});
			
		},
		liMouseEnter : function(){
			
			this.parents('ul:first')
				.addClass('mouseOn');
			
			this.find('ul:first')
				.css('visibility', 'visible')
				.menueffect('effect', 'show');
			
		},
		liMouseLeave : function(){
			
			this.parents('ul:first')
				.removeClass('mouseOn');
			
			this.find('ul:first:not(:hidden)')
				.css('visibility', 'visible')
				.menueffect('effect', 'hide');
			
		},
		aEvent : function(){
			
			return this.each(function(){
				
				// Initialisation de this
				var $this = $(this);
								
				// Application des événements
				$this.focusin(function(){
					
					aCurrent = $(this);
					aPrevious = $(this).menueffect('getOptions').aPrevious;
					//alert(aPrevious);
					
					if(aPrevious){
						aPrevious
							.clearQueue()
							.parents('ul:first')
					}
					
					aCurrent
						.parents('li')
						.addClass('focusPath');
					
					aCurrent
						.parents('li:first')
						.menueffect('liMouseEnter');
					
					$(this).menueffect('getOptions').target.find('li').each(function(){
						if($(this).is('.focusPath')){
							$(this).addClass('mouseOn').removeClass('focusPath');	
						} else {
							$(this).removeClass('mouseOn').menueffect('liMouseLeave');
						}
					});
					
				}).focusout(function(){
					
					// Initialisation de tous les ul
					$(this).menueffect('getOptions').target.find('ul');
					// Récupération de l'ancienne balise a active
					$(this).menueffect('getOptions').aPrevious = $(this);
					// Délai de fermeture de tous les sous-menus si l'on sort totalement du menu
					$(this).delay(100).queue(function(){
						$(this).menueffect('getOptions').target.find('li').menueffect('liMouseLeave');
					});

				});
				
			});
			
		},
		effect : function(type){
			
			// Initialisation du type d'effet attendu
			$(this).menueffect('setOptions', {effectType : type});
			
			
			return this.each(function(){
				// Récupération des paramètres
				var o = $(this).menueffect('getOptions');
				
				var type = o.effectType;
				
				// ON ou OFF
				if(type == 'show'){
					
					var name = o.effectOn;
					var options = o.effectOnOptions;
					var duration = o.effectOnDuration;
					var callback = o.effectOnCallback;
					
				} else if(type == 'hide') {
					
					var name = o.effectOff;
					var options = o.effectOffOptions;
					var duration = o.effectOnDuration;
					var callback = o.effectOffCallback;
					
				}
												
				$.extend(options, { mode : type });
				
				// Application de l'effet
				$(this).e(name, options, duration, callback);		
			});
			
		},
		getOptions : function(){
			
			// Si l'élément en cours à déjà la classe "menueffect_dataoptions"...
			if(this.data('options')){
				// Retour du data
				return this.data('options');
			} else {
				// Recherche du target et retour du data
				return this.parents('.menueffect_dataoptions:first').data('options');
			}
			
		},
		setOptions : function(options){
			
			// Si l'élément en cours à déjà la classe "menueffect_dataoptions"...
			if(this.data('options')){
				// Retour de l'objet en cours
				var domElem = this;
			} else {
				// Recherche et retour du target
				var domElem = this.parents('.menueffect_dataoptions:first');
			}
			
			var o = domElem.data('options');
			
	        // Si les options existent...
			if(options){ 
		        $.extend(o, options);
		    }

			return domElem.data('options', o);
		}
	};

	// Création du plugin
	$.fn.menueffect = function(method) {
		if (methods[method]){
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || ! method) {
			return methods.ini.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.menueffect');
		}		
	};
	
})(jQuery);

