/**
 * imports nécessaires
 * 
 *	<script language="JavaScript" src="xbDom.js"></script>
 *
 */

/**
 * Objet l'affichage et le déroulement d'un diaporama
 * @param a_name      identifiant du diaporama (unique sur la page)
 * @param a_images    tableau des images à afficher
 * @param a_format    paramétrage de l'affichage (si null, pas de construction par défaut)
 * @param a_init	  true si affichage de la première diapo
 */
function DiapoComponent(a_name, a_images, a_format, a_init) {
	this.name = a_name;
	this.images = a_images;
	
	this.init = ((a_init == null) || (a_init == 'undefined')) ? true : a_init;

	this.initFormat = function(a_format) {
		if (a_format) {
			this.format = a_format;
		} else {
			// construction d'un format par défaut
			this.format = new Object();
			this.format.table = new Object();
			this.format.image = new Object();
			this.format.desc = new Object();
		}
	}
	
	/**
	 * Renvoie le paramètre a_paramName de l'objet a_obj.
	 * S'il n'est pas défini, renvoie a_default.
	 * @param a_obj		    objet contenant les paramètres
	 * @param a_paramName   nom du paramètre demandé
	 * @param a_default		valeur par défaut
	 */
	this.getParam = function(a_obj, a_paramName, a_default) {
		if (a_obj && a_obj[a_paramName]) {
			return a_obj[a_paramName];
		} else {
			return a_default;
		}
	}
	
	/**
	 * Renvoie l'éventuelle css.
	 * @param a_obj		    objet contenant la css
	 * @param a_paramName   nom du paramètre demandé
	 */
	this.getCss = function(a_obj, a_paramName) {
		var l_css = this.getParam(a_obj, a_paramName);
		if (l_css) {
			return ' class="' + l_css + '"';
		} else {
			return '';
		}
	}
	
	/**
	 * Insère à l'endroit d'appel le code complet du composant
	 */
	this.build = function() {
		// on définit les identifiants des boutons présents
		var l_boutons = (this.format.commands) 
							? this.format.commands
							: [{"id":"prev"}, {"id":"stop"}, {"id":"start"}, {"id":"next"}];
		var l_s = "";

		// table
		l_s += '<table align="' + this.getParam(this.format.table, 'align', 'center')
				+ '" width="' + this.getParam(this.format.table, 'width', '100%')
				+ '" height="' + this.getParam(this.format.table, 'height', '100%')
				+ '" border="' + this.getParam(this.format.table, 'border', '0')
				+ '" cellspacing="' + this.getParam(this.format.table, 'cellspacing', '5')
				+ '" cellpadding="' + this.getParam(this.format.table, 'cellpadding', '3')
				+ '"';
		l_s	+= this.getCss(this.format.table, 'css');
		l_s += '>';
		
		// image
		l_s += '<tr>';
		l_s += '<td colspan="' + (l_boutons.length > 0 ? l_boutons.length : 1)
				+ '" height="'  + this.getParam(this.format.image, 'heightTD', '100%')
				+ '" align="'  + this.getParam(this.format.image, 'align', 'center')
				+ '" valign="' + this.getParam(this.format.image, 'valign', 'middle');
		l_s += '"';
		l_s	+= this.getCss(this.format.image, 'css');
		l_s += '>';
		l_s += '<img id="img_' + this.name + '"';
		// largeur imposée
		var l_size = this.getParam(this.format.image, "width", 0);
		if (l_size > 0) {
			l_s += ' width="' + l_size + '"';
		}
		l_size = this.getParam(this.format.image, "height", 0);
		if (l_size > 0) {
			l_s += ' height="' + l_size + '"';
		}
		
		if (this.getParam(this.format.image, 'defil', (l_boutons.length > 0)) == true) {
			l_s += ' onclick="' + this.name + '.switchDefil();"';
		}
		if (window.imgLoaded) {
			l_s += ' onload="imgLoaded(' + this.name + ')";'
		}
		l_s += '/>';
		l_s += '</td>';
		l_s += '</tr>';
		
		// description (text)
		if (this.format.desc) {
			// on veut bien le texte
			l_s += '<tr>';
			l_s += '<td colspan="' + l_boutons.length 
						+ '" align="' + this.getParam(this.format.desc, 'align', 'center');
			l_s += '"';
			
			l_s	+= this.getCss(this.format.desc, 'cssTD');
			l_s += ' id="desc_' + this.name + '" name="desc_' + this.name;
			l_s += '">&nbsp;';
			l_s += '</td>';
			l_s += '</tr>';
		}
		
		// boutons (encapsulés dans une table)
		this.commands = [];
		if (l_boutons.length > 0) {
			l_s += '<tr>';
			l_s += '<td';
			l_s	+= this.getCss(this.format.tableCommands, 'cssTD');
			l_s += '>';
			// table
			l_s += '<table align="' + this.getParam(this.format.tableCommands, 'align', 'center') 
					+ '" width="' + this.getParam(this.format.tableCommands, 'width', '100%')
					+ '" border="' + this.getParam(this.format.tableCommands, 'border', '0')
					+ '" cellspacing="' + this.getParam(this.format.tableCommands, 'cellspacing', '5')
					+ '" cellpadding="' + this.getParam(this.format.tableCommands, 'cellpadding', '3')
					+ '"';
			l_s	+= this.getCss(this.format.table, 'css');
			l_s += '>';
			
			l_s += '<tr>';
			var l_command;
			var l_params;
			for (i = 0; i < l_boutons.length; i++) {
				l_command = l_boutons[i].id;
				l_params = l_boutons[i].params;
				// on conserve les paramètres directement accessibles par le nom de la commande
				this.commands[l_command] = l_params;
				
				l_s += '<td';
				if (l_params && l_params.widthTD) {
					l_s += ' width="' + l_params.widthTD + '"';
				}
				if (l_params && l_params.align) {
					l_s += ' align="' + l_params.align + '"';
				}
				if (l_params && l_params.cssTD) {
					l_s += ' class="' + l_params.cssTD + '"';
				}
				l_s += '>';
				// div
				l_s += '<div id="' + l_command + '_' + this.name + '" onclick="';
				if (l_params && l_params.cssOff) {
					l_s += 'this.className = \'' + l_params.cssOff + '\';';
				}
				if (l_params && l_params.command) {
					l_s += l_params.command;
				} else {
					l_s += this.name + '.' + l_command + '();';
				}
				l_s += '"';
				if (l_params && l_params.cssOff) {
					l_s += ' class="' + l_params.cssOff + '"';
					l_s += ' onmouseup="this.className = \'' + l_params.cssOff + '\';"';
				}
				if (l_params && l_params.cssClic) {
					l_s += ' onmousedown="this.className = \'' + l_params.cssClic + '\';"';
				}
				if (l_params && l_params.width) {
					l_s += ' style="width:' + l_params.width + '"';
				}
				l_s += '>';
				l_s += (l_params && l_params.codeOff) ? l_params.codeOff : l_command;
				l_s += '</div>';
				l_s += '</td>';
			}
			l_s += '</tr>';
			l_s += '</table>';
	
			l_s += '</td>';
			l_s += '</tr>';
		}
		l_s += '</table>';
		
		// on affiche
		document.write(l_s);
		
		// on initialise les images
		this.initImages();
		
		// on initialise le comportement des boutons
	}
	
	/**
	 * Ajoute les images définit dans le tableau à la combo.
	 */
	this.initImages = function() {
		this.image = xbGetElementById("img_" + this.name);
		this.imgDesc = xbGetElementById("desc_" + this.name);

		// on affiche la premiere
		if (this.init == true) {
			this.displayImage(0);
		}
	}
	
	/**
	 * Affiche l'image correspondant à l'index fourni.
	 * @param a_index index (0 based)
	 */
	this.displayImage = function(a_index) {
		// on conserve l'index courant
		this.index = a_index;
		
		// affiche l'image correspondant a l'index
		this.image.src = ((this.format._imgs) ? this.format._imgs : '.')+ '/' 
							+ this.images[a_index][0];

		// appelle la méthode de callback si elle existe
		if (this.imgSelected) {
			this.imgSelected(a_index);
		}
	}
	
	// on lance la construction directement dans le constructeur, si un format est défini
	this.initFormat(a_format);
	if (a_format) {
		this.build();
	}
		
	/**
	 * Affiche l'image venant d'être sélectionnée dans la combo.
	 */
	this.imageSelected = function() {
		// affiche l'image selectionnee
		this.displayImage(this.imgDesc.selectedIndex);
	}
	
	/**
	 * Renvoie l'index de l'image sélectionnée.
	 * @return l'index sélectionné
	 */
	this.getSelected = function() {
		return this.index;
	}
	
	/**
	 * Sélectionne et affiche l'image correspondant à l'index fourni.
	 * @param a_newIndex   index de l'image à afficher
	 */
	this.setSelected = function(a_newIndex) {
		if (this.imgDesc) {
			xbSetInnerHTML(this.imgDesc, this.images[a_newIndex][1]);
		}
		// affiche l'image associee
		this.displayImage(a_newIndex);
	}
	
	/**
	 * Sélectionne et affiche l'image correspondant au nom de de la source fournie.
	 * @param a_imgSrc   nom de la source de l'image à afficher
	 */
	this.setSelectedSrc = function(a_imgSrc) {
		// on parcours la liste de sources pour trouver l'index correspondant
		for (i = 0; i < this.images.length; i++) {
			if (this.images[i][0] == a_imgSrc) {
				this.setSelected(i);
				break;
			}
		}
	}
	
	/**
	 * Affiche l'image suivante, en bouclant.
	 */
	this.next = function() {
		// recupere l'index courant
		var l_index = this.getSelected();
		// incremente
		l_index++;
		// verifie que l'index ne sort pas des bornes
		l_index %= this.images.length;
		// selectionne l'index
		this.setSelected(l_index);
	}
	
	/**
	 * Affiche l'image précédante, en bouclant.
	 */
	this.prev = function() {
		// recupere l'index courant
		var l_index = this.getSelected();
		// decremente
		l_index--;
		// verifie que l'index ne sort pas des bornes
		if (l_index < 0) {
			l_index = this.images.length - 1;
		}
		// selectionne l'index
		this.setSelected(l_index);
	}
	
	/**
	 * Lance le déroulement automatique du diaporama, 
	 * à partir de l'image courante.
	 */
	this.start = function() {
		if (this.defil) {
			// on ne fait rien
		} else {
			// on essaie de garder le bouton start enfonce
			this.pushCommand("start", "true");
			// on change
			this.next();
			// on continue
			this.defil = window.setInterval(a_name + ".next()", this.getParam(this.format, "delay", 2000));
		}
	}
	
	/**
	 * Arrête le déroulement.
	 */
	this.stop = function() {
		if (this.defil) {
			window.clearInterval(this.defil);
			this.defil = null;
			// on "releve" le bouton start
			this.pushCommand("start");
		}
	}
	
	/**
	 * Lance ou arrête le défilement en fonction de l'état courant.
	 */
	this.switchDefil = function() {
		if (this.defil) {
			// on arrête
			this.stop();
		} else {
			// on lance
			this.start();
		}
	}
	
	/**
	 * Enfonce le bouton correspondant à la commande fournie si a_true est définit,
	 * le relève sinon.
	 * @param  a_command  nom de la commande
	 * @param  a_true  si définit, enfonce le bouton
	 */
	this.pushCommand = function(a_command, a_true) {
		var l_params = this.commands[a_command];
		if (l_params) {
			// il y a bien une commande correspondante
			// on recupere le div correspondant a la commande
			var l_div = xbGetElementById(a_command + "_" + this.name);
			if (l_div) {
				// on change la css
				if (a_true) {
					if (l_params.cssOn) {
						l_div.className = l_params.cssOn;
					}
					if (l_params.codeOn) {
						xbSetInnerHTML(l_div, l_params.codeOn);
					}
				} else {
					if (l_params.cssOff) {
						l_div.className = l_params.cssOff;
					}
					if (l_params.codeOff) {
						xbSetInnerHTML(l_div, l_params.codeOff);
					}
				}
			}
		}
	}
	
	/**
	 * Enfonce le bouton correspondant à la commande fournie si a_true est définit,
	 * le relève sinon.
	 * @param  a_command  nom de la commande
	 * @param  a_true  si définit, enfonce le bouton
	 */
	this.updateResolutionLinks = function(a_imgSrc, a_links) {
		var l_index = this.setSelectedSrc(a_imgSrc);
		if (!a_links || a_links.length == 0 ) {
			return;
		}
		var l_formatsOffset = 2;
		for (var i = 0; i < a_links.length; i++) {
			var l_link = a_links[i];
			l_link.href = repImgs + "/" + this.images[l_index][l_formatsOffset + i];
			l_link.title = repImgs + "/" + this.images[l_index][l_formatsOffset + i];
		}
	}
}
