/**
 * Handler de menu utilisé par les TimingWindow et EscapeWindow
 *
 * Il gère l'affichage et les actions utilisateur, mais pas le positionnement
 * des éléments de menu, ni leur arrivée à l'écran.
 *  - les flèches haut et bas déplacent la sélection
 *  - espace et entrée valident la sélection
 *  - escape sélectionne et valide une option définie par l'écran utilisateur
 *
 * Il est destiné à être encapsulé dans un écran qui gèrera ces éléments.
 */

 /**
  * Création du gestionnaire du menu, hors la partie graphique
  *  - container : l'objet DIV qui contiendra les éléments DHTML créés
  *  - fader : le fader sur le container (état In, i.e. affichage normal, en entrée)
  *  - imageFx : l'outil pour effectuer les opérations graphiques (texte détouré)
  *  - count : le nombre d'entrées dans le menu
  * 
  */
 function MenuDriver(container, fader, imageFx, count)
 {
	this.container = container;
	this.fader = fader;
	this.imageFx = imageFx;

	this.optionCount = count;
	
	this.menuControls = new Array(count);
	this.optionAvailable = new Array(count);

 }
 
 
  MenuDriver.prototype = {
  
  
    /**
	 * Initialization / remise à zéro des paramètres 
	 *  - premier élément de menu sélectionné
	 */
	initialize : function() {
		this.selectedOption = 0;
		this.userAcknowledged = false;
		this.escapeOption = 2;
		
		for (var i=0; i<this.optionCount; ++i)
		{
			this.menuControls[i] = this.imageFx.createOutlinedTextPanel(this.container, "timing_user_controls", "loader_text", "white");
			this.optionAvailable[i] = true;
		}
	},
	
	/**
	 * Renvoie le n-ieme contrôle de menu (pour action sur son style par exemple)
	 */
	getControl : function(index) {
		return this.menuControls[index];
	},
	
	/**
	 * Renvoie l'index de l'option sélectionnée
	 */
	getSelectedOption : function() {
		return this.selectedOption;
	},
	
	/**
	 * Définit si une option est accessible ou non
	 */
	setOptionAvailable : function(index, avail) {
		this.optionAvailable[index] = avail;
		this.menuControls[index].style.display = (avail ? "block" : "none");
	},
	
	/**
	 * Définit le texte d'une option de menu
	 */
	setOptionText : function(index, text) {
		this.imageFx.outlinedWrite(this.menuControls[index], text);
	},
	
	/**
	 * Définit l'option sélectionnée (ou par défaut, si appelé avant la première utilisation
	 */
	setSelectedOption : function(index) {
		this.selectedOption = index;
	},
	
	/**
	 * Définit l'option correspondant à la touche ESCAPE
	 */
	setEscapeOption : function(index) {
		this.escapeOption = index;
	},
	
	/**
	 *	Ferme et détruit les éléments DHTML de la fenêtre
	 */
	terminate : function() {
		for (var i=0; i<this.optionCount; ++i)
		{
			this.container.removeChild(this.menuControls[i]);
			this.menuControls[i] = 0;
		}
	},

	/**
	 *  Affiche le texte des menus et en anime la couleur
	 */
	repaint : function(timer) {
		var glitter = Math.cos(0.05*timer);
		var red = Math.round(255+(glitter<0 ? 80*glitter : 0));
		var green = Math.round(255+(glitter>0 ? 80*glitter : 0));
		var blue = Math.round(255+(glitter>0 ? 80*glitter : 0));
		var highlightColor = "rgb("+red+", "+green+", "+blue+")";
		if ((timer%3)==0 && ((Math.floor(timer/50)&1)==0) && !this.userAcknowledged) {
			highlightColor = "#FF8080";
		}
		var blurredColor = "#A0A0A0";
		for (var i=0; i<this.optionCount; ++i)
		{
			this.imageFx.setHighlightColor(this.menuControls[i], (this.selectedOption==i ? highlightColor : blurredColor));
		}	
	 },
	
	/**
	 * Handler des événements onkeydown (touche clavier pressée)
	 * Choix de l'option du menu s'il s'agit d'une flèche verticale, en ignorant les options non disponibles.
	 * Renvoie true si l'événement doit continuer à être propagé (i.e. non traité ici), false sinon
	 */
	onKeyDown : function(event) {
		var handled = this.keyControl(event, true);
		if (this.upKeyPressed && !this.downKeyPressed) {
			var delta = 1;
			var deltaFound = 0;
			while (this.selectedOption-delta>=0 && deltaFound==0) {
				if (this.optionAvailable[this.selectedOption-delta]) {
					deltaFound = delta;
				}
				++delta;
			}
			this.selectedOption -= deltaFound;
		}
		if (!this.upKeyPressed && this.downKeyPressed) {
			var delta = 1;
			var deltaFound = 0;
			while (this.selectedOption+delta<this.optionCount && deltaFound==0) {
				if (this.optionAvailable[this.selectedOption+delta]) {
					deltaFound = delta;
				}
				++delta;
			}
			this.selectedOption += deltaFound;
		}
		return !handled;
	},
	
	/**
	 * Handler des événements onkeyup (touche clavier relâchée)
	 */
	onKeyUp : function(event) {
		this.keyControl(event, false);
	},
	
	/**
	 * Handler délégué pour les événements clavier.
	 * Enregistre les appuis et les relâchements des flèches
	 * et de la touche Escape.
	 * Renvoie true si l'événement est géré, false sinon
	 */
	keyControl : function(event, value)
	{
		var handled = true;
		var key = 0;
		if (window.event) { // IE
			key = window.event.keyCode;
		} else { // FF, Opera,...
			key = event.which;
		}

		switch (key) {
			case 38 : // fleche haut
				this.upKeyPressed = value;
				break;
			case 40 : // fleche bas
				this.downKeyPressed = value;
				break;
			case 27 : // escape
				this.selectedOption = this.escapeOption;
				this.userAcknowledged |= value;
				break;
			case 13 : // entrée
			case 32 : // espace
				this.userAcknowledged |= value;
				break;
			default :
				handled = false;
		}
		return handled;
	}	
	
}
	