/**
 * @package bibliotheque
 * @subpackage benchmark
 * @filesource
 */

/**
 * objet js permettant l'affichage à la manière de jquery.thickbox mais avec la possibilité d'ouvrir n'importe quel code html fournit en paramêtre
 *
 * exemple simple :
 * PHP:
 * $laPage->ajouteJavascript('/framework/lib/js/html_include/benchmark/framework/util/objet.js');
 * $laPage->ajouteJavascript('/framework/lib/js/html_include/benchmark/framework/ihm/objpopup.js');
 * $objPage->ajouteStyle('/framework/lib/js/html_include/benchmark/framework/ihm/objpopup.css');
 * ou
 * $objPage->ajouteStyle('application/lib/js/html_include/benchmark/framework/ihm/');
 * JS:
 * popup = new benchmark.framework.ihm.ObjPopup();
 * popup.ouvreHtml('<p>blabla</p>');
 *
 * popup = new benchmark.framework.ihm.ObjPopup();
 * popup.ouvreURL('http://www.google.com');
 *
 * ou bien pour une image :
 * popup = new benchmark.framework.ihm.ObjPopup();
 * popup.ouvreImage('http://un.site.com/image.jpg');
 *
 * ou bien pour du flash :
 * popup = new benchmark.framework.ihm.ObjPopup();
 * popup.ouvreFlash('http://un.site.com/flash.swf');
 *
 * avec des options :
 * popup = new benchmark.framework.ihm.ObjPopup( { vitesse : 100 });
 * popup.ouvreImage('<p>blabla</p>',{classe : 'autreclasse', id : 28 });
 *
 * pour fermer le popup manuellement :
 * popup.fermer();
 *
 * @author Damien BENOIT <benoit@benchmark.fr>
 * @package bibliotheque
 * @subpackage html_include
 * @version 1.00
 * @since 26/07/08 création du fichier
 * @since 14/10/08 Pierre Chabiland <chabiland@benchmark.fr> ajout d'une methode "modifie" + ajout d'un parametre de configuration à la methode ouvrir et ouvrirHtml
 * @since 16/10/08 Olivier REYT <reyt@benchmark.fr> ajout des methodes "ouvreIframe" et "ouvreURL"
 * @since 16/10/08 Damien BENOIT <benoit@benchmark.fr> changement dans les méthodes d'ouverture et fermeture pour pouvoir réinstancier l'objet plus rapidement et éviter le bug de délais d'une seconde
 * @since 16/12/2008 Thomas JOBERT <jobert@benchmark.fr> Diverses modifs : centrage, animation
 * @since 08/04/2009 Benoit LANDHAUSER <landhauser@benchmark.fr> ajout du parametre masquerFlash 
 *			pour ne pas masquer automatiquement les flash à l'ouverture de la popup
 * 			ce paramètre est à trus par défaut (le flash sera masqué), pour les pubs flash notamment
 */

if(typeof benchmark == "undefined") { var benchmark = new Object(); }
if(typeof benchmark.framework == "undefined") { benchmark.framework = new Object(); }
if(typeof benchmark.framework.ihm == "undefined") { benchmark.framework.ihm = new Object(); }

/**
 * constructeur :
 * @param configuration objet de configuration (optionnel )
 * @return void
 */
benchmark.framework.ihm.ObjPopup = function(configuration)
{
	this.configurationDefaut = 
		{
			largeur	: 500,
			hauteur	: 300,
			x		: 0,
			y		: 0,
			vitesse	: 200
		};
	
	/*
	 * Mode d'ouverture de la popup
	 */
	this.modeOuverture = '';

	/**
	 * méthodes de l'objet :
	 */

	/**
	 * fermeture du popup
	 */
	this.ferme = function()
	{
		var objPopupConteneur = $('#ObjPopupConteneur');
		var objPopupMasque = $('#ObjPopupMasque');

		objPopupMasque.unbind('click');
		objPopupMasque.hide();
		objPopupConteneur.slideUp('fast');

		if ($.browser.msie && $.browser.version == '6.0')
		{
			// hack IE permettant de bien supprimer une animation flash dans la page
			$('object', objPopupConteneur).remove();
			$('select.ObjPopUp_select').removeClass('ObjPopUp_select').show();
		}
		if (this.configuration.masquerFlash)
		{
			// On enleve la classe ObjPopUp_flash à tous les flashs et on les réaffiche
			$('.ObjPopUp_flash').removeClass('ObjPopUp_flash').css("visibility", "visible");
		}
		objPopupMasque.remove();
		objPopupConteneur.remove();
	};



	/*
	 * obtenir les coordonnées centrées 
	* return array x et y positions centrées de l'objet 
	* @since 17/11/2008 Thomas JOBERT <jobert@benchmark.fr>
	* Lorsque l'une des taille est supérieure à celle de la fenetre le centrage correspondant n'est pas effectué
	* @since 19/12/2008 Thomas JOBERT Modif gestion du centrage des popups ayant une taille supérieure à la fenêtre
	 *
	 */

	this.getCoordonneeCentre = function ()
	{

		var posX=0;
		var posY=0;
		
		// centrage vertical
		if ($('#ObjPopupConteneur').height() < $(window).height()) {
			posY = ( ( $(window).height() / 2 ) - ( $('#ObjPopupConteneur').height() / 2 ) );
			
			if( $.browser.msie && $.browser.version == '6.0' ){
				posY += (document.body.scrollTop || document.documentElement.scrollTop);
			}
		} else {
			// position absolue pour le scroll
			$('#ObjPopupConteneur').css('position','absolute');
			$('#ObjPopupMasque').css('height', $(window).height());
			$('#ObjPopupMasque').css('position','fixed');
		}

		// centrage horizontal
		if ($('#ObjPopupConteneur').width() < $(window).width()){
			posX = ( $(window).width()  / 2) - ($('#ObjPopupConteneur').width() / 2);
		} else {
			// position absolue pour le scroll
			$('#ObjPopupConteneur').css('position','absolute');
			$('#ObjPopupMasque').css('width', $(window).width());
			$('#ObjPopupMasque').css('position','fixed');
		}
		
		
		return  {
			x : posX,
			y : posY
		};
		
	};	



	/**
	 * centrer le popup
	 * @return void
	 */
	this.centre = function()
	{
		// centrage :
		var centrer = this.getCoordonneeCentre();
		this.deplace(centrer.x, centrer.y);
	};

	/**
	 * redimensionner le popup
	 * @param x position x
	 * @param y position y
	 * @return void
	 */
	this.redimensionne = function(hauteur, largeur)
	{
		$("#ObjPopIframe").attr(
			{
				width: largeur,
				height: hauteur
			}
		);

		//if ($.browser.msie && $.browser.version == '6.0')
		if ($.browser.msie)
		{
			$('#ObjPopupConteneur').css(
				{
					width: largeur + 'px',
					height: hauteur + 'px'
				}
				);
		}
		else
		{
			$('#ObjPopupConteneur').animate(
				{
					width		: largeur + 'px',
					Height	: hauteur + 'px'
				},
				this.configuration.vitesse
			);
		}
	};


	/**
	 * déplacer le popup aux coordonnées
	 * @param x position x
	 * @param y position y
	 * @return void
	 */
	this.deplace = function(x, y)
	{
		if ($.browser.msie)
		{
			$('#ObjPopupConteneur').css({
				top: y + 'px',
				left: x + 'px'
			});
		}
		else
		{
			$('#ObjPopupConteneur').animate(
				{
					top	: y + 'px',
					left	: x + 'px'
				},
				this.configuration.vitesse
			);
		}
	};

	/**
	* fonction privée centrale d'ouverture du popup acceptant n'importe quel contenu
	* @param contenu string html
	*/
	this.ouvre = function(contenu, configuration)
	{
		
		/* Configuration par défaut de la fonction */
		configuration = benchmark.framework.util.objet.fusion(
			configuration,
			{
				fermetureSurClic		: true,
				fermetureMasqueSurClic	: true,
				fermetureAfficheBouton	: true,
	                	ouvertureAvecAnimation	: false,
	                	masquerFlash		: true
                	}
		);

		/* On complète la configuration de ObjPopup */
		this.configuration = benchmark.framework.util.objet.fusion(
			configuration,
			this.configuration
		);

		/* Si on souhaite masquer les flash (comportement par defaut) */
		if (this.configuration.masquerFlash)
		{
			if ($.browser.msie)
			{
				$('object:has(param[name!="wmode"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
				$('object:has(param[name="wmode"][value="window"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
			}
			else
			{
				$('object:has(param[name!="wmode"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
				$('object:has(param[name="wmode"][value="window"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
				$("[src$='swf'][wmode!='opaque'][wmode!='transparent']").addClass('ObjPopUp_flash').css("visibility", "hidden");
			}
		}
		
		if ($('#ObjPopupMasque').attr('id') != 'ObjPopupMasque')
		{
			
			$('body').append(
				'<div id="ObjPopupMasque"></div>'+
				'<div id="ObjPopupConteneur" style="top:'+this.configuration.y+'px;left:'+this.configuration.x+'px;'+
				( ($.browser.msie && $.browser.version == '6.0' ) ? 'width:'+this.configuration.largeur+'px;height:'+this.configuration.hauteur+'px;' : '' ) +
				'">'+
				( (configuration.fermetureAfficheBouton) ? '<a id="ObjPopupTitre" href="#">Fermer ou échap</a>' : '' ) +
				'<div id="ObjPopupContenu" >' + contenu + '</div>'+
			    '</div>'
			);

			$('#ObjPopupTitre').click(function(event) {
				if (typeof(objPopup) != 'undefined')
				{
					objPopup.ferme();
					return false;
				}
			});

			if ($.browser.msie && $.browser.version == '6.0')
				$('select').addClass('ObjPopUp_select').hide();
		}

		var objPopupConteneur = $('#ObjPopupConteneur');
		var objPopupContenu = $('#ObjPopupContenu');
		var objPopupMasque = $('#ObjPopupMasque');

		/* Si on ne souhaite pas l'animation d'ouverture alors on centre directement */
		if (!this.configuration.ouvertureAvecAnimation)
		{
	    		var centrer = this.getCoordonneeCentre();
			objPopupConteneur.css({
				top: centrer.y + 'px',
				left: centrer.x + 'px'
			});
		}
	
		objPopupMasque.css('opacity', '0.7');
		objPopupMasque.fadeIn('fast');
		// 25/02/2009 Adeline SAILLARD <saillard@benchmark.fr>
		// Cas très particulier (verrue) : si on est en mode iframe sur ie6, alors on ajoute un timeout pour corriger un bug de popup vide présent uniquement dans ce cas
		// TODO : à revoir
		if (this.modeOuverture == 'iframe' && $.browser.msie) {
			setTimeout(function() {
				objPopupContenu.html(contenu);
			}, 100);
		} else {
			objPopupContenu.html(contenu);
		}
		objPopupConteneur.fadeIn('fast');
		objPopupContenu.fadeIn('fast');

		// on bind la suppression à la touche echap
		// ajout de l'objet dans le scope local :
		var objPopup = this;

		if(configuration.fermetureMasqueSurClic)
		{
			objPopupMasque.click(function(event) {
				if (typeof(objPopup) != 'undefined')
				{
					objPopup.ferme();
					return false;
				}
			});
		}

		if(configuration.fermetureSurClic)
		{
			objPopupConteneur.click(function(event) {
				if (typeof(objPopup) != 'undefined')
				{
					objPopup.ferme();
					return false;
				}
			});
		}

		if($.browser.msie)
		{
			$(document).bind('keydown', function(event) {
				if (event.keyCode == 27)
				{
					objPopup.ferme();
					return false;
				}
			});

			// bind pour le recentrage
			$(window).resize(function(event) {
				if (typeof(objPopup) != 'undefined' && objPopup.configuration.ouvertureAvecAnimation)
					objPopup.centre();
			});
		}
		else
		{
			$(window).keydown(function(event) {
				if (event.keyCode == 27 ) // on ne réagit que sur échap
				{
					if(typeof(objPopup) != 'undefined' )
					{
						objPopup.ferme();
						return false;
					}
				}
			}).resize(function(event) { // bind pour le recentrage
				if (typeof(objPopup) != 'undefined' )
				{
					if(objPopup.configuration.ouvertureAvecAnimation)
						objPopup.centre();
				}
			});
		}

		if (this.configuration.ouvertureAvecAnimation)
		{
			setTimeout(function() {objPopup.centre();}, 100);
			// certains browsers ont du mal au premier jet on retente, tant pis pour l'effet rebond
			setTimeout(function() {objPopup.centre();}, 500);
		} else {
			// Le recentrage est effectué recentrer les popups plus hautes que l'écran et les passer en fixe pour pouvoir scroller.
			objPopup.centre();
		}


	};

	/**
	 * fonction public permettant de modifier le contenu html de la popup tout en la laissant ouverte
	 * @param contenu html le contenu remplacant l'existant
	 * @param callBack function methode appelée quand le contnu html est disponible dans le dom
	 */
	this.modifie = function(contenu, callBack)
	{
		$('#ObjPopupContenu').fadeOut('fast', function(){
			var self = $(this);
			self.empty();
			self.html(contenu);
			if (callBack)
				callBack();
			self.fadeIn('fast');
		});
	}

	/**
	 * ouverture du popup en affichant du code html
	 * @todo Faire en sorte que la taille du popup s'adapte a la taille du contenu
	 * @param contenu html
	 */
	this.ouvreHtml = function(contenu, configuration)
	{
		this.modeOuverture = 'html';
		
		this.ouvre(contenu, configuration);
	};

	/**
	 * ouverture du popup en affichant du code html que l'on ira chercher dans une URL
	 *
	 * @param url url de la page à charger
	 * @param configuration Tableau contenant les différentes informations de configuration
	 * @return Void
	 * @author Olivier Reyt <reyt@benchmark.fr>
	 * @since 16/10/2008 Olivier Reyt <reyt@benchmark.fr>
	 */
	this.ouvreURL = function(url, configuration)
	{
		var contenu = $.ajax({url: url, async: false}).responseText;
		
		this.modeOuverture = 'url';
		
		this.ouvre(contenu, configuration);
	};

	/**
	 * Ouverture du popup en affichant du code html que l'on ira chercher dans une URL
	 * Si on a l'élément DimensionAuto à TRUE dans la configuration, on chargera automatiquement la taille
	 * en fonction de la taille du body de l'iframe
	 *
	 * @param url url de la page à charger
	 * @param configuration Tableau contenant les différentes informations de configuration
	 * @return Void
	 * @author Olivier Reyt <reyt@benchmark.fr>
	 *	On charge le contenu de l'iframe dans la variable contenu
	 * @since 16/10/2008 Olivier Reyt <reyt@benchmark.fr>
	 */
	this.ouvreIframe = function(url, configuration)
	{

		// On fusionne les tableaus de configuration
		configuration = benchmark.framework.util.objet.fusion(
			configuration,
			this.configurationDefaut
		);

		this.modeOuverture = 'iframe';

		var contenu = '<iframe id="ObjPopIframe" src=' + url + ' width=' + configuration.largeur + ' height=' + configuration.hauteur + ' frameborder="0"></iframe>';

		// On ajoute un type à tous les FLASH et on les caches
		if ($.browser.msie)
		{
			$('object:has(param[name!="wmode"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
			$('object:has(param[name="wmode"][value="window"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
		}
		else
		{
			$('object:has(param[name!="wmode"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
			$('object:has(param[name="wmode"][value="window"])').addClass('ObjPopUp_flash').css("visibility", "hidden");
			$("[src$='swf'][wmode!='opaque'][wmode!='transparent']").addClass('ObjPopUp_flash').css("visibility", "hidden");
		}

		// On ouvre l'iframe
		this.ouvre(contenu, configuration);

		// Si on calculer la taille automatiquement
		if (typeof(configuration.DimensionAuto) != "undefined" && configuration.DimensionAuto == true){
			// On place this dans le scope local pour y accéder dans la fonction TimeOut
			var self = this;

			// On attend 300 ms pour que l'iframe souvre en entier
			setTimeout(function() {
				// Au moment du load de l'élement ObjPopIframe, à savoir l'iframe
				$("#ObjPopIframe").bind("load", {self: self}, function(e) {
					// On prend la hauteur et la largeur du body de l'iframe, +20 pour etre large
					largeur = $('#ObjPopIframe')[0].contentWindow.$('body').width() + 20;
					hauteur = $('#ObjPopIframe')[0].contentWindow.$('body').height() + 20;

					// On redimensionne le popup avec ces valeurs
					e.data.self.redimensionne(hauteur, largeur);

					var selfCentre = e.data.self;

					// Au bout de 300 ms, on centre le popup, le temps qu'il s'affiche en entier
					setTimeout(function() {
						selfCentre.centre();
					}, 300);

					//if($.browser.msie){
					$('#ObjPopIframe')[0].contentWindow.$('body').bind('keydown', function(event) {
						if (event.keyCode == 27)
						{
							selfCentre.ferme();
							return false;
						}
					});
				});
			}, 300);
		}
	};

	/**
	 * ouverture du popup en affichant un flash
	 * @param url string
	 */
	this.ouvreFlash = function(url, configuration)
	{
		configuration = benchmark.framework.util.objet.fusion(
			configuration,
			{
				titre			: 'image',
				nom			: 'image',
				hauteur		: 300,
				largeur		: 300,
				style			: '',
				options		: '',
				id			: 'popup',
				backgroundColor	: '#ffffff',
				classe		: 'image_popup'
			}
		);
		
		this.modeOuverture = 'flash';

		this.ouvre(
			'<div id="conteneur_' + configuration.id + '" class="' + configuration.classe+'">'
			+ '<embed id="' + configuration.id + '" height="' + configuration.hauteur + '" width="' + configuration.largeur + '" quality="high" bgcolor="' + configuration.backgroundColor + '" '
			+ ' name="' + configuration.nom + '" style="' + configuration.style + '" src="' + url + '" type="application/x-shockwave-flash"/>'
			+ '</div>'
		);
	};

	/**
	 * ouverture du popup en affichant une image
	 * @param url string
	 */
	this.ouvreImage = function(url, configuration)
	{
		configuration = benchmark.framework.util.objet.fusion(
			configuration,
			{
				titre		: 'image',
				hauteur	: null,
				largeur	: null,
				alt		: 'image',
				classe	: 'image_popup',
				style		: '',
				options	: '',
				id		: null
			}
		);
		
		this.modeOuverture = 'image';
		
		this.ouvre(
			'<img id="' + configuration.id + '" src="' + url + '" title="' + configuration.titre + '" '
			+ ' alt="' + configuration.alt + '" class="' + configuration.classe + '"'
			+ ' style="width:' + configuration.largeur + 'px; height:' + configuration.hauteur + 'px; ' + configuration.style + '"'
			+ ' ' + configuration.options + '>'
		);
	};

 	/**
 	 * configure l'objet en réattribuant les valeurs par defaut négligées à l'objet de configuration :
 	 * @return void
 	 */
	this.configure = function()
	{
		this.configuration = benchmark.framework.util.objet.fusion(this.configuration, this.configurationDefaut);
	};


	
 	/**
 	* Ajoute du HTML au début ou à la fin du bloc contenu
 	* @return void
 	* @since 25/11/2008 Thomas JOBERT
 	*/	
	this.ajouteHTML = function(message,position) {
		
			if (position == 'debut') {
				$('#ObjPopupContenu').prepend(message);
			} else if (position == 'fin') {
				$('#ObjPopupContenu').append(message);
			}
	};

	/**
	 * constructeur :
	 */
 	// on recupere les arguments :
	this.configuration = configuration || {};
	this.configure();
};