/* ****************************************************

	@file         ix.validation.js
	@description  Script de validation de formulaires
	@author       remi (ixmedia.com)
	@version      20100304

	vim: set noet ts=4 fdm=marker fenc=utf-8:

***************************************************** */

jQuery.fn.ixValidation = function() {
	return this.each(function() {

		var self = this;
		var $self = $(this);

		/**
		 * @var config
		 */
		var config = {
			formats : {
				requis      : /^.+$/,
				telephone   : /^[0-9]{3}\-[0-9]{4}$/,
				numerique   : /^[0-9]+$/,
				zip         : /^[0-9]{5}\-[0-9]{4}$/,
				codepostal  : /^[a-zA-Z][0-9][a-zA-Z]\s?[0-9][a-zA-Z][0-9]$/,
				codepostal6 : /^[a-zA-Z][0-9][a-zA-Z][0-9][a-zA-Z][0-9]$/,
				siteweb     : /^(([a-zA-Z0-9\-\.]+.)?[a-zA-Z0-9\-\.\/]+\.[a-z\.]{2,8}\/?[a-zA-Z0-9\-\.\/]*)?$/,
				date        : /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/,
				courriel    : /^(?:[a-z0-9!#$%&'*+/=?^_/`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i
			},
			textes : {
				messageEchec : 'Le formulaire contient des erreurs :'
			}
		}

		/**
		 * Affecte les comportements sur les champs nécessaires
		 */
		function bind_events() {

			// Événements sur le formulaire {{{
			// -----------------------------------------------------------------------------
			$self.each( function() {

				$(this).submit(function() {
					return on_submit();
				});

				$(this).bind('clear_errors', function( e ) {
					$(this).find('.message').remove();
					$(this).data('errors', []);
				});

				$(this).bind('add_error', function( e, msg ) {
					var errors = $(this).data('errors');
					errors.push( msg );
					$(this).data('errors', errors);
				});

				$(this).bind('display_errors', function( e ) {
					var output = '<div class="message message-echec"><p>'+config.textes.messageEchec+'</p><ul>';
					var erreurs = $(this).data('errors');
					$.each( erreurs, function() { 
						output += '<li>'+this+'</li>'
					});
					output += '</ul></div>';
					$(this).prepend( output );
				});

			});
			// }}}

			// Événements sur les champs {{{
			// -----------------------------------------------------------------------------
			$self.find('li.champ').each( function() {

				$(this).data('custom_error_class', 'champ-'+$(this).metadata().type+'-erreur');

				$(this).bind('clear_errors', function( e ) {
					$(this).removeClass('champ-erreur').removeClass( $(this).data('custom_error_class') ).find('.champ-message').remove();
					e.stopPropagation();
				});

				$(this).bind('add_error', function( e, msg ) {
					var $this = $(this);
					$this.trigger( 'clear_errors' ).addClass('champ-erreur').addClass( $(this).data('custom_error_class') ).append('<div class="champ-message">'+msg+'</div>');
					e.stopPropagation();
					e.preventDefault();
				});

			});
			//}}}

			// Obtiens la valeur d’un champ {{{
			// -----------------------------------------------------------------------------
			$.fn.get_champ_val = function() {
				if ( this.is('.champ-texte') ) {
					return this.find('input').val();
				}
				if ( this.is('.champ-textemulti') ) {
					return this.find('textarea').val();
				}
				if ( this.is('.champ-select') ) {
					return this.find('select').val();
				}
			}
			//}}}

		}
		bind_events();

		function on_submit() {
			if ( !do_validations() ) {
				$self.trigger('display_errors');
				return false;
			}
		}

		function do_validations() {
			var form_valide = true;
			$self.trigger('clear_errors');
			$self.find('li.champ').each(function() {
				var $this = $(this);
				var valeur = $this.get_champ_val();
				var validations = $this.metadata().validations;
				$this.trigger( 'clear_errors' );
				if ( validations ) {
					$.each( validations, function() {
						var message = this.message;
						var valide = true;

						// Validation par regex
						if ( this.validation.regex ) {
							var regex = config.formats[ this.validation.regex ];
							if ( !valeur.match( regex ) ) {
								valide = false;
							}
						}

						// Validation par callback
						if ( this.validation.callback ) {
							var validation_callback = this.validation.callback( valeur );
							if ( validation_callback !== true ) {
								valide = false;
								if ( validation_callback !== false ) {
									message = validation_callback;
								}
							}
						}
						
						if ( !valide ) {
							form_valide = false;
							$self.trigger('add_error', message );
							$this.trigger('add_error', message );
							return false;
						}

					});
				}
			});
			return form_valide;
		}

	});
};

$(function() {
	$('form.ix-formulaire').ixValidation();
});

function validationExterne( val ) {
	return false;
	// On pourrait aussi retourner un message personnalisé
	//return 'oh là là!';
}

