/*
 * fonction mconfirm
 * Gestionnaire d'confirme
 *
 * Basé sur jQuery
 *
 * Copyright 2010, Jérôme Engeln
 *
 * Depend de :
 *		me_ajax.js
 * 
 * Date: 31/12/2010 - 17h00
 */

(function( $, undefined ) {

	$.fn.mconfirm = 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 confirm classique)
		if($me.globals.dialog.open == 1) {
			me.queuingDialog("confirm", 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.confirm;
		} 
		// 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.confirm)) {
			for ( name in $me.options.confirm ) {
				if(!options[name]) {
					options[name] = $me.options.confirm[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-confirm",
				textClass:			options.textClass != undefined ?options.textClass:					"me-confirm-text",
				titleClass:			options.titleClass != undefined ?options.titleClass:				"me-confirm-title",
				overlayClass:		options.overlayClass != undefined ?options.overlayClass:			"me-confirm-overlay",
				closeClass:			options.closeClass != undefined ?options.closeClass:				"me-confirm-close",
				closeSpanClass:		options.closeSpanClass != undefined ?options.closeSpanClass:		"me-confirm-close-text",
				buttonsClass:		options.buttonsClass != undefined ?options.buttonsClass:			"me-confirm-buttons",
				buttonOkClass:		options.buttonOkClass != undefined ?options.buttonOkClass:			"me-confirm-button-ok",
				buttonCancelClass:	options.buttonCancelClass != undefined ?options.buttonCancelClass:	"me-confirm-button-cancel",
				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:		'top',
				defaultContent:		options.defaultContent != undefined ?options.defaultContent:		"Ceci est un message de confirmation par défaut !",
				title:				options.title != undefined ?options.title:							"?",
				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,
				libelleClose:		options.libelleClose != undefined ?options.libelleClose:			"Fermer",
				libelleOk:			options.libelleOk != undefined ?options.libelleOk:					"Ok",
				libelleCancel:		options.libelleCancel != undefined ?options.libelleCancel:			"Annuler"
			};
		// 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'confirme
		var	meConfirmDialog = (self.meConfirmDialog = $('<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é
			meConfirmTitre = ((options.usetitle)?
					((self.meConfirmTitre = $('<div></div>'))
						.appendTo(meConfirmDialog)
						.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
			meConfirmClose = (self.meConfirmClose = $('<a href="#" ></a>'))
				.appendTo(meConfirmDialog)
				.addClass(options.closeClass)
				.css({
					zIndexClose: (options.zIndex+1),
					position: "absolute"
				})
				.click(function() {
					close();
					return false;
				}),
			// Ajout du texte dans le lien
			meConfirmCloseText = (self.meConfirmCloseText = $('<span></span>'))
				.addClass(options.closeSpanClass)
				.text(options.libelleClose)
				.appendTo(meConfirmClose),				
			// On ajoute le layer du message
			meConfirmText = (self.meConfirmText = $('<div></div>'))
				.appendTo(meConfirmDialog)
				.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 {
							self.confirm = false;
							close();
							return false;
						}
					})) : null	
				),
			meConfirmButtons = (( options.forceValidation )?
					((self.meConfirmButtons = $('<div></div>'))
					.appendTo(meConfirmDialog)
					.addClass(options.buttonsClass)
					.css({	
							position: "relative",
							 // Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left"
					})) : null	
				),
			meConfirmButtonOk = (( options.forceValidation && meConfirmButtons )?
					((self.meConfirmButtonOk = $('<span></span>'))
					.appendTo(meConfirmButtons)
					.addClass(options.buttonOkClass)
					.css({	
							position: "relative",
							 // Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left",
							textAlign: "center",
							cursor: "pointer"
					})
					.html(options.libelleOk)
					.click( function() {
						self.confirm = true;
						close();
						return true;
					})) : null	
				),
			meConfirmButtonCancel = (( options.forceValidation && meConfirmButtons )?
					((self.meConfirmButtonCancel = $('<span></span>'))
					.appendTo(meConfirmButtons)
					.addClass(options.buttonCancelClass)
					.css({	
							position: "relative",
							 // Pour IE6 => Sinon la largeur se met à 100% de la fenetre
							float: "left",
							textAlign: "center",
							cursor: "pointer"
					})
					.html(options.libelleCancel)
					.click( function() {
						self.confirm = false;
						close();
						return false;
					})) : null	
				),
			// Fonction de fermeture de la fenêtre
			close = function() {
				meConfirmDialog.fadeOut(options.fadeout, function() {
					self.meConfirmDialog.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.confirm.l = null;
					me.globals.confirm.h = null;
					// On appelle la fonction de retour
					if(jQuery.isFunction(callback)) {
						callback.call(self);
					}
					// 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'confirme 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 confirme
				if(!me.globals.confirm.h) {
					self.meConfirmDialog.show();
					var h = self.meConfirmDialog.css({
						width: options.width,
						height: options.height
					}).innerHeight();
					self.meConfirmDialog.css({width: h+"px" });
					if(h < options.minheight) {
						h = options.minheight; 
						self.meConfirmDialog.css({height: options.minheight });
					}
					me.globals.confirm.h = h;
					self.meConfirmDialog.hide();
				} else {
					var h = me.globals.confirm.h;
				}
				if(!me.globals.confirm.l) {
					self.meConfirmDialog.show();
					var l = self.meConfirmDialog.css({
						width: options.width,
						height: options.height
					}).innerWidth();
					self.meConfirmDialog.css({width: l+"px" });
					if(l < options.minwidth) {
						l = options.minwidth; 
						self.meConfirmDialog.css({width: options.minwidth+"px" });
					}
					me.globals.confirm.l = l;
					self.meConfirmDialog.hide();
				} else {
					var l = me.globals.confirm.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.meConfirmDialog.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.meConfirmText.css({
					float: "none"
				});
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meConfirmTitre) {
					self.meConfirmTitre.css({
						float: "none"
					});
				}
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meConfirmButtons) {
					self.meConfirmButtons.css({
						float: "none"
					});
				}
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meConfirmButtonOk) {
					self.meConfirmButtonOk.css({
						float: "none"
					});
				}
				// Pour IE6 => Après récupération de la taille du contenu du dialog, on enlève les floats
				if(self.meConfirmButtonCancel) {
					self.meConfirmButtonCancel.css({
						float: "none"
					});
				}
				// Dans le cas normal, on fait apparaitre le dialog
				if(!noeffect) {
					self.meConfirmDialog.fadeIn(options.fadein);
				} 
				// Sinon on l'affiche directement
				else {
					self.meConfirmDialog.show();
				}
				// On calle l'overlay
				if(options.overlay) {
					self.meDocOverlay.css({ width: (win.width() + doc.scrollLeft()), height: (win.height() + doc.scrollTop()) });
					if(!noeffect) {
						self.meDocOverlay.fadeIn(options.overlayfadein);
					} else {
						self.meConfirmDialog.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.meConfirmDialog)
						.animate({ top: '-=15' }, 60, function() { $(self.meConfirmDialog)
						.animate({ top: '+=30' }, 60, function() { $(self.meConfirmDialog)
						.animate({ top: '-=15' }, 60, function() {	$(self.meConfirmDialog)
						.animate({ top: '-=5'  }, 60, function() { $(self.meConfirmDialog)
						.animate({ top: '+=5'  }, 60); }); }); }); });
				} else {
					$(self.meConfirmDialog)
						.animate({ left: '-=20' }, 60, function() { $(self.meConfirmDialog)
						.animate({ left: '+=40' }, 60, function() { $(self.meConfirmDialog)
						.animate({ left: '-=20'	}, 60, function() {	$(self.meConfirmDialog)
						.animate({ left: '-=10' }, 60, function() { $(self.meConfirmDialog)
						.animate({ left: '+=10' }, 60); }); }); }); });
				}
			},
			confirm = self.confirm = false;
		
		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'confirme
		open();

		// Evenement resize sur la fenetre
		$(window).resize( function() { 
			open(true);
		});
		// Repositionnement de la fenêtre au scroll
		$(window).scroll( function() {
			open(true);
		});

		return true;

	};

	$.fn.mconfirmclose = function(message, options, callback, meAlertDialog, meDocOverlay) {

		var self = this,
			// Fonction de fermeture de la fenêtre
			close = function() {
				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));
