if (typeof Prototype == 'undefined') 
	throw('Veuillez importer la classe "Prototype"');
	
if (typeof Effect == 'undefined') 
	throw('Veuillez importer la classe "Effect"');
	
if (typeof CookieJar == 'undefined') 
	throw('Veuillez importer la classe "CookieJar"');

	
var Accordeon = Class.create();
Accordeon.prototype = {
	
	// Variables
	rubriques : null,
	sousRubriques : null,
	sousRubriqueEncoursIndex : null,
	cookieRubrique : null,
	enMouvementOuvre : false,
	enMouvementFerme : false,
	
	/**
	 * Consctructeur
	 */
	initialize : function(options){
		this.options = Object.extend({
			vitesse : 1,
			conteneur : 'menu',
			rubriques : '.rubrique',
			sousRubriques : '.sous-rubrique',
			selectClasse : 'rubrique_active',
			utiliseCookies : true,
			ouvreParDefaut : -1,
			ouvre : -1,
			vitesse : 0.5
		}, options || {});

		if(this.options['utiliseCookies']){
			this.creeCookie();
			if(this.options['ouvre'] == -1){
				this.recupereRubriqueCookie();
			}
		}			
		
		this.setRubriques();
		this.setRubriquesLinks();
		this.fermeTout();
	},
	
	/**
	 * Récupère toutes les rubriques
	 * @access private
	 */
	setRubriques : function(){
		this.rubriques = $$('#'+this.options['conteneur']+' '+this.options['rubriques']);
		this.sousRubriques = $$('#'+this.options['conteneur']+' '+this.options['sousRubriques']);

		if(this.rubriques.length != this.sousRubriques.length){
			throw("Il doit y avoir autant de rubrique que de sous-rubriques.");
		}
	},
	
	/**
	 * Applique un controle sur le click des rubriques
	 * @access private
	 * @param mixed elt Elément à tester
	 * @return int
	 */
	setRubriquesLinks : function(){
		this.rubriques.each(function(item, index){
			if(this.hasSousRubriques(index)){
				item.observe('click', this.ouvreFerme.bind(this, index), false);
				this.setRubriqueLinkWithSousRubriques(item);
			} else {
				this.setRubriqueLinkWithNoSousRubriques(item, index);
			}
		}.bind(this));
	},
	
	/**
	 * Retire la possibilité de click à l'élément
	 * @access private
	 * @param mixed elt Elément
	 */
	setRubriqueLinkWithSousRubriques : function(item){
		item.onclick = function(){
			return false;
		};
	},
	
	/**
	 * Edite le click pour qu'un traitement soit fait au préalable
	 * @access private
	 * @param mixed elt Elément
	 */
	setRubriqueLinkWithNoSousRubriques : function(item, index){
		item.onclick = function(){
			this.unsetClass(this.sousRubriqueEncoursIndex);
			this.ferme(this.sousRubriqueEncoursIndex);
			this.setClass(index);
			this.sousRubriqueEncoursIndex = index;
			this.modifieCookie();
		}.bind(this);
	},
	
	/**
	 * retour la position de l'élément correspond.
	 * Si elt est un numérique, il est retourné immédiatement.
	 * Sinon la position de la rubrique dont l'id est égale elt est retourné
	 * @access private
	 * @param mixed elt Elément à tester
	 * @return int
	 */
	getRubriqueIndex : function(elt){
		this.rubriques.each(function(item, index){
			if(item.id == elt){
				elt = index;
			}
		});

		return elt;
	},
	
	/**
	 * Retour la position de l'élément par défaut
	 * @access private
	 * @return int
	 */
	getDefaultRubriqueIndex : function(){
		var index = this.getRubriqueIndex(this.options['ouvre']);
		if(this.sousRubriques[index]){
			return index;
		}
		
		index = this.getRubriqueIndex(this.options['ouvreParDefaut']);
		
		if(this.sousRubriques[index]){
			return index;
		}
		
		return -1;
	},
	
	/**
	 * Vérifie si une rubrique a des sous-rubriques
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	hasSousRubriques : function(eltIndex){
		return this.sousRubriques[eltIndex].descendants() != '';
	},
	
	/**
	 * Gère l'ouverture ou la fermeture en fonction de l'élément sélectionné
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	ouvreFerme : function(eltIndex){
		// S'il y a encore une ouverture ou une fermeture en mouvement
		if(this.enMouvementOuvre || this.enMouvementFerme){
			return false;
		}
		
		// Si la rubrique n'a pas de sous-rubrique
		if(!this.hasSousRubriques(eltIndex)){
			return false;
		}
		
		// Si les sous-rubriques n'existe pas
		if(!this.sousRubriques[eltIndex]){
			return false;
		}

		// Si l'élément concerné est celui déjà ouvert
		if(eltIndex == this.sousRubriqueEncoursIndex){
			this.ferme(eltIndex);
			this.sousRubriqueEncoursIndex = null;
		
		// Sinon
		} else {
			this.ferme(this.sousRubriqueEncoursIndex);
			this.ouvre(eltIndex);
			this.sousRubriqueEncoursIndex = eltIndex;
		}

		this.modifieCookie();
	},
	
	/**
	 * ouverture d'un menu avec effet
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	ouvre : function(eltIndex){
		if(!this.sousRubriques[eltIndex]){
			return false;
		}
		
		this.enMouvementOuvre = true;
		
		new Effect.BlindDown(this.sousRubriques[eltIndex], {
			duration : this.options['vitesse'],
			afterFinish : function(){
				this.enMouvementOuvre = false;
			}.bind(this)
		});
		
		this.setClass(eltIndex);
	},
	
	/**
	 * Fermeture d'un menu avec effet
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	ferme : function(eltIndex){
		if(!this.sousRubriques[eltIndex]){
			return false;
		}
		
		this.enMouvementFerme = true;
		
		new Effect.BlindUp(this.sousRubriques[eltIndex], {
			duration : this.options['vitesse'],
			afterFinish : function(){
				this.enMouvementFerme = false;
			}.bind(this)
		});

		this.unsetClass(eltIndex);
	},
	
	/**
	 * Applique la classe de rubrique sélectionnée
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	setClass : function(eltIndex){
		if(this.rubriques[eltIndex]){
			this.rubriques[eltIndex].addClassName(this.options['selectClasse']);
		}
	},
	
	/**
	 * Retire la classe de rubrique sélectionnée
	 * @param int eltIndex Index du panneau concerné
	 * @access private
	 */
	unsetClass : function(eltIndex){
		if(this.rubriques[eltIndex]){
			this.rubriques[eltIndex].removeClassName(this.options['selectClasse']);
		}
	},
	
	/**
	 * Ferme toutes les sous-rubriques sans effet
	 * @access private
	 */
	fermeTout : function(){
		this.sousRubriqueEncoursIndex = this.getDefaultRubriqueIndex();
		this.sousRubriques.each(function(item, index){
			if(this.sousRubriqueEncoursIndex != index){
				item.hide();
			} else {
				this.setClass(index);
			}
		}.bind(this));
	},
	
	/**
	 * Création du cookie
	 * @access private
	 */
	creeCookie : function(){
		this.cookieRubrique = jar = new CookieJar({
			expires:3600,
			path: '/'
		});
	},
	
	/**
	 * Modifie le cookie destinié à garder en mémoire la rubrique d'ouvert
	 * @access private
	 */
	modifieCookie : function(){
		if(!this.cookieRubrique){
			return;
		}
		
		this.cookieRubrique.empty();
		this.cookieRubrique.put('sousRubriqueEncoursIndex', this.sousRubriqueEncoursIndex);
	},
	
	/**
	 * Récupère id à ouvrir
	 * @access private
	 */
	recupereRubriqueCookie : function(){
		if(!this.cookieRubrique){
			return;
		}
		
		this.options['ouvre'] = this.cookieRubrique.get('sousRubriqueEncoursIndex');
		this.cookieRubrique.empty();
	},
	
	/**
	 * Fonction sans utilité
	 * @access private
	 */
	notuse : function(){
	}
}
