/*

Script Authors:

		Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>

		Based on validation.js by Andrew Tetlaw (http://tetlaw.id.au/view/blog/really-easy-field-validation-with-prototype)

*/



var InputValidator = new Class({

	initialize: function(className, options){

		this.setOptions({

			errorMsg: 'Validation failed.',

			test: function(field){return true}

		}, options);

		this.className = className;

	},



	test: function(field){

		if($(field)) return this.options.test($(field), this.getProps(field));

		else return false;

	},



	getError: function(field){

		var err = this.options.errorMsg;

		if($type(err) == "function") err = err($(field), this.getProps(field));

		return err;

	},

	getProps: function(field){

		if($(field) && $(field).getProperty('validatorProps')){

			try {

				return Json.evaluate($(field).getProperty('validatorProps'));

			}catch(e){ return {}}

		} else {

			return {}

		}

	}

});

InputValidator.implement(new Options);





var FormValidator = new Class({

	options: {

		fieldSelectors:"input, select, textarea",

		useTitles:false,

		evaluateOnSubmit:true,

		evaluateFieldsOnBlur: true,

		evaluateFieldsOnChange: true,

		serial: true,

		warningPrefix: "Warning: ",

		errorPrefix: "Erreur : ",

		onFormValidate: function(isValid, form){},

		onElementValidate: function(isValid, field){}

	},

	initialize: function(form, options){

		this.setOptions(options);

		try {

			this.form = $(form);

			if(this.options.evaluateOnSubmit) this.form.addEvent('submit', this.onSubmit.bind(this));

			if(this.options.evaluateFieldsOnBlur) this.watchFields();

		}catch(e){//console.log('error: %s', e);

		}

	},

	getFields: function(){

		return this.fields = this.form.getElementsBySelector(this.options.fieldSelectors)

	},

	watchFields: function(){

		try{

			this.getFields().each(function(el){

					el.addEvent('blur', this.validateField.pass([el, false], this));

				if(this.options.evaluateFieldsOnChange)

					el.addEvent('change', this.validateField.pass([el, true], this));

			}, this);

		}catch(e){//console.log('error: %s', e);

		}

	},

	onSubmit: function(event){

		if(!this.validate()) new Event(event).stop();

		else {

			this.stop();

			this.reset();

		}

	},



	reset: function() {

		this.getFields().each(this.resetField, this);

	},



	validate : function() {

		var result = this.getFields().map(function(field) { return this.validateField(field, true); }, this);

		result = result.every(function(val){

			return val;

		});

		this.fireEvent('onFormValidate', [result, this.form]);

		return result;

	},



	validateField: function(field, force){

		if(this.paused) return true;

		field = $(field);

		var result = true;

		var failed = this.form.getElement('.validation-failed');

		var warned = this.form.getElement('.warning');

		if(field && (!failed || force || (failed && !this.options.serial))){

			var validators = field.className.split(" ").some(function(cn){

				return this.getValidator(cn);

			}, this);

			result = field.className.split(" ").map(function(className){

				return this.test(className,field);

			}, this);

			result = result.every(function(val){

				return val;

			});

			if (validators && !field.hasClass('warnOnly')){

				if(result) field.addClass('validation-passed').removeClass('validation-failed');

				else field.addClass('validation-failed').removeClass('validation-passed');

			}

			if(!warned || force || (warned && !this.options.serial)) {

				var warnings = field.className.split(" ").some(function(cn){

					if(cn.test('^warn-') || field.hasClass('warnOnly')) return this.getValidator(cn.replace(/^warn-/,""));

				}, this);

				field.removeClass('warning');

				var warnResult = field.className.split(" ").map(function(cn){

					if(cn.test('^warn-') || field.hasClass('warnOnly')) return this.test(cn.replace(/^warn-/,""), field, true);

				}, this);

			}

		}

		return result;

	},

	getPropName: function(className){

		return '__advice'+className;

	},



	test: function(className, field, warn){

		if(field.hasClass('ignoreValidation')) return true;

		warn = $pick(warn, false);

		if(field.hasClass('warnOnly')) warn = true;

		field = $(field);

		var isValid = true;

		if(field) {

			var validator = this.getValidator(className);

			if(validator && this.isVisible(field)) {

				isValid = validator.test(field);

				if(!isValid && validator.getError(field)){

					if(warn) field.addClass('warning');

					var advice = this.makeAdvice(className, field, validator.getError(field), warn);

					this.insertAdvice(advice, field);

					this.showAdvice(className, field);

				} else this.hideAdvice(className, field);

				this.fireEvent('onElementValidate', [isValid, field]);

			}

		}

		if(warn) return true;

		return isValid;

	},

	showAdvice: function(className, field){

		var advice = this.getAdvice(className, field);

		if(advice && !field[this.getPropName(className)] && (advice.getStyle('display') == "none" || advice.getStyle('visiblity') == "hidden" || advice.getStyle('opacity')==0)){

			field[this.getPropName(className)] = true;

			if(advice.smoothShow) advice.smoothShow();

			else advice.setStyle('display','block');

		}

	},

	hideAdvice: function(className, field){

		var advice = this.getAdvice(className, field);

		if(advice && field[this.getPropName(className)]) {

			field[this.getPropName(className)] = false;

			if(advice.smoothHide) advice.smoothHide();

			else advice.setStyle('display','none');

		}

	},

	isVisible : function(field) {

		while(field.tagName != 'BODY') {

			if($(field).getStyle('display') == "none") return false;

			field = field.parentNode;

		}

		return true;

	},

	getAdvice: function(className, field) {

		return $('advice-' + className + '-' + this.getFieldId(field))

	},

	makeAdvice: function(className, field, error, warn){

		var errorMsg = (warn)?this.options.warningPrefix:this.options.errorPrefix;

				errorMsg += (this.options.useTitles) ? $pick(field.title, error):error;

		var advice = this.getAdvice(className, field);

		if(!advice){

			var cssClass = (warn)?'warning-advice':'validation-advice';

			advice = new Element('div').addClass(cssClass).setProperty(

				'id','advice-'+className+'-'+this.getFieldId(field)).setStyle('display','none').appendText(errorMsg);

		} else{

			advice.setHTML(errorMsg);

		}

		return advice;

	},

	insertAdvice: function(advice, field){

		switch (field.type.toLowerCase()) {

			case 'radio':

				var p = $(field.parentNode);

				if(p) {

					p.adopt(advice);

					break;

				}

			default: advice.injectAfter($(field));

	  };

	},

	getFieldId : function(field) {

		return field.id ? field.id : field.id = "input_"+field.name;

	},



	resetField: function(field) {

		field = $(field);

		if(field) {

			var cn = field.className.split(" ");

			cn.each(function(className) {

				if(className.test('^warn-')) className = className.replace(/^warn-/,"");

				var prop = this.getPropName(className);

				if(field[prop]) this.hideAdvice(className, field);

				field.removeClass('validation-failed');

				field.removeClass('warning');

				field.removeClass('validation-passed');

			}, this);

		}

	},



	stop: function(){

		this.paused = true;

	},



	start: function(){

		this.paused = false;

	},



	ignoreField: function(field, warn){

		if(field = $(field)){

			this.enforceField(field);

			if(warn) field.addClass('warnOnly');

			else field.addClass('ignoreValidation');

		}

	},



	enforceField: function(field){

		if(field = $(field)){

			field.removeClass('warnOnly');

			field.removeClass('ignoreValidation');

		}

	}

});

FormValidator.implement(new Options);

FormValidator.implement(new Events);



FormValidator.adders = {



	validators:{},



	add : function(className, options) {

		this.validators[className] = new InputValidator(className, options);

		if(!this.initialize){

			this.implement({

				validators: this.validators

			});

		}

	},



	addAllThese : function(validators) {

		$A(validators).each(function(validator) {

			this.add(validator[0], validator[1]);

		}, this);

	},

	getValidator: function(className){

		return this.validators[className];

	}

};

Object.extend(FormValidator, FormValidator.adders);

FormValidator.implement(FormValidator.adders);





FormValidator.add('IsEmpty', {

	errorMsg: false,

	test: function(element) {

		if(element.type == "select-one"||element.type == "select")

			return !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != "");

		else

			return ((element.getValue() == null) || (element.getValue().length == 0));

	}

});





FormValidator.addAllThese([



	['requis', {

		errorMsg: function(element){return 'ce champ est requis.'},

		test: function(element) {

			return !FormValidator.getValidator('IsEmpty').test(element);

		}

	}],



	['minLength', {

		errorMsg: function(element, props){

			if($type(props.minLength))

				return 'Please enter at least ' + props.minLength + ' characters (you entered ' + element.getValue().length + ' characters).';

			else return '';

		},

		test: function(element, props) {

			if($type(props.minLength)) return (element.getValue().length >= $pick(props.minLength, 0));

			else return true;

		}

	}],



	['maxLength', {

		errorMsg: function(element, props){

			if($type(props.maxLength))

				return 'Please enter no more than ' + props.maxLength + ' characters (you entered ' + element.getValue().length + ' characters).';

			else return '';

		},

		test: function(element, props) {

			return (element.getValue().length <= $pick(props.maxLength, 10000));

		}

	}],



	['validate-number', {

		errorMsg: 'Please enter a valid number in this field.',

		test: function(element) {

				return FormValidator.getValidator('IsEmpty').test(element) || !/[^\d+$]/.test(element.getValue());

		}

	}],



	['validate-digits', {

		errorMsg: 'Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.',

		test: function(element) {

			return FormValidator.getValidator('IsEmpty').test(element) ||

				(!/[^a-zA-Z]/.test(element.getValue()) && /[\d]/.test(element.getValue()));

		}

	}],



	['validate-alpha', {

		errorMsg: 'Please use letters only (a-z) in this field.',

		test: function (element) {

			return FormValidator.getValidator('IsEmpty').test(element) ||  /^[a-zA-Z]+$/.test(element.getValue())

		}

	}],



	['validate-alphanum', {

		errorMsg: 'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',

		test: function(element) {

			return FormValidator.getValidator('IsEmpty').test(element) || !/\W/.test(element.getValue())

		}

	}],



	['validate-date', {

		errorMsg: 'Please use this date format: mm/dd/yyyy. For example 03/17/2006 for the 17th of March, 2006.',

		test: function(element) {

			if(FormValidator.getValidator('IsEmpty').test(element)) return true;

	    var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;

	    if(!regex.test(element.getValue())) return false;

	    var d = new Date(element.getValue().replace(regex, '$1/$2/$3'));

	    return (parseInt(RegExp.$1, 10) == (1+d.getMonth())) &&

        (parseInt(RegExp.$2, 10) == d.getDate()) &&

        (parseInt(RegExp.$3, 10) == d.getFullYear() );

		}

	}],



	['validate-email', {

		errorMsg: 'cette adresse email n\'est pas valide.',

		test: function (element) {

			return FormValidator.getValidator('IsEmpty').test(element) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(element.getValue());

		}

	}],



	['validate-url', {

		errorMsg: 'Please enter a valid URL.',

		test: function (element) {

			return FormValidator.getValidator('IsEmpty').test(element) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(element.getValue());

		}

	}],







	['validate-date-au', {

		errorMsg: 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.',

		test: function(element) {

			if(FormValidator.getValidator('IsEmpty').test(element)) return true;

	    var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;

	    if(!regex.test(element.getValue())) return false;

	    var d = new Date(element.getValue().replace(regex, '$2/$1/$3'));

	    return (parseInt(RegExp.$2, 10) == (1+d.getMonth())) &&

        (parseInt(RegExp.$1, 10) == d.getDate()) &&

        (parseInt(RegExp.$3, 10) == d.getFullYear() );

		}

	}],



	['validate-currency-dollar', {

		errorMsg: 'Please enter a valid $ amount. For example $100.00 .',

		test: function(element) {

			return FormValidator.getValidator('IsEmpty').test(element) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(element.getValue());

		}

	}],



	['validate-one-required', {

		errorMsg: 'Please enter something for at least one of the above options.',

		test: function (element) {

			var p = element.parentNode;

			var options = p.getElements('input');

			return $A(options).some(function(el) {

				return el.getValue();

			});

		}

	}]

]);



window.addEvent('domready', function(){

if ($('boutonenvoyer')!=null) {
	
	$('boutonenvoyer').addEvent('click', function() {

	var myFormValidator = new FormValidator($('adminform'));

	});
}
});


