/*
 * fonction malert
 * Gestionnaire d'alerte
 *
 * Basé sur jQuery
 *
 * Copyright 2010, Jérôme Engeln
 *
 * Depend de :
 *		me_ajax.js
 * 
 * Date: 31/12/2010 - 17h00
 */

(function( $, undefined ) {

	var ua = navigator.userAgent;
	var isSmartPhone = /iPad/i.test(ua) || /iPhone OS 3_1_2/i.test(ua) || /iPhone OS 3_2_2/i.test(ua);

	$.fn.malert = function(message, options, callback) {
	
		// Si un appel au dialog est fait lorsqu'un autre est déjà ouvert, on le met en attente d'execution (idem fonctionnement alert classique)
		if($me.globals.dialog.open == 1) {
			me.queuingDialog("alert", message, options, callback);
			return false;
		}
		// Si on passe le callback dans le 2ème paramètre de la fonction
		if(jQuery.isFunction(options) && !callback && !jQuery.isPlainObject(options)) {
			callback = options;
		}
		// Aucune option locale n'est passée en paramètres, on initialise les options avec les options définies au niveau global
		if(!options) {
			// objet vide ou configuré
			options =  $me.options.alert; 
		} 
		// Si des options locales sont communiquées et que les options globales sont configurées, on ajoute les options globales manquantes aux options locales
		// Les options locales surchargent ainsi les options globales
		else if(jQuery.isPlainObject($me.options.alert)) {
			for ( name in $me.options.alert ) {
				if(!options[name]) {
					options[name] = $me.options.alert[name];
				}
			}
		}
		// Si le message n'est pas passé en paramètre, il peut être dans le selector !
		if(typeof this.selector == "string" && ( message == undefined || !message)) {
			message = this.selector;
		}
		// Déclaration des variables
		var self = this,
			options = {
				dialogClass:		options.dialogClass != undefined ?options.dialogClass:			"me-alert",
				textClass:			options.textClass != undefined ?options.textClass:				"me-alert-text",
				titleClass:			options.titleClass != undefined ?options.titleClass:			"me-alert-title",
				overlayClass:		options.overlayClass != undefined ?options.overlayClass:		"me-alert-overlay",
				closeClass:			options.closeClass != undefined ?options.closeClass:			"me-alert-close",
				closeSpanClass:		options.closeSpanClass != undefined ?options.closeSpanClass:	"me-alert-close-text",
				buttonsClass:		options.buttonsClass != undefined ?options.buttonsClass:		"me-alert-buttons",
				buttonOkClass:		options.buttonOkClass != undefined ?options.buttonOkClass:		"me-alert-button-ok",
				usetitle:			options.usetitle != undefined ?options.usetitle:				true,
				zIndex:				options.zIndex != undefined ?options.zIndex:					1000,
				width:				options.width != undefined ?options.width:						'auto',
				height:				options.height != undefined ?options.height:					'auto',
				minwidth:			options.minwidth != undefined ?options.minwidth:				300,
				minheight:			options.minheight != undefined ?options.minheight:				20,
				overlay:			options.overlay != undefined ?options.overlay:					true,
				shakeit:			options.shakeit != undefined ?options.shakeit:					true,
				forceValidation:	options.forceValidation != undefined ?options.forceValidation:	true,
				shakedirection:		options.shakedirection != undefined ?options.shakedirection:	'left',
				defaultContent:		options.defaultContent != undefined ?options.defaultContent:	"Ceci est le message d'alerte par défaut !",
				title:				options.title != undefined ?options.title:						"Message d'alerte :",
				fadein:				options.fadein != undefined ?options.fadein:					50,
				overlayfadein:		options.overlayfadein != undefined ?options.overlayfadein:		50,
				fadeout:			options.fadeout != undefined ?options.fadeout:					50,
				overlayfadeout:		options.overlayfadeout != undefined ?options.overlayfadeout:	50,
				overlayOpacity:		options.overlayOpacity != undefined ?options.overlayOpacity:	0.7,
				overlayCloseOnClick:		options.overlayCloseOnClick != undefined ?options.overlayCloseOnClick:	true,
				libelleClose:		options.libelleClose != undefined ?options.libelleClose:		"Fermer",
				libelleOk:			options.libelleOk != undefined ?options.libelleOk:				"Ok"
			};
		// On bloque le clic sur IE6 car problème d'opacité sur l'overlay !
		if(options.overlay && $.browser.msie && $.browser.version < 7) {
			$(document).click( function() {
				return false;
			});
		}
		// On ajoute la div de l'alerte
		var	meAlertDialog = (self.meAlertDialog = $('<div></div>'))
				.appendTo(document.body)
				.hide()
				.addClass(options.dialogClass)
				.css({
					zIndex: options.zIndex,
					position: "relative",
					// Pour IE6 => Sinon la largeur se met à 100% de la fenetre
					float: "left",
					display: "none",
					top : 0,
					left : 0
				}),
			// On ajoute le layer du titre si un titre est paramétré
			meAlertTitre = ((options.usetitle)?
					((self.meAlertTitre = $('<div></div>'))
						.appendTo(meAlertDialog)
						.addClass(options.titleClass)
						.css({	
							position: "relative",
							// Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left"
						})
						.html( options.title ))
					: null
				),
			// On ajoute le lien de fermeture de la fenêtre
			meAlertClose = (self.meAlertClose = $('<a href="#" ></a>'))
				.appendTo(meAlertDialog)
				.addClass(options.closeClass)
				.css({
					zIndexClose: (options.zIndex+1),
					position: "absolute"
				})
				.click(function() {
					close();
					return false;
				}),
			// Ajout du texte dans le lien
			meAlertCloseText = (self.meAlertCloseText = $('<span></span>'))
				.addClass(options.closeSpanClass)
				.text(options.libelleClose)
				.appendTo(meAlertClose),				
			// On ajoute le layer du message
			meAlertText = (self.meAlertText = $('<div></div>'))
				.appendTo(meAlertDialog)
				.addClass(options.textClass)
				.css({	
					position: "relative",
					// Pour IE6 => Sinon la largeur se met à 100% de la fenetre
					float: "left"
				})
				.html( ((message != "")?message:options.defaultContent) ),
			meDocOverlay = (( options.overlay )?
					((self.meDocOverlay = $('<div></div>'))
					.appendTo(document.body)
					.hide()
					.addClass(options.overlayClass)
					.css({
						position : "absolute",
						zIndex: (options.zIndex-1),
						top: 0,
						left: 0,
						width: 0,
						height: 0
					})
					.click( function() {
						if(options.forceValidation) {
							if(options.shakeit) {
								shakeitonthefloor();
							} else {
								return false;
							}
						} else {
							if(options.overlayCloseOnClick)	close();
						}
					})) : null	
				),
			meAlertButtons = (( options.forceValidation )?
					((self.meAlertButtons = $('<div></div>'))
					.appendTo(meAlertDialog)
					.addClass(options.buttonsClass)
					.css({	
							position: "relative",
							 // Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left"
					})) : null	
				),
			meAlertButtonOk = (( options.forceValidation && meAlertButtons && options.libelleOk != "" )?
					((self.meAlertButtonOk = $('<span></span>'))
					.appendTo(meAlertButtons)
					.addClass(options.buttonOkClass)
					.css({	
							position: "relative",
							 // Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left",
							margin: "auto",
							textAlign: "center",
							cursor: "pointer"
					})
					.html(options.libelleOk)
					.click( function() {
						close();
					})) : null	
				),
				
			// Fonction de fermeture de la fenêtre
			close = function() {
				meAlertDialog.fadeOut(options.fadeout, function() {
					self.meAlertDialog.remove();
					if(options.overlay) {
						self.meDocOverlay.fadeOut(options.overlayfadeout, function() {
							self.meDocOverlay.remove();	
						});
					}
					// On détruit les évènements à la fermeture le fenetre
					jQuery( window ).trigger( "resize" ).unbind( "resize" );
					jQuery( window ).trigger( "scroll" ).unbind( "scroll" );
					if(options.overlay && $.browser.msie && $.browser.version < 7) {
						jQuery( document ).trigger( "click" ).unbind( "click" );
					}
					// Le dialog est fermé
					$me.globals.dialog.open = 0;
					me.globals.alert.l = null;
					me.globals.alert.h = null;
					// On appelle la fonction de retour
					if(jQuery.isFunction(callback)) {
						callback.call(arguments);
					}
					// On appelle la prochain dialog mis en en attente !
					var oqueue = new Array();
					var execDialog = null;
					for(var queue in me.globals.dialog.queue) {
						if(jQuery.isFunction(me.globals.dialog.queue[queue]) && queue == 0) {
							execDialog = me.globals.dialog.queue[queue];
						} else {
							oqueue.push(me.globals.dialog.queue[queue]);
						}
					}
					if($me.globals.dialog.open == 0) {
						me.globals.dialog.queue = oqueue;
						if (jQuery.isFunction(execDialog)) {
							execDialog.call(arguments);
						}
					}
				});
			},
			// Fonction d'ouverture : Calcul la largeur et la hauteur du message d'alerte pour le positionne au centre de la page
			open = function(noeffect) {
				// Le dialog est ouvert
				$me.globals.dialog.open = 1;
				// On récupère la largeur et la hauteur du layer alerte
				if(!me.globals.alert.h) {
					self.meAlertDialog.show();
					var h = self.meAlertDialog.css({
						width: options.width,
						height: options.height
					}).height();
					self.meAlertDialog.css({width: h+"px" });
					if(h < options.minheight) {
						h = options.minheight; 
						self.meAlertDialog.css({height: options.minheight });
					}
					me.globals.alert.h = h;
					self.meAlertDialog.hide();
				} else {
					var h = me.globals.alert.h;
				}
				if(!me.globals.alert.l) {
					self.meAlertDialog.show();
					var l = self.meAlertDialog.css({
						width: options.width,
						height: options.height
					}).width();
					self.meAlertDialog.css({width: l+"px" });
					if(l < options.minwidth) {
						l = options.minwidth; 
						self.meAlertDialog.css({width: options.minwidth+"px" });
					}
					me.globals.alert.l = l;
					self.meAlertDialog.hide();
				} else {
					var l = me.globals.alert.l;
				}
				// On place le layer au milieu de la fenetre
				position(l, h, noeffect);
			},
			// Fonction de positionnement au centre de la page
			position = function(l, h, noeffect) {
				var win = $(window);
				var doc = $(document);
				var left = ( (win.width()/2) + doc.scrollLeft() ) - (l/2);
				if(win.height() < doc.height()) {
					left = left - 12;
				}
				var top = ( (win.height()/2) + doc.scrollTop() ) - (h/2);
				if(win.width() < doc.width()) {
					top = top - 14;
				}
				self.meAlertDialog.css({ top: top, left: left, position: 'absolute', float: 'none' });
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				self.meAlertText.css({
					float: "none"
				});
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meAlertTitre) {
					self.meAlertTitre.css({
						float: "none"
					});
				}
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meAlertButtons) {
					self.meAlertButtons.css({
						float: "none"
					});
				}
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meAlertButtonOk) {
					self.meAlertButtonOk.css({
						float: "none"
					});
				}
				// Dans le cas normal, on fait apparaitre le dialog
				if(!noeffect) {
					self.meAlertDialog.fadeIn(options.fadein);
				} 
				// Sinon on l'affiche directement
				else {
					self.meAlertDialog.show();
				}
				// On calle l'overlay
				if(options.overlay) {
					//self.meDocOverlay.css({ width: (win.width() + doc.scrollLeft()), height: (win.height() + doc.scrollTop()) });
					self.meDocOverlay.css({ width: (doc.width() ), height: (doc.height()) });
					if(!noeffect) {
						self.meDocOverlay.fadeIn(options.overlayfadein);
					} else {
						self.meAlertDialog.show();
					}
				}
				// Doit-on secouer le tout ?
				if(options.shakeit && !noeffect) {
					shakeitonthefloor();
				}
			},
			shakeitonthefloor = function() {
				// On lance un vibrato sur la fenetre
				if(options.shakedirection == 'top') {
					$(self.meAlertDialog)
						.animate({ top: '-=15' }, 60, function() { $(self.meAlertDialog)
						.animate({ top: '+=30' }, 60, function() { $(self.meAlertDialog)
						.animate({ top: '-=15' }, 60, function() {	$(self.meAlertDialog)
						.animate({ top: '-=5'  }, 60, function() { $(self.meAlertDialog)
						.animate({ top: '+=5'  }, 60); }); }); }); });
				} else {
					$(self.meAlertDialog)
						.animate({ left: '-=20' }, 60, function() { $(self.meAlertDialog)
						.animate({ left: '+=40' }, 60, function() { $(self.meAlertDialog)
						.animate({ left: '-=20'	}, 60, function() {	$(self.meAlertDialog)
						.animate({ left: '-=10' }, 60, function() { $(self.meAlertDialog)
						.animate({ left: '+=10' }, 60); }); }); }); });
				}
			};
		
		if( (!$.browser.msie || ( $.browser.msie && $.browser.version >= 7 ) ) && options.overlay ) {
			meDocOverlay.css({ opacity: options.overlayOpacity });
		} else if ($.browser.msie && $.browser.version < 7 && options.overlay) {
			// Sur IE 6 on désactive le background sur l'overlay
			meDocOverlay.css({ background: "none" });
		}

		// On affiche l'alerte
		open();

		// Evenement resize sur la fenetre
		$(window).resize( function() { 
			if(!isSmartPhone) {
				open(true);
			}
		});
		// Repositionnement de la fenêtre au scroll
		$(window).scroll( function() {
			if(!isSmartPhone) {
				open(true);
			}
		});

		// On sauvegarde les params de la fenêtre ouverte
		me.paramsDialogOpen("alert", message, options, callback, meAlertDialog, meDocOverlay);

	};

	$.fn.malertclose = function(message, options, callback, meAlertDialog, meDocOverlay) {

		var self = this,
			// Fonction de fermeture de la fenêtre
			close = function() {
				if($me.globals.dialog.open == 0) return false;
				meAlertDialog.fadeOut(options.fadeout, function() {
					meAlertDialog.remove();
					if(options.overlay) {
						meDocOverlay.fadeOut(options.overlayfadeout, function() {
							meDocOverlay.remove();	
						});
					}
					// On détruit les évènements à la fermeture le fenetre
					jQuery( window ).trigger( "resize" ).unbind( "resize" );
					jQuery( window ).trigger( "scroll" ).unbind( "scroll" );
					if(options.overlay && $.browser.msie && $.browser.version < 7) {
						jQuery( document ).trigger( "click" ).unbind( "click" );
					}
					// Le dialog est fermé
					$me.globals.dialog.open = 0;
					me.globals.alert.l = null;
					me.globals.alert.h = null;
					// On appelle la fonction de retour
					if(jQuery.isFunction(callback)) {
						callback.call(arguments);
					}
					// On appelle la prochain dialog mis en en attente !
					var oqueue = new Array();
					var execDialog = null;
					for(var queue in me.globals.dialog.queue) {
						if(jQuery.isFunction(me.globals.dialog.queue[queue]) && queue == 0) {
							execDialog = me.globals.dialog.queue[queue];
						} else {
							oqueue.push(me.globals.dialog.queue[queue]);
						}
					}
					if($me.globals.dialog.open == 0) {
						me.globals.dialog.queue = oqueue;
						if (jQuery.isFunction(execDialog)) {
							execDialog.call(arguments);
						}
					}
				});
			};
		close();

	};

}(jQuery));
