// Gestion de la valeur par défaut des champs
$(document).ready(function() {
	// Uniquement sur les champs texte et les textarea
	$('form :text, form textarea').each(function() {
		// Valeur par défaut du champ
	    var value = $(this).val();

		// Suppression de la valeur lors du focus si elle équivaut la valeur par défaut
		// et que le champ ne possède pas une valeur passée en paramètre 
	    $(this).focus(function() {
	        if (!$(this).hasClass('noDefaultValue') && $(this).val() == value) {
	            $(this).val('');
	        }
	    });

		// Valeur par défaut si le champ est vide lorsqu'on le quitte
	    $(this).blur(function() {
	        if ($(this).val() == '') {
	            $(this).val(value);
	        }
	    });
	});
});

// Ajoute un message d'erreur sur un élément
function elementErreur(element, validatorName) {
	// S'il s'agit d'une liste d'éléments
	if (element.length > 1 || element.attr('name').indexOf('[') != -1) {
		// On récupère le conteneur de la liste
		element = element.parent().parent().parent();
		// On déplace le conteneur de l'icône près du premier élément
		element.parent().find('li:first').append(element.parent().find('.validation'));
	}

	// On vérifie que l'élément ne possède pas déjà un message d'erreur
	if (element.parent().find("span.erreur").length == 0) {
		element.addClass('form_erreur');

		// S'il s'agit d'un bloc div (liste d'options), on modifie la classe css
		if (element.parent().attr('class') == 'divGenerateur') {
			element.parent().attr('class', 'divGenerateurErreur');
		} else {
			// Sinon on ajoute la classe d'erreur
			element.parent().addClass('erreur');
		}
	}

	// On ajoute le message d'erreur correspondant
	if (element.parent().find('.erreur').length > 0) {
		element.parent().find('.erreur').text(App.Message[validatorName]);
	} else {
		element.parent().prepend('<span class="erreur" style="display:none;">' + App.Message[validatorName] + '</span>');
	}

	// On affiche le message d'erreur
	element.parent().find('span.erreur').slideDown('normal', function() {
		// On affiche une icône d'erreur
		element.parent().find('.validation').html('<img src="/ressources/img/erreur.png"/>');
	});
}

// Supprime le message d'erreur d'un élément
function elementValide(element, validatorName) {
	// S'il s'agit d'une liste d'éléments
	if (element.length > 1 || element.attr('name').indexOf('[') != -1) {
		// On récupère le conteneur de la liste
		element = element.parent().parent().parent();
		// On déplace le conteneur de l'icône près du premier élément
		element.parent().find('li:first').append(element.parent().find('.validation'));
	}

	// Si l'élément n'avait pas d'erreur
	if (element.parent().find('span.erreur').text() == '') {
		// On affiche une icône de validation
		element.parent().find('.validation').html('<img src="/ressources/img/valide.png"/>');
	} else {
		// On cache le message d'erreur
		element.parent().find('span.erreur').slideUp('normal', function() {
			element.removeClass('form_erreur');

			// S'il s'agit d'un bloc div (liste d'options), on modifie la classe css
			if (element.parent().attr('class') == 'divGenerateurErreur') {
				element.parent().attr('class', 'divGenerateur');
			} else {
				// Sinon on ajoute la classe d'erreur
				element.parent().removeClass('erreur');
			}

			// On supprime le message d'erreur
			$(this).remove();

			// On affiche une icône de validation
			element.parent().find('.validation').html('<img src="/ressources/img/valide.png"/>');
		});
	}
}

// Fonction de validation d'un champ
function validerChamp(element, value, ruleset, formValidates, keyup) {
	var elementValidates = true;

	// On boucle sur les validateurs de l'élément
	for (var i in ruleset) {
		// Récupération du nom du validateur
		var validatorName = ruleset[i].name;
		// Nom du dernier validateur
		var LastValidatorName = validatorName;

		// On vérifie que le validateur existe
		if (App.Validator[validatorName] !== undefined) {
			// Test de validation de l'élément
			var elementValidates = App.Validator[validatorName](value, ruleset[i].parameters);

			// L'élément n'est pas valide, on déclare les statuts de validation à false
			if (!elementValidates) {
				formValidates = false;
				elementValidates = false;
				break;
			}
		}
	}

	if (elementValidates) {
		elementValide(element, LastValidatorName);
	} else {
		elementErreur(element, LastValidatorName);

		// Si l'option keyup est active
		if (keyup !== false) {
			element.keyup(function() {
				// On valide le champ lors du keyup
				// L'option keyup n'est pas activé pour éviter de lancer x fois l'évènement
				validerChamp($(this), $(this).val(), ruleset, true, false);
			});
		}
	}

	return formValidates;
}

$(document).ready(function() {
	// Etat de validation
	var formValidates = true;

	// On boucle sur les formulaires
	for (var form in Forms) {
		// Nom du formulaire
		var formName = form;
		// Règles de validation du formulaire
		var rules = Forms[formName];

		// On boucle sur les éléments du formulaire
		for (var field in Forms[form]) {
			// Fonction lorsque l'on quitte l'élément
			$('#' + field + ', input[name=' + field + '\[\]]').blur(function() {
				// Elément du formulaire
				var element = $(this);
				// Nom de l'élément
				var field = element.attr('name').replace(/\[/, '').replace(/\]/, '');

				// Règles de validation de l'élément
				var ruleset = rules[field];
				// Valeur de l'élément
				var value = element.val();

				// Si l'élément possède plusieurs options (checkbox, radios)
				if ($('input[name=' + field + '\[\]]').length > 1) {
					// On récupère un tableau avec les valeurs cochées ou sélectionnées
					value = new Array();
					element = $('input[name=' + field + '\[\]]');
					element.each(function() {
						if ($(this).is(':checked') || $(this).is(':selected')) {
							value.push($(this).val());
						}
					});
				}

				// Validation de l'élément
				formValidates = validerChamp($(this), $(this).val(), ruleset, formValidates);
			});
		}
	}
});

// Déclaration des variables
var App = App || { };
var Forms = Forms || { };

// Fonction de validation du formulaire complet ou d'une étape
App.validate = function(form, etape) 
{
	// Nom du formulaire
	var formName = (form.id) ? form.id : 'form';
	// Règles de validation du formulaire
	var rules = Forms[formName];
	// Etat de validation
	var formValidates = true;

 	// Pour chaque éléments du formulaire ayant une règle de validation associée
	for (var key in rules) {
		// Si tous les éléments sont vérifiés ou si l'élément en cours est dans l'étape à valider
		if (etape === undefined || etape.find('input[name=' + key + '], textarea[name=' + key + ']').length > 0
			|| etape.find('input[name=' + key + '\[\]]').length > 0)
		{
			// Elément du formulaire
			var element = form[key];
			var multiElement = false;

			// Si l'élément n'existe pas (cas des checkbox et boutons radios)
			if (element === undefined) {
				multiElement = true;
				var element = form[key + '[]'];
			}

			// Règles de validation de l'élément
			var ruleset = rules[key];

			// Valeur de l'élément
			var value = (element.nodeName == 'INPUT' || element.nodeName == 'TEXTAREA') 
				? element.value 
				: element.innerHTML;

			// Si l'élément possède plusieurs options (checkbox, radios)
			if (multiElement === true) {
				// On récupère un tableau avec les valauers cochées ou sélectionnées
				value = new Array();
				$(element).each(function() {
					if ($(this).is(':checked') || $(this).is(':selected')) {
						value.push($(this).val());
					}
				});
			}

			formValidates = validerChamp($(element), value, ruleset, formValidates);
		}
	}

	return formValidates;
}

// Liste des messages d'erreurs associés aux validateurs
App.Message = {
	Zend_Validate_NotEmpty : 'Ce champ est vide : vous devez le compléter.',
	Zend_Validate_Alnum : 'Ce champ ne peut contenir que des lettres et/ou des chiffres.',
	Zend_Validate_Alpha : 'Ce champ ne peut contenir que des lettres.',
	Zend_Validate_Digits : 'Ce champ ne peut contenir que des chiffres.',
	Zend_Validate_EmailAddress : 'L\'adresse email n\'est pas valide. Elle doit respecter le format adresse@domaine.com.',
	Zend_Validate_Between : 'La valeur de ce champ doit être comprise entre %min% et %max% inclus.',
	Zend_Validate_Float : 'Ce champ doit contenir un nombre décimal.',
	Zend_Validate_Int : 'Ce champ doit contenir un nombre entier.',
	Zend_Validate_StringLength : 'Ce champ doit contenir entre %min% et %max% caractères.',
	My_Zend_Validate_Different : 'Vous devez renseigner ce champ.',
	My_Zend_Validate_Telephone : 'Votre numéro de téléphone doit être composé de 10 à 14 chiffres sans espace ni point.'
}

// Liste des règles de validation
App.Validator = {
	Zend_Validate_NotEmpty: function(value, parameters)
	{
		if (value != '') {
			return true;
		} else {
			return false;
		}
	},
	Zend_Validate_Alnum: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else if (parameters.allowWhiteSpace) {
			return value.match(/^[a-z0-9\s]*$/i);
		} else {
			return value.match(/^[a-z0-9]*$/i);
		}
	},
	Zend_Validate_Digits: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else if (parameters.allowWhiteSpace) {
			return value.match(/^[0-9\s]*$/i);
		} else {
			return value.match(/^[0-9]*$/i);
		}
	},
	Zend_Validate_Alpha: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else if (parameters.allowWhiteSpace) {
			return value.match(/^[a-z\s]*$/i);
		} else {
			return value.match(/^[a-z]*$/i);
		}
	},
	Zend_Validate_EmailAddress: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else {
			return (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(value));
		}
	},
	Zend_Validate_Int: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else if (!isNaN(parseInt(value))) {
			return true;
		} else {
			return false;
		}
	},
	Zend_Validate_Float: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else if (!isNaN(parseFloat(value))) {
			return true;
		} else {
			return false;
		}
	},
	Zend_Validate_Between: function(value, parameters)
	{
		if (value == '' || value >= parameters.min && value <= parameters.max) {
			return true;
		} else {
			// Remplacement des valeurs min et max
			App.Message['Zend_Validate_Between'] = App.Message['Zend_Validate_Between'].replace(/%min%/, parameters.min).replace(/%max%/, parameters.max);
			return false;
		}
	},
	Zend_Validate_StringLength: function(value, parameters)
	{
		if (value.length >= parameters.min && value.length <= parameters.max) {
			return true;
		} else {
			// Remplacement des valeurs min et max
			App.Message['Zend_Validate_StringLength'] = App.Message['Zend_Validate_StringLength'].replace(/%min%/, parameters.min).replace(/%max%/, parameters.max);
			return false;
		}
	},
	My_Zend_Validate_Different: function(value, parameters)
	{
		if (value != parameters.label) {
			return true;
		} else {
			return false;
		}
	},
	My_Zend_Validate_Telephone: function(value, parameters)
	{
		if (value == '') {
			return true;
		} else {
			if(value.length>=10 && value.length<=14){
				return (/^[0-9]+$/.test(value));
			} else {
				return false;
			}
		}
	}
};