// JavaScript Document

function debugObject($object) {
	var $i;
	var $str = 'Object : ' + $object;
	for($i in $object) {
		$str += '\n' + $i + ' => ' + $object[$i];
	}
	alert($str);
}

var easyForm = {
	// Valeurs par défaut pour les infobulles (doit TOUJOURS etre une chaine, meme pour les entiers...)
	toolTipDefaultOpts : {
		position : 'right',	// Position = top, left, bottom, right
		delayIn  : '0',		// Attente avant apparition	= X millisecs
		delayOut : '0',		// Attente avant disparition = X millisecs
		fadeIn   : '100',	// Durée d'apparition = X millisec
		fadeOut  : '100'	// Durée de disparition = X millisec
	},
	// Initialisation de tout les formulaire compatibles
	init : function() {
		// Initialisation
		easyForm.initForm('form.easyForm');
	},
	// Initialisation de formulaire précis
	initForm : function($selector) {
		// Variables
		var $form = jQuery($selector);
		var $fieldList = $form.find('input, textarea, select');
		var $i, $count, $field, $toolTip, $toolTipItem, $data, $opt;
		// Application des callback
		$fieldList.blur(easyForm.blur).focus(easyForm.focus).addClass('easyFormBlured');
		$fieldList.filter('input, textarea').bind('keyup', easyForm.checkFieldCallback);
		$fieldList.filter('select').bind('change', easyForm.checkFieldCallback);
		$form.submit(easyForm.checkFormCallback);
		// Création de toutes les infobulles
		$count = $fieldList.size();
		for($i = 0; $i < $count; $i++) {
			$field = $fieldList.eq($i);
			// Chargement données
			$data = {
				toolTipId : $i,
				classList : easyForm.getClassList($field)
			};
			$field.data('easyForm', $data);
			// Recuperation des options d'affichage
			if (typeof($data.classList['easyFormToolTipOpts']) == 'object') $toolTip = $data.classList['easyFormToolTipOpts'];
			else $toolTip = easyForm.toolTipDefaultOpts;
			// Utilisation des valeurs par defaut si aucune valeur existante
			for($opt in easyForm.toolTipDefaultOpts) {
				if (typeof($toolTip[$opt]) != 'string') $toolTip[$opt] = easyForm.toolTipDefaultOpts[$opt];
			}
			// Creation
			$toolTipItem = jQuery('<div class="easyFormToolTip"></div>');
			$toolTipItem.css('opacity', 0).appendTo(document.body).show();
			// Ajout de la classe pour le positionnement
			switch($toolTip.position.toLowerCase()) {
				case 'top'    : $toolTipItem.addClass('easyFormToolTipTop'); break;
				case 'bottom' : $toolTipItem.addClass('easyFormToolTipBottom'); break;
				case 'left'   : $toolTipItem.addClass('easyFormToolTipLeft'); break;
				case 'right'  : 
				default       : $toolTipItem.addClass('easyFormToolTipRight'); break;
			}
			// Stockage
			$toolTip.item = $toolTipItem;
			easyForm.toolTipList[$i] = $toolTip;
			easyForm.toolTipUpdate($field);
		}
		// Retour
		return $form;
	},
	// Update d'un toolTip
	toolTipSetContent : function($node, $textList) {
		// Variables
		var $toolTipId = $node.data('easyForm').toolTipId;
		var $toolTip = easyForm.toolTipList[$toolTipId];
		var $html = jQuery('<div/>');
		var $i;
		// Mise à jour du texte
		for($i in $textList) $html.append('<span>' + $textList[$i] + '</span>');
		$toolTip.item.html($html);
	},
	toolTipUpdate : function($node) {
		// Variables
		var $toolTipId = $node.data('easyForm').toolTipId;
		var $toolTip = easyForm.toolTipList[$toolTipId];

		var $bodyTop = jQuery(document.body).offset().top;
		var $bodyLeft = jQuery(document.body).offset().left;
		var $nodeTop = $node.offset().top;
		var $nodeLeft = $node.offset().left;
		var $nodeWidth = $node.outerWidth(true);
		var $nodeHeight = $node.outerHeight(true);
		var $toolTipWidth = $toolTip.item.outerWidth(true);
		var $toolTipHeight = $toolTip.item.outerHeight(true);
		// Positionnement
		switch($toolTip.position.toLowerCase()) {
		case 'top'    :  
			$toolTip.item.css({
				top : $nodeTop - $toolTipHeight,
				left : $nodeLeft + ($nodeWidth - $toolTipWidth) / 2
			});
			break;
		case 'bottom' : 
			$toolTip.item.css({
				top : $nodeTop + $nodeHeight,
				left : $nodeLeft + ($nodeWidth - $toolTipWidth) / 2
			});
			break;
		case 'left'   :
			$toolTip.item.css({
				top : $nodeTop + ($nodeHeight - $toolTipHeight) / 2,
				left : $nodeLeft - $toolTipWidth
			});
			break;
		case 'right'  :
			$toolTip.item.css({
				top : $nodeTop + ($nodeHeight - $toolTipHeight) / 2,
				left : $nodeLeft + $nodeWidth
			});
			break;
		}
	},
	toolTipShow : function($node) {
		// Variables
		var $toolTipId = $node.data('easyForm').toolTipId;
		var $toolTip = easyForm.toolTipList[$toolTipId];
		// On stop les effets en cours, ajoute une pause si besoin, et on requeue l'effet
		$toolTip.item.stop(true);
		$toolTip.item.animate({fakeDelay : 1}, 1 * $toolTip.delayIn, function(){ jQuery(this).show(); });
		$toolTip.item.animate({opacity : 1}, 1 * $toolTip.fadeIn);
		return true;
	},
	toolTipHide : function($node) {
		// Variables
		var $toolTipId = $node.data('easyForm').toolTipId;
		var $toolTip = easyForm.toolTipList[$toolTipId];
		// On stop les effets en cours, ajoute une pause si besoin, et on requeue l'effet
		$toolTip.item.stop(true);
		$toolTip.item.animate({fakeDelay : 1}, 1 * $toolTip.delayOut);
		$toolTip.item.animate({opacity : 0}, 1 * $toolTip.fadeOut, function(){ jQuery(this).hide(); });
		return true;
	},
	// Fonctions de vérification de champs
	checkFieldCallback : function(event) {
		// Variables
		var $node = jQuery(this);
		// Pas de verification sur les champs vides
		if ($node.val() == '') return easyForm.toolTipHide($node);
		// Recuperation de la validité du champ
		var $status = easyForm.checkField(this);
		// Valide, on cache le tooltip
		if ($status.valid) return easyForm.toolTipHide($node);
		// Affichage des messages d'erreur
		easyForm.toolTipSetContent($node, $status.error);
		easyForm.toolTipUpdate($node);
		easyForm.toolTipShow($node);
	},
	checkField : function($selector) {
		// Variables
		var $node = jQuery($selector);
		var $value = $node.val();
		var $checked = false;
		var $isValid = true;
		var $errorList = [];
		var $classList;
		var $class;
		var $temp;
		// Si le champ n'est pas vide et faculatif, on va le check
		if ($value != '' || !$node.hasClass('easyFormOptional')) {
			// Sinon on va effectuer un check complet dessus
			$classList = $node.data('easyForm').classList;
			// Checks
			for($class in $classList) {
				if (typeof(easyForm.type[$class]) == 'object') {
					// Recuperation du resultat du check
					$temp = easyForm.type[$class].method($value, $classList[$class]);
					// Si erreur, on stocke le message
					if (!$temp) {
						if (typeof(easyForm.type[$class].message) == 'string') $errorList.push(easyForm.type[$class].message);
						else $errorList.push(easyForm.type[$class].message($classList[$class]));
					}
					// Et mise à jour
					$isValid = $isValid && $temp;
					$checked = true;
				}
			}
			// Si le champ a subit au moins une verification
			if ($checked) {
				// On change sa classe selon sa validité
				if ($isValid) {
					$node.removeClass('easyFormError');
					$node.addClass('easyFormSuccess');			
				} else {
					$node.removeClass('easyFormSuccess');
					$node.addClass('easyFormError');			
				}
			}
		}
		// On renvoit le status, et les eventuels messages d'erreur
		return { valid : $isValid, error : $errorList };
	},
	// Fonctions de vérification de formulaire
	checkFormCallback : function(event) {
		// Variables
		var $field;
		var $errorMsg = '';
		// SI le fomulaire n'est pas valide, on ne submit pas, et on affiche l'erreur
		if (!easyForm.checkForm(this)) {
			event.preventDefault();
			$errorMsg += 'Le(s) champ(s) suivants sont incorrect(s) :';
			for($field in easyForm.lastError) $errorMsg += '\n - ' + $field;
			alert($errorMsg);
		}
	},
	checkForm : function($formSelector) {
		// Variables
		var $form = jQuery($formSelector);
		var $fieldList = $form.find('input, select, textarea');
		var $size = $fieldList.size();
		var $isValid = true;
		var $fieldDescr;
		var $counter;
		var $status;
		var $field;
		// Check du formulaire
		easyForm.lastError = [];
		for($counter = 0; $counter < $size; $counter++) {
			// On check chacun des champs
			$field = $fieldList.eq($counter);
			$status = easyForm.checkField($field, false);
			// Si erreur, on la stocke
			if (!$status.valid) {
				$fieldDescr = $field.attr('title');
				if ($fieldDescr == '') $fieldDescr = $field.attr('name');
				if ($fieldDescr == '') $fieldDescr = 'Champ n°' + ($counter + 1)
				easyForm.lastError[$fieldDescr] = $status.error;
			}
			$isValid = $isValid && $status.valid;
		}
		// On retourne l'état du formulaire
		return $isValid;
	},
	// Recuperation de la liste des classes et des arguments d'un champ
	getClassList : function($node) {
		// Variables
		var $i, $temp, $class, $args;
		var $classes = jQuery.trim($node.attr('class')).split(/[^a-zA-Z0-9_.:-]+/);
		var $classList = {};
		// Parcours des classes
		for(var $i in $classes) {
			// Separation du nom de la classe de ses eventuels arguments
			$class = $classes[$i];
			$temp = $class.split(/:/);
			$class = $temp[0];
			$temp.shift();
			// Recuperation de la liste des arguments
			$args = {};
			for(var $j in $temp) {
				// Separation nom/valeur dde l'argument, et stockage
				$arg = ($temp[$j] + '.').split(/\./);
				$args[$arg[0]] = $arg[1];				
			}
			// Stockage si il s'agit d'une methode de test
			$classList[$class] = $args;
		}
		// On renvoie le tout
		return $classList;
	},	
	// Event onBlur
	blur : function() {
		var $node = jQuery(this);
		$node.removeClass('easyFormFocused easyFormSuccess');
		$node.addClass('easyFormBlured');
		easyForm.toolTipHide($node);
	},
	// Event onFocus
	focus : function() {
		var $node = jQuery(this);
		$node.removeClass('easyFormBlured');
		$node.addClass('easyFormFocused');
		$node.trigger('keyup');
	},
	// Permet d'ajouter un nouveau type de check
	register : function($name, $function, $message) {
		if (typeof($function) != 'function') return false;
		if (typeof($message) != 'function' && typeof($message) != 'string') return false;
		easyForm.type[$name] = {
			method : $function,
			message : $message
		};
	},
	// Liste des infoBulles
	toolTipList : {},
	// Pour le stockage des erreurs
	lastError : {},
	// Liste de méthodes de verification
	type : {},
	// Rend les animations flash de la page transparente, pour éviter que les bulles ne passent "derriere" (fonctionne très mal, voir pas du tout)
	fixTransparentFlash : function() {
		// Listing des animations flash
		var $object = jQuery('object[classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"]');
		var $i, $wmode, $embed;
		// Parcours des flash
		for($i = 0; $i < $object.size(); $i++) {
			// Changement du wmode (balise param)
			$wmode = $object.eq($i).find('param[name=wmode]');
			if ($wmode.size() == 0) $wmode = jQuery('<param name="wmode" value="transparent">').appendTo($object.eq($i));
			$wmode.attr('value', 'transparent');
			// Changement du wmode (balise object)
			$embed = $object.eq($i).find('embed');
			$embed.attr('wmode', 'transparent');
		}
	}
};



/********************************************************
 *                                                      *
 * Inscription des differentes methodes de verification *
 *                                                      *
 ********************************************************/
// Champ obligatoire
easyForm.register('easyFormMandatory',
	function($val) { return $val.match(/./); },
	'Ce champ est obligatoire.'
);

// Champ numerique
easyForm.register( 'easyFormNum',
	function($val) { return $val.match(/^[0-9]+$/); },
	'Vous ne pouvez utiliser que des chiffres.'
);

// Champ Alpha
easyForm.register('easyFormAlpha',
	function($val) { return $val.match(/^[a-zA-Z. .'.-.ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ]+$/); },
	'Vous ne pouvez utiliser que des lettres.'
);

// Champ AlphaNum
easyForm.register('easyFormAlphaNum',
	function($val) { return $val.match(/^[a-zA-Z0-9]+$/); },
	'Vous ne pouvez utiliser que des chiffres et des lettres.'
);

// Champ Mail
easyForm.register('easyFormMail',
	function($val) { return $val.match(/^[a-zA-Z][a-zA-Z0-9_.+]{2,19}@[a-zA-Z][a-zA-Z0-9.-]+\.[a-z]{2,4}$/); },
	'Cette adresse n\'est pas une adresse email valide.'
);

// Adresse internet
easyForm.register('easyFormUrl',
	function($val) { return $val.match(/^https?:\/\/[a-zA-Z][a-zA-Z0-9.-]{2,}\.[a-z]{2,4}(\/[a-zA-Z0-9_.+\/]+)?$/); },
	'L\'adresse internet doit être de type "http://www.nomdedomaine.extension"'
);

// Date
easyForm.register('easyFormDate',
	function($val) { return $val.match(/^[0-9][0-9]?\/[0-9][0-9]?\/[0-9]{4}$/); },
	'La date doit être présentée dans le format jj/mm/aaaa'
);

// Telephone / Fax
easyForm.register('easyFormTel',
	function($val) { return $val.match(/^(\+3[0-9]|0)[0-9]{9}$/); },
	'Ce numéro de téléphone n\'est pas valide.'
);

// Limite de taille
easyForm.register('easyFormSize',
	function($val, $args) {
		if (typeof($args.fixed) == 'string') {
			$args.min = $args.fixed;
			$args.max = $args.fixed;
		}
		if (typeof($args.min) == 'string' && $val.length < 1 * $args.min) return false;
		if (typeof($args.max) == 'string' && $val.length > 1 * $args.max) return false;
		return true;
	},
	function($args) {
		if (typeof($args.fixed) == 'string') return 'Ce champ doit contenir exactement ' + $args.fixed + ' caractères.';
		if (typeof($args.min) == 'string') {
			if (typeof($args.max) == 'string') return 'Ce champ doit contenir entre ' + $args.min + ' et ' + $args.max + ' caractères.';
			return 'Ce champ doit contenir un minimum de ' + $args.min + ' caractères.';
		}
		return 'Ce champ doit contenir un maximum de ' + $args.max + ' caractères.';
	}
);	

// Limite de nombre de mots
easyForm.register('easyFormWords',
	function($val, $args) {
		var $wordCount = $val.replace(/^\s+/, '').replace(/\s+$/, '').split(/\s+/).length;
		if (typeof($args.fixed) == 'string') {
			$args.min = $args.fixed;
			$args.max = $args.fixed;
		}
		if (typeof($args.min) == 'string' && $wordCount < 1 * $args.min) return false;
		if (typeof($args.max) == 'string' && $wordCount > 1 * $args.max) return false;
		return true;
	},
	function($args) {
		if (typeof($args.fixed) == 'string') return 'Ce champ doit contenir exactement ' + $args.fixed + ' mots.';
		if (typeof($args.min) == 'string') {
			if (typeof($args.max) == 'string') return 'Ce champ doit contenir entre ' + $args.min + ' et ' + $args.max + ' mots.';
			return 'Ce champ doit contenir un minimum de ' + $args.min + ' mots.';
		}
		return 'Ce champ doit contenir un maximum de ' + $args.max + ' mots.';
	}
);	

// Limite de valeur numerique
easyForm.register('easyFormValue',
	function($val, $args) {
		$val = 1 * $val;
		if (typeof($args.fixed) == 'string') {
			$args.min = $args.fixed;
			$args.max = $args.fixed;
		}
		if (typeof($args.min) == 'string' && $val < 1 * $args.min) return false;
		if (typeof($args.max) == 'string' && $val > 1 * $args.max) return false;
		return true;
	},
	function($args) {
		if (typeof($args.fixed) == 'string') return 'Ce champ doit valoir exactement ' + $args.fixed + '.';
		if (typeof($args.min) == 'string') {
			if (typeof($args.max) == 'string') return 'Ce champ doit avoir une valeur comprise entre ' + $args.min + ' et ' + $args.max + '.';
			return 'Ce champ doit avoir une valeur minimale de ' + $args.min + '.';
		}
		return 'Ce champ doit avoir une valeur maximale de ' + $args.max + '.';
	}
);	

// Double verification d'un champ (par exemple, la confirmation d'un mot de passe)
easyForm.register('easyFormDoubleCheck',
	function($val, $args) {
		if (typeof($args.id) == 'string' && $val == jQuery('#' + $args.id).val()) return true;
		return false;
	},
	'Les deux champs doivent avoir la même valeur.'
);

