
var AppMenu = {
	menuIdPrefixe        : "menu",
	menuContenuIdPrefixe : "menuContenu",
	menusMax             : 0,
	menusEnFermeture     : null,
	menuEnOuverture      : 0,
	menuOuvert           : 0,
	menusEffet           : null,

	initialise : function(nbMenu) {
		AppMenu.menusMax = nbMenu;
		AppMenu.menusEnFermeture = new Array(nbMenu + 1); // l'élément 0 est ignoré
		AppMenu.menusEffet = new Array(nbMenu + 1); // l'élément 0 est ignoré
	},

	initialiseAffichage : function(evenement) {
		for (var i = 1; i <= AppMenu.menusMax; i++) {
			Event.observe(AppMenu.menuIdPrefixe + i, "mouseover", AppMenu.gereEvtOver);
			Event.observe(AppMenu.menuIdPrefixe + i, "mouseout", AppMenu.gereEvtOut);
			Event.observe(AppMenu.menuIdPrefixe + i, "click", AppMenu.gereEvtClick);
		}
	},

	ouvre : function(numeroMenu) {
		
		// initialisation
		var startOn = null;
		var finishOn = null;
		var originalHeight = null;
		
		// si le menu à ouvrir est en cours de fermeture
		// alors il faut inverser l'effet de fermeture
		if (AppMenu.menusEnFermeture[numeroMenu]) {
			var effetTmp = AppMenu.menusEffet[numeroMenu];
			effetTmp.cancel();
			originalHeight = effetTmp.options.scaleMode.originalHeight;
			var instant = new Date().getTime();
			var dureeEffet = instant - effetTmp.startOn;
			var progressionEffet = dureeEffet / effetTmp.totalTime;
			finishOn = instant + progressionEffet * 1000;
			startOn = finishOn - effetTmp.options.duration * 1000;
			AppMenu.menusEnFermeture[numeroMenu] = false;
		}
		
		// ouverture du menu
		var effetTmp = Effect.SlideDown(
			AppMenu.menuContenuIdPrefixe + numeroMenu,
			{
				beforeStart : function(effet) {
					// ceci permet de mettre l'effet en attente
					effet.state = "attente";
				},
				afterSetupFinal : function(effet) {
					// ceci ne sert que s'il faut inverser un effet initial
					effet.options.afterSetupOriginal(effet);
					effet.originalStyle.height = null;
				},
				afterFinish : function(effet) {
					AppMenu.menusEffet[AppMenu.menuEnOuverture] = null;
					AppMenu.menuOuvert = AppMenu.menuEnOuverture;
					AppMenu.menuEnOuverture = 0;
					effet.element.setOpacity(0.9); // pour IE
				},
				duration : 0.5
			});
		// s'il y avait un effet initial à inverser
		if (startOn != null) {
			effetTmp.options.scaleMode.originalHeight = originalHeight;
			effetTmp.options.afterSetupOriginal = effetTmp.options.afterSetup;
			effetTmp.options.afterSetup = effetTmp.options.afterSetupFinal;
			effetTmp.startOn = startOn;
			effetTmp.finishOn = finishOn;
		}

		// lancement de l'effet d'ouverture
		effetTmp.state = "idle"; // ceci permet de relancer l'effet mis en attente
		AppMenu.menusEffet[numeroMenu] = effetTmp;
		AppMenu.menuEnOuverture = numeroMenu;
		AppMenu.menuOuvert = 0;
	},

	ferme : function(numeroMenu) {
		
		// initialisation
		var fermeOk = false;
		var startOn = null;
		var finishOn = null;
		var originalHeight = null;

		// si le menu à fermer est en cours d'ouverture
		// alors il faut inverser l'effet d'ouverture
		if (AppMenu.menuEnOuverture == numeroMenu) {
			fermeOk = true;
			var effetTmp = AppMenu.menusEffet[numeroMenu];
			effetTmp.cancel();
			originalHeight = effetTmp.options.scaleMode.originalHeight;
			var instant = new Date().getTime();
			var dureeEffet = instant - effetTmp.startOn;
			var progressionEffet = dureeEffet / effetTmp.totalTime;
			finishOn = instant + progressionEffet * 1000;
			startOn = finishOn - effetTmp.options.duration * 1000;
			AppMenu.menuEnOuverture = 0;
		}
		// sinon, si le menu à fermer est complétement ouvert,
		// alors il faut le fermer
		else if (AppMenu.menuOuvert == numeroMenu) {
			fermeOk = true;
			AppMenu.menuOuvert = 0;
		}
		
		// s'il y a un traitement de fermeture à faire
		if (fermeOk) {
			
			// création de l'effet de fermeture
			var effetTmp = Effect.SlideUp(
				AppMenu.menuContenuIdPrefixe + numeroMenu,
				{
					beforeStart : function(effet) {
						// ceci permet de mettre l'effet en attente
						effet.state = "attente";
					},
					afterSetupFinal : function(effet) {
						// ceci ne sert que s'il faut inverser un effet initial
						effet.options.afterSetupOriginal(effet);
						effet.originalStyle.height = null;
					},
					afterFinish : function(effet) {
						var numeroMenuTmp = parseInt(
							effet.element.id.substring(
								AppMenu.menuContenuIdPrefixe.length),
							10);
						AppMenu.menusEnFermeture[numeroMenuTmp] = false;
						AppMenu.menusEffet[numeroMenuTmp] = null;
					}
				});
			
			// s'il y avait un effet initial à inverser
			if (startOn != null) {
				effetTmp.options.scaleMode.originalHeight = originalHeight;
				effetTmp.options.afterSetupOriginal = effetTmp.options.afterSetup;
				effetTmp.options.afterSetup = effetTmp.options.afterSetupFinal;
				effetTmp.startOn = startOn;
				effetTmp.finishOn = finishOn;
			}
			
			// lancement de l'effet de fermeture
			effetTmp.state = "idle";
			AppMenu.menusEffet[numeroMenu] = effetTmp;
			AppMenu.menusEnFermeture[numeroMenu] = true;
		}
	},

	gereEvtOver : function(evenement) {
		// récupération du numéro du menu
		var numeroMenu = parseInt(this.id.substring(AppMenu.menuIdPrefixe.length), 10);

		// si le menu n'est pas celui en ouverture (ou déjà ouvert)
		if (AppMenu.menuEnOuverture != numeroMenu && AppMenu.menuOuvert != numeroMenu) {

			// si un menu est en cours d'ouverture ou s'il y en a un ouvert
			// alors il faut le fermer
			if (AppMenu.menuEnOuverture != 0) {
				AppMenu.ferme(AppMenu.menuEnOuverture);
			}
			else if (AppMenu.menuOuvert != 0) {
				AppMenu.ferme(AppMenu.menuOuvert);
			}

			// ouverture du menu à afficher
			AppMenu.ouvre(numeroMenu);
		}
	},

	gereEvtOut : function(evenement) {
		var numeroMenu = 0;
		var eltSrc = evenement.target;
		if (eltSrc != null) {
			eltSrc = $(eltSrc);
		}
		var eltDst = null;
		if (eltSrc != null && (eltSrc.className == "menu" || eltSrc.up(".menu") != null)) {
			eltDst = evenement.relatedTarget;
			if (eltDst != null) {
				eltDst = $(eltDst);
			}
		}
		if (eltDst != null && eltDst.className != "menu" && eltDst.up(".menu") == null) {
			if (AppMenu.menuEnOuverture != 0) {
				numeroMenu = AppMenu.menuEnOuverture;
			}
			else if (AppMenu.menuOuvert != 0) {
				numeroMenu = AppMenu.menuOuvert;
			}
		}
		if (numeroMenu > 0) {
			AppMenu.ferme(numeroMenu);
		}
	},

	gereEvtClick : function(evenement) {
		// récupération du numéro du menu
		var numeroMenu = parseInt(this.id.substring(AppMenu.menuIdPrefixe.length), 10);

		// si le menu n'est pas celui en ouverture (ou celui déjà ouvert)
		// alors il faudra l'ouvrir
		var ouvreOk = 
			AppMenu.menuEnOuverture != numeroMenu 
			&& AppMenu.menuOuvert != numeroMenu;
		
		// si un menu est en cours d'ouverture ou s'il y en a un ouvert
		// alors il faut le fermer
		if (AppMenu.menuEnOuverture != 0) {
			AppMenu.ferme(AppMenu.menuEnOuverture);
		}
		else if (AppMenu.menuOuvert != 0) {
			AppMenu.ferme(AppMenu.menuOuvert);
		}
		
		// ouverture du menu à afficher (si besoin)
		if (ouvreOk) {
			AppMenu.ouvre(numeroMenu);
		}
	}

};

