/**
 * Fonctionnalités en rapport avec les contenus multimédia.
 * 
 * @require PAGE.util
 * @require	jQuery
 * @require SWFObject 2.x
 * @require FLV Player
 */
(function($) {
	
	/**
	 * Création ou récupération d'espaces de noms spécifiques.
	 */
	
	var P = window.PAGE, $util = P.util;
	var $media = P.media || (P.media = {});
	var $flash = $media.flash || ($media.flash = {});
	
	/////////////////////////////////////
	// Flash (plus players FLV et MP3).
	/////////////////////////////////////
	
	/**
	 * Id d'éléments de la page et classes qu'ils peuvent porter.
	 */
	
	var sFlashObjectClass = "flashObject";
	var sMediaPlayerClass = "mediaPlayer";
	var sVideoPlayerClass = "videoPlayer"
	var sAudioPlayerClass = "audioPlayer";
	var sFLVPlayerClass = "flvPlayer " + sVideoPlayerClass;
	var sMP3PlayerClass = "mp3Player " + sAudioPlayerClass;
	
	/**
	 * Chemin du fichier SWF du lecteur FLV.
	 */
	var sFLVPlayerPath = "media/images/local/skin/site/player_flv_maxi.swf";
	
	/**
	 * Chemin du fichier SWF du lecteur MP3.
	 */
	var sMP3PlayerPath = "media/images/local/skin/site/player_mp3_maxi.swf";
	
	/**
	 * Couleur de rollover de différents éléments des lecteurs (sans #).
	 */
	var sOverColor = "0098d3";
	
	/**
	 * Couleur de fond des lecteurs (sans #).
	 */
	var sBackgroundColor = "787878";
	
	/**
	 * Options par défaut de la fonction embedSWF().
	 */
	var hDefEmbedSWFOptions = {
		
		width: 640,
		height: 480,
		version: "9.0.0",
		expressInstallSWF: "media/js/site/libs/swfobject/expressInstall.swf",
		vars: {},
		params: {
			wmode: "transparent"
		},
		attributes: {}
	};
	
	/**
	 * Options par défaut de la fonction embedFLVPlayer(). Inclut les options
	 * par défaut pour FLV Player lui-même.
	 * 
	 * @see	http://flv-player.net/players/maxi/documentation/
	 */
	var hDefEmbedFLVPlayerOptions = {
			
		width: 300,
		height: 300,
		config: {
			shortcut: 0,
			showplayer: "autohide",
			showloading: "autohide",
			playertimeout: 500,
			showstop: 1,
			showvolume: 1,
			showtime: 1,
			showfullscreen: 1,
			// showiconplay: 1,
			bgcolor1: sBackgroundColor,
			bgcolor2: sBackgroundColor,
			playercolor: sBackgroundColor,
			buttonovercolor: sOverColor,
			sliderovercolor: sOverColor
		}
	};
	
	/**
	 * Options par défaut de la fonction embedMP3Player(). Inclut les options
	 * par défaut pour FLV Player lui-même.
	 * 
	 * @see	http://flv-player.net/players/maxi/documentation/
	 */
	var hDefEmbedMP3PlayerOptions = {
			
		width: 200,
		height: 20,
		config: {
			showloading: "autohide",
			showstop: 1,
			showvolume: 1,
			bgcolor1: sBackgroundColor,
			bgcolor2: sBackgroundColor,
			buttonovercolor: sOverColor,
			sliderovercolor: sOverColor
		}
	};
	
	/**
	 * Indique si on conteneur, sélectionné en jQuery, contient (ou est
	 * susceptible de contenir) un objet Flash (fut-ce un lecteur).
	 * 
	 * @public
	 * @param	jQuery	jCont	Un élément HTML sélectionné en jQuery.
	 * @return	Si cet élément contient, ou contiendra, un objet Flash.
	 */
	function containsFlash(jCont) {
		
		return jCont.find(
			"." + sFlashObjectClass +
			", ." + sMediaPlayerClass +
			", ." + sContainerClass
		).length > 0;
	}
	
	$flash.containsFlash = containsFlash;
	
	/**
	 * Remplace un élément de la page par un fichier SWF chargé par SWFObject.
	 * 
	 * <p>N.B. cette fonction ne fait rien si l'élément désigné par son id
	 * pour contenir le Flash est déjà un <object>.</p>
	 * 
	 * <p>Options de configuration recommandées :<ul>
	 *   <li>width: (640) Largeur.</li>
	 *   <li>height: (480) Hauteur.</li>
	 *   <li>vars: ({}) Table de hash de variables à passer au Flash.</li>
	 *   <li>params: ({}) Table de hash de paramètres à passer au Flash.</li>
	 *   <li>attribtues: ({}) Table de hash d'attributs à passer au Flash.</li>
	 * </ul></p>
	 * 
	 * @public
	 * @param	String	sSWFPath	Chemin du fichier .swf à mettre en place.
	 * @param	String	sContId		Identifiant HTML du conteneur du Flash.
	 * @param	Hash	hOptions	Options de configuration.
	 */
	function embedSWF(sSWFPath, sContId, hOptions) {
		
		// Vérification d'applicabilité.
		
		if ($("#" + sContId)[0].tagName.toLowerCase() === "object") {
			return;
		}
		
		// Récupération des options, prioritaires par rapport aux options
		// par défaut.
		
		hOptions = $util.extend(hDefEmbedSWFOptions, hOptions);
		
		// Mise en place avec SWFObject.
		
		swfobject.embedSWF(
				
			sSWFPath, sContId, hOptions.width, hOptions.height,
			hOptions.version, hOptions.expressInstallSWF, hOptions.vars,
			hOptions.params, hOptions.attributes
		);
		
		// Marquage avec des classes spécifiques.
		
		setTimeout(function() {
			$("#" + sContId).addClass(sFlashObjectClass);
		}, 150);
	}
	
	$flash.embedSWF = embedSWF;
	
	/**
	 * Remplace un élément de la page par un lecteur vidéo FLV en Flash.
	 * 
	 * <p>Options de configuration recommandées :<ul>
	 *   <li>width: (300) Largeur.</li>
	 *   <li>height: (300) Hauteur.</li>
	 *   <li>config: ({}) Configuration FLV Player (hors fichier FLV).</li>
	 * </ul></p>
	 * 
	 * <p>Options spécifiques à embedSWF disponibles :<ul>
	 *   <li>vars: ({}) Variables à passer au Flash (hors configuration FLV player).</li>
	 *   <li>params: ({}) Paramètres à passer au Flash (hors configuration plein écran).</li>
	 *   <li>attributes: ({}) Attributs à passer au Flash.</li>
	 * </ul></p>
	 * 
	 * @public
	 * @param	String	sFLVPath	URL absolue du fichier .flv à lire.
	 * @param	String	sContId		Identifiant HTML du conteneur du Flash.
	 * @param	Hash	hOptions	Options de configuration.
	 * @param	Hash	hSWFOptions (Opt.) Options spécifiques à embedSWF().
	 */
	function embedFLVPlayer(sFLVPath, sContId, hOptions, hSWFOptions) {
		
		// Récupération des options, prioritaires par rapport aux options
		// par défaut.
		
		hOptions = $util.extend(hDefEmbedFLVPlayerOptions, hOptions);
		
		// Mise en place avec SWFObject. Toutes les options de configuration
		// FLV Player sont en fait transmises ici, sous forme de variables.
		// On force les dimensions dans les options de FLV Player pour IE.
		
		var hVars = $util.extend({			
			
			flv: sFLVPath,
			width: hOptions.width,
			height: hOptions.height
		},
		hOptions.config);
		
		hSWFOptions = $util.extend({
			
			width: hOptions.width,
			height: hOptions.height,
			vars: hVars,
			params: {
				allowfullscreen: (hVars.showfullscreen == 1)
			}			
		},
		hSWFOptions);
		
		setTimeout(function() {

			embedSWF(sFLVPlayerPath, sContId, hSWFOptions);
			
			// Marquage avec des classes spécifiques.
			
			setTimeout(function() {
				$("#" + sContId).addClass(sMediaPlayerClass)
				.addClass(sFLVPlayerClass);
			}, 150);
			
		}, 50);
	}
	
	$flash.embedFLVPlayer = embedFLVPlayer;
	
	/**
	 * Remplace un élément de la page par un lecteur audio MP3 en Flash.
	 * 
	 * <p>Options de configuration recommandées :<ul>
	 *   <li>width: (300) Largeur.</li>
	 *   <li>height: (300) Hauteur.</li>
	 *   <li>config: ({}) Configuration MP3 Player (hors fichier MP3).</li>
	 * </ul></p>
	 * 
	 * <p>Options spécifiques à embedSWF disponibles :<ul>
	 *   <li>vars: ({}) Variables à passer au Flash (hors configuration FLV player).</li>
	 *   <li>params: ({}) Paramètres à passer au Flash.</li>
	 *   <li>attributes: ({}) Attributs à passer au Flash.</li>
	 * </ul></p>
	 * 
	 * @public
	 * @param	String	sMP3Path	URL absolue du fichier .mp3 à lire.
	 * @param	String	sContId		Identifiant HTML du conteneur du Flash.
	 * @param	Hash	hOptions	Options de configuration.
	 * @param	Hash	hSWFOptions (Opt.) Options spécifiques à embedSWF().
	 */
	function embedMP3Player(sMP3Path, sContId, hOptions, hSWFOptions) {
		
		// Récupération des options, prioritaires par rapport aux options
		// par défaut.
		
		hOptions = $util.extend(hDefEmbedMP3PlayerOptions, hOptions);
		
		// Mise en place avec SWFObject. Toutes les options de configuration
		// MP3 Player sont en fait transmises ici, sous forme de variables.
		// On force les dimensions dans les options de MP3 Player pour IE.
		
		var hVars = $util.extend({
			
			mp3: sMP3Path,
			width: hOptions.width,
			height: hOptions.height
		},
		hOptions.config);
		
		hSWFOptions = $util.extend({
			
			width: hOptions.width,
			height: hOptions.height,
			vars: hVars		
		},
		hSWFOptions);
		
		setTimeout(function() {
			
			embedSWF(sMP3PlayerPath, sContId, hSWFOptions);
		
			// Marquage avec des classes spécifiques.
			
			setTimeout(function() {
				$("#" + sContId).addClass(sMediaPlayerClass)
				.addClass(sMP3PlayerClass);
			}, 150);
		
		}, 50);
	}
	
	$flash.embedMP3Player = embedMP3Player;
	
	////////////////////////////////////////////
	// Flash & players: automatic realization.
	////////////////////////////////////////////
	
	/**
	 * Id d'éléments de la page et classes qu'ils peuvent porter.
	 */
	
	var sContainerClass = "mediaContainer"; // Conteneur général.
	var sDeferClass = "mediaDefer"; // Pour le conteneur : réalisation différée.
	
	var sConfigAnchorClass = "mediaConfig"; // Pour ancre : info de configuration.
	var sVarAnchorClass = "mediaVar"; // Pour ancre : info de variable Flash.
	var sParamAnchorClass = "mediaParam"; // Pour ancre : info de paramètre Flash.
	var sAttribAnchorClass = "mediaAttrib"; // Pour ancre : info d'attribut Flash.
	var sDataAnchorClass = "mediaData"; // Pour ancre : source de l'objet Flash.
	
	var iFlashObjectIdGenerator = 0;
	var sFlashObjectIdPrefix = sFlashObjectClass + "-";
	
	/**
	 * Noms d'entrées de hOptions et non de hOptions.config.
	 */
	var hBaseConfigEntries = {	
		width: true, height: true
	};
	
	/**
	 * Noms d'entrées de hSWFOptions et non de hOptions.config.
	 */
	var hBaseSWFConfigEntries = {
		version: true
	};
	
	/**
	 * Fournit un identifiant unique destiné à un objet Flash.
	 * 
	 * @return	String	Un identifiant unique.
	 */
	function generateFlashObjectId() {
		return sFlashObjectIdPrefix + (iFlashObjectIdGenerator++);
	}
	
	/**
	 * Remplace le conteneur de la description d'un objet multimedia par
	 * l'objet décrit.
	 *  
	 * @param	String|jQuery	xCont	Conteneur multimédia, ou son identifiant HTML.
	 */
	function realize(xCont) {
		
		// Récupération du conteneur, en lui ajoutant un identifiant HTML 
		// s'il n'en possède pas déjà.
		
		var sContId, jCont;
		
		if (typeof xCont === "string") {
			
			sContId = xCont;
			jCont = $("#" + xCont);
		}
		else {
			
			jCont = xCont;
			sContId = jCont.attr("id");
		
			if (!sContId) {
				
				sContId = generateFlashObjectId();
				jCont.attr("id", sContId);
			}
		}
		
		// HACK: attention aux imbrications sauvages en texte riche...
		
		jCont.find("." + sContainerClass).insertAfter("#" + sContId);
		
		// Récupération de toutes les options.
		
		var hOptions = {config: {}};
		var hSWFOptions = {vars: {}, params: {}, attributes: {}};
		
		function readOpt(jAnchor) {
			
			var hOpt;
			
			var sOpt = jAnchor.attr("name");
			var iDelimPos = sOpt.indexOf(":");
			
			if (iDelimPos > 0) {
			
				hOpt = {
					name: sOpt.substring(0, iDelimPos),
					value: sOpt.substring(iDelimPos + 1)
				};
			}
			
			return hOpt;
		}
		
		jCont.find("a." + sConfigAnchorClass).each(function() {
			
			var hOpt = readOpt($(this));
			
			if (!!hOpt) {
				
				if (!!hBaseConfigEntries[hOpt.name]) {
					hOptions[hOpt.name] = hOpt.value;
				} else if (!!hBaseSWFConfigEntries[hOpt.name]) {
					hSWFOptions[hOpt.name] = hOpt.value;
				} else {
					hOptions.config[hOpt.name] = hOpt.value;
				}
			}
		});
		
		jCont.find("a." + sVarAnchorClass).each(function() {
			
			var hOpt = readOpt($(this));
			
			if (!!hOpt) {
				hSWFOptions.vars[hOpt.name] = hOpt.value;
			}
		});
		
		jCont.find("a." + sParamAnchorClass).each(function() {
			
			var hOpt = readOpt($(this));
			
			if (!!hOpt) {
				hSWFOptions.params[hOpt.name] = hOpt.value;
			}
		});
		
		jCont.find("a." + sAttribAnchorClass).each(function() {
			
			var hOpt = readOpt($(this));
			
			if (!!hOpt) {
				hSWFOptions.attributes[hOpt.name] = hOpt.value;
			}
		});
		
		var sDataPath = jCont.find("a." + sDataAnchorClass).eq(0).attr("href");
		
		// Remplacement du conteneur par l'animation ou le player approprié.
		
		if (!!sDataPath) {
			
			if (jCont.hasClass(sVideoPlayerClass)) {
				embedFLVPlayer(sDataPath, sContId, hOptions, hSWFOptions);
			} else if (jCont.hasClass(sAudioPlayerClass)) {
				embedMP3Player(sDataPath, sContId, hOptions, hSWFOptions);
			} else {
				embedSWF(sDataPath, sContId, $util.extend(hOptions, hSWFOptions));
			}
		}
	}
	
	$flash.realize = realize;
	
	/**
	 * Remplace tous les conteneurs de descriptions d'objets multimedia
	 * descendants d'un autre conteneur par les objets décrits.
	 *  
	 * @param	String|jQuery	xCont	Conteneur ou son identifiant HTML.
	 */
	function realizeAllChildren(xCont) {
		
		var jCont = (typeof xCont === "string" ? $("#" + xCont) : xCont);
		
		jCont.find("div." + sContainerClass).each(function() {
			realize($(this));
		});
	}
	
	$flash.realizeAllChildren = realizeAllChildren;
	
	/**
	 * Remplace tous les conteneurs de descriptions d'objets multimedia
	 * visibles sur la page par les objets décrits.
	 */
	function realizeAllVisible() {
		
		// On recherche tous les conteneurs visibles qui décrivent des objets
		// multimédia à réaliser sur la page.
		
		$("div." + sContainerClass + ":visible").each(function() {
			realize($(this));
		});
	}
	
	/**
	 * Mise en place au chargement de la page.
	 */	
	$(document).ready(function() {
		
		// Mise en place de tous les objets Flash visibles d'emblée.
		
		realizeAllVisible();
	});
})
(jQuery);