//Chaque chargement d'un page, attacher les evenements necessaires aus formulaires
Event.observe(window, "load", function() {
	attachValidation();
});

//Attacher un evenement au evenement "submit" des formulaires
function attachValidation() {
	this._arrForms = $A($$("form"));
	this._key = "VALIDATE";
	this._arrForms.each( function(item) {
		if(item.className.toUpperCase() == this._key){
			var v = new Validation(item);
			v = null;
		}else{
			//Event.observe(item, "submit", showLoader);
		}
		item = null;
	});
	this._arrForms = null;
}

var Validation = Class.create();
Validation.prototype = {
	
	//Attributs 
	_form 					: null,
	_errorContainer			: null,
	_errorsToShow			: [],
	_errorColor				: "#FFE9EA",
	_normalColor			: "#FFFFFF",
	_errorsToRemove			: [],
	_langue					: "fr",
	_key					: "VALIDATE",
	_messagePrefix			: "ERREUR DE SAISIE",
	_messagePrefixKeys		: $H({
								"en": "ERROR",
								"fr": "ERREUR DE SAISIE"
							}),
	_methodKeys				: $H({
								"NOTEMPTY"		: "isNotEmpty",
								"VALIDDATE"		: "isValidDate",
								"NOTCHECKED"	: "isNotChecked",
								"MATCH"			: "isNotMatch",
								"VALIDEMAIL"	: "isValidEmail",
								"VALIDNUMBER"	: "isValidNumber",
								"GREATERTHAN" 	: "isGreaterThan",
								"MINLENGTH"		: "isMinLength"
							}),
	
	initialize : function(pForm){
		if (!pForm){
			return;
		}
		this._form = pForm;
		//this._langue = (!(pForm.lang)) ? "fr" : (pForm.lang);
		//defaultLangue		
		this._langue = (!(pForm.lang)) ? ( !(defaultLangue) ? "fr" : defaultLangue ) : (pForm.lang);
		this._messagePrefix = (!(this._messagePrefixKeys[this._langue])) ? this._messagePrefix : this._messagePrefixKeys[this._langue];
		this._errorContainer = $("msgErreurs");
		//R?cuperer l'ensemble des methodes ? ?xecuter lors de la soumission
		this._fieldValidations = this._getFieldValidations();
		Event.observe(this._form,'submit',this._check.bind(this),false);
		pForm = null;
	},
	
	_getDefaultMessage : function (pField,pKey){
		
		var mssgField = (!pField.name) ? pField.id : pField.name;
		
		//R?cuperer l'element "label" associ? au champ
		var elemLabel = this._form.getElementsBySelector("label[for="+pField.id+"]")[0];

		//S'il existe, r?cuperer le texte qu'il contient
		if(elemLabel !== null){
			mssgField = (elemLabel.innerHTML).stripTags().strip();
			mssgField = mssgField.replace(/\*|:/gi, "");
		}
		
		//R?cuperer la message prefixe 
		var mssgPrefix = Try.these( 
			function() { return defaultMessages[pKey]; }
		) || "Error : ";
		
		pField = null;
		pKey = null;
		elemLabel = null;
		
		return (mssgPrefix+"'"+mssgField+"'");
		
	},
	
	_getFieldValidations : function(){
		
		//R?cuperer les champs ? valider, ie Les champs ou l'attribut "class" contient le valeur "VALIDATE"
		var fields = document.getElementsByClassName(this._key,this._form);
		
		var arrValidations = [];
		
		//Valider chaque champ
		fields.each( (function (field){
			
			//R?cuperer les methodes ? partir de la className
			var _className = field.className;
			var strMethods = _className.substring(_className.indexOf("{"), _className.indexOf("}")+1);
			//Cr?er un objet JavaScript ? partir de cet string
			var objMethods = eval("mm = "+strMethods);
	
			//Convertir en Hash
			var hMethods = $H(objMethods);
			
			//R?cuperer les options pour un fonction donn?e
			var strOptions = "";
			var hOptions = "";
			if(_className.indexOf("OPTIONS") != -1){
				strOptions = _className.substring(_className.indexOf("["), _className.indexOf("]")+1);
				strOptions = strOptions.replace("[","{");
				strOptions = strOptions.replace("]","}");
				hOptions = $H(eval("oo = "+strOptions));
			}
			
			//Cr?er un objet FieldValidation pour chaque validation de chaque champ
			hMethods.each( (function(pair) {
				var _mssg = (!pair[1]) ? this._getDefaultMessage(field,pair[0]) : pair[1];
				var _options = (!hOptions[pair[0]]) ? "" : hOptions[pair[0]] ;
				var _method = new FieldValidation(field,this._methodKeys[pair[0]],_mssg, this._langue, _options);
				arrValidations[arrValidations.length] = _method;
				_mssg = null;
				_options = null;
				_method = null;
				pair = null;
			}).bind(this));
			
			field = null;
			
		}).bind(this)); //Attacher l'objet de validation (this)
		
		fields = null;
		
		return arrValidations;		
	},
	
	_check : function(pEvent){
		
		this._fieldValidations.each( (function(fv){ 
			//TODO : stocker uniquement la premiere erreur trouv? sur un champ...
			var mssg = fv._errorMessage;
			
			//V?rifier que les champs sont visible ... ;-)
			var boolVisible = !(fv._champ.style.display);
			
			//Si oui, v?rifier ses ancestors ...
			if(boolVisible){
				var ancestors = fv._champ.ancestors();
				ancestors.each( function(anc){
					if(! anc.visible()){
						boolVisible = false;
					}
					anc = null;
				});
				ancestors = null;
			}
			
			//On teste uniquement les champs visible
			if(boolVisible){
				(fv._test()) ? this._errorsToRemove.push([fv._champ,mssg]) : this._errorsToShow.push([fv._champ,mssg]);
			}
			
			boolVisible = null;
			mssg = null;
			fv = null;
			
		}).bind(this));
		
		//traitement des erreurs
		this._resetErrors();
		this._showAllErrors();
		
		if(this._errorsToShow.size() > 0){
			Event.stop(pEvent);
			this._errorContainer.scrollTo();
		}else{
			//showLoader();
		}
		
		this._errorsToShow.clear();
		this._errorsToRemove.clear();
		
		pEvent = null;
	},
	
	_showAllErrors : function(){
		
		if(this._errorsToShow.size() < 1){
			return;
		}
		
		if(this._errorContainer){
			var mssg = "<strong>"+this._messagePrefix+" :</strong>";			
			var errors = this._errorContainer.innerHTML;
			if(errors.indexOf(mssg) == -1){
				var _insert = new Insertion.Bottom(this._errorContainer, mssg+("<br />").toUpperCase());
			}
			mssg = null;
			errors = null;
		}
		
		this._errorsToShow.each( (function(error){
				error[0].style.backgroundColor = this._errorColor;
				this._showError(error[1]);
				error = null;
		}).bind(this));
		
	},
	
	_resetErrors : function(){
		
		//Supprimer la liste des erreurs
		if(this._errorContainer){
			this._errorContainer.innerHTML = null;
		}
		
		//Resetter les champs
		if(this._errorsToRemove.size() < 1){
			return;
		}
		
		this._errorsToRemove.each( (function(error){
			error[0].style.backgroundColor = this._normalColor;
			error = null;
		}).bind(this));
		
	},
	
	//Afficher un message d'erreur
	_showError : function(pMessage, pErrorContainer){
		var mssg = (!pMessage) ? this._errorMessage : pMessage;
		if(pErrorContainer){
			this._errorContainer = pErrorContainer;
		}
		if(!this._errorContainer){
			alert(mssg);
		}else{
			var errors = this._errorContainer.innerHTML;
			if(errors.indexOf(mssg) == -1){
				var _insert = new Insertion.Bottom(this._errorContainer, mssg+("<br />").toUpperCase());
			}
			errors = null;
		}
		mssg = null;
		pMessage = null;
		pErrorContainer = null;
		return false;
	},
	
	//Cacher un message d'erreur
	_removeError : function(pMessage, pErrorContainer){
		var mssg = (!pMessage) ? this._errorMessage : pMessage;
		
		if(pErrorContainer){
			this._errorContainer = pErrorContainer;
		}
		
		if(!this._errorContainer){
			return;
		}
		
		pMessage = null;
		pErrorContainer = null;
		
		var errors = this._errorContainer.innerHTML;
		if( (errors.indexOf(mssg) >= 0) ){
			var txt = null;
			if(errors.indexOf("<br>") >= 0){
				txt = errors.gsub(mssg+"<br>","");
			}else{
				txt = errors.gsub(mssg+"<BR>","");
			}
			this._errorContainer.innerHTML = txt;
			txt = null;
		}
		errors = null;
		mssg = null;
		return true;
	},
	
	toString : function(){ return "[object Validation]"; }
	
};


/* Classe de base pour la validation des champs */
var FieldValidation = Class.create();
FieldValidation.prototype = {
	
	//Attributs 
	_champ				: null,
	_function			: null,
	_options			: null,
	_errorMessage		: "",
	_errorContainer		: "",
	_langue				: "fr",
	
	//Initialisation
	initialize : function(pChamp,pFunction,pMessage,pLangue,pOptions){
		this._champ = pChamp;
		this._function = pFunction;
		this._options = pOptions;
		if(pLangue){
			this._langue = pLangue;
		}
		this._errorMessage	= pMessage;
		this._errorContainer = $("msgErreurs");
		pChamp = null;
		pFunction = null;
		pMessage = null;
		pLangue = null;
		pOptions = null;
	},
	
	//Methodes
	_test : function(){
		//Appeler le method stock? dans "_function", le methode doit renvoyer un valeur BOOLEAN
		return (eval(this._function)).call(this);
	},
	_showError : function(pm,ec){ (new Validation())._showError( ((!pm) ? this._errorMessage : pm), ((!ec) ? this._errorContainer : ec) ) },
	_removeError : function(pm,ec){ (new Validation())._removeError( ((!pm) ? this._errorMessage : pm), ((!ec) ? this._errorContainer : ec) ) },
	
	//Override "toString" methode
	toString : function(){ return "[object FieldValidation]"; }
}

/*******************************************************************************/
/***** Methodes de validation ? appeler lors de la soumission d'un formulaire **/
/*******************************************************************************/

//helper fonction : Suppression des espaces
function trimString(str) {
	str=str.replace(/\s/ig,'');
	return str;
}

/* V?rifier qu'un champ ? ?t? rempli */
function isNotEmpty(){
	var objField = this._champ;
	if(!objField){
		return;
	}
	return objField.present();
}

/* V?rifier si les valeurs de deux champs sont identiques */
function isNotMatch(){

	var objField = this._champ;
	var objFieldMatch = $(this._options);
	
	if((!objField || !objFieldMatch) || !objFieldMatch.present()){
		return true;
	}
	
	if( !objField.present() 
			|| !objFieldMatch.present()
			|| objField.value.toUpperCase() != objFieldMatch.value.toUpperCase() ){	
			return false;
	}else{
		return true;
	}
	
}

/* V?rifer si une date est valide */
function isValidDate(){ 
		
		var objField = this._champ;
		if(!objField){
			return true;
		}
		
		var langue = (!this._langue) ? "fr" : this._langue;
		var dateFormat = [ ["mm", "dd", "yyyy"], "/" ];
		var language_date_format = $H({
			"en": [ ["mm", "dd", "yyyy"], "/" ],
			"lt": [ ["yyyy", "mm", "dd"], "-" ],
			"fr": [ ["dd", "mm", "yyyy"], "/" ],
			"sp": [ ["dd", "mm", "yyyy"], "/" ],
			"it": [ ["dd", "mm", "yyyy"], "/" ],
			"de": [ ["dd", "mm", "yyyy"], "/" ],
			"pt": [ ["dd", "mm", "yyyy"], "/" ],
			"hu": [ ["dd", "mm", "yyyy"], "/" ],
			"nl": [ ["dd", "mm", "yyyy"], "-" ]
		});
		
		var df = new DatePickerFormatter(
			language_date_format[langue][0],
			language_date_format[langue][1]
		);
		
		return ( df.match(objField.value) );
}

function isValidEmail(){
	var objField = this._champ;
	if(!objField){
		return true;
	}
	
	var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
	var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,50}|[0-9]{1,3})(\]?)$/; // valid
	
	var strEmail = trimString(objField.value);
	
	return ( (!reg1.test(strEmail)) && (reg2.test(strEmail)) );
}

function isNotChecked(){
	var objField = this._champ;
	if(!objField){
		return true;
	}
	return objField.checked;
}

function isValidNumber(){
	
	var objField = this._champ;
	if(!objField || objField.value == "" || objField.value == null){
		return true;
	}
	var _value = objField.value;
	var valid = true;
	
	if(isNaN(_value)){
		valid = false;
	}
	
	//WHOLENUMBER ou DECIMAL
	var _testTypeKey = this._options;
	var _hashTestType = $H({
							"WHOLENUMBER"	: true,
							"DECIMAL" 		: false
						});
	
	var boolWholeNumber = _hashTestType[_testTypeKey];
	
	//If wholenumber only
	if(boolWholeNumber && valid){
		valid = (_value.indexOf(".") != -1) ? false : true;
	}
	
	return valid;
}

function isGreaterThan(){
	var objField = this._champ;
	if(!objField){
		return true;
	}
	
	var _min = (parseInt(this._options)) ? parseInt(this._options) : 0;
	var _value = objField.value;
	
	if(isNaN(_value)){
		return false;
	}else{
		return (_value > _min);
	}
}

function isMinLength(){

	var objField = this._champ;
	var intLength = (parseInt(this._options)) ? (parseInt(this._options)) : 0;	
	var _value = objField.value;

	if( !objField 
		|| !_value 
		|| !intLength
		|| !isFinite(intLength) ){
			return true;
	}
	
	return (_value.length >= intLength);
}


/*******************************************************************************/
/***** Methodes de validation ? appeler lors de la modification d'un champ ****/
/*******************************************************************************/
/* 
V?rifier que la difference entre deux dates est "PLUS QUE" ou "MOINS QUE" un valeur d?fini.
Si seulement un date est sp?cifi? utilise le date actuel (ie new Date()).
	Retourner un boolean "true||false" dependant du la comparateur sp?cifi?
		"GT" == "Greater than"					: TRUE si la difference est "PLUS" que "DIFFERENCE"
		"GTE" == "Greater than || Equal to"		: TRUE si la difference est "PLUS ou EGALE A" que "DIFFERENCE"
		"LT" == "Less than"						: TRUE si la difference est "MOINS" que "DIFFERENCE"
		"LTE" == "Less than || Equal to"		: TRUE si la difference est "MOINS ou EGALE A" que "DIFFERENCE"
		
*/
var TestDateDifference = Class.create();
TestDateDifference.prototype = Object.extend(new FieldValidation(), {
	
//Attributs
	_champB 		: null,
	_difference		: null, //en ms
	_comparison		: new Array(),
	_comparisons 	: $H({
						"GT"	: ">",
						"GTE"	: ">=",
						"LT"	: "<",
						"LTE"	: "<=",
						"DIFF_POSITIF"	: ">=0"
					}),
	_dateFormat 	: [ ["mm", "dd", "yyyy"], "/" ],
	_language_date_format : $H({
		"en": [ ["mm", "dd", "yyyy"], "/" ],
		"lt": [ ["yyyy", "mm", "dd"], "-" ],
		"fr": [ ["dd", "mm", "yyyy"], "/" ],
		"sp": [ ["dd", "mm", "yyyy"], "/" ],
		"it": [ ["dd", "mm", "yyyy"], "/" ],
		"de": [ ["dd", "mm", "yyyy"], "/" ],
		"pt": [ ["dd", "mm", "yyyy"], "/" ],
		"hu": [ ["dd", "mm", "yyyy"], "/" ],
		"nl": [ ["dd", "mm", "yyyy"], "-" ]
	}),
	
	//Initialize
	initialize : function(pChamp,pChampB,pDifference,pComparison,pErrorMessage,pErrorContainer,pLangue){
		
		if ( !pChamp 
				|| !pComparison 
				|| !pDifference 
				|| isNaN(pDifference) ) {
			return;
		}
		this._champ = $(pChamp);
		this._champB = (!pChampB) ? null : $(pChampB);
		this._difference = parseInt(pDifference);
		this._comparison = (pComparison.indexOf("|") != -1) ? $A(pComparison.split("|")) : $A(new Array(pComparison));
		this._errorMessage = (!pErrorMessage) ? "" : pErrorMessage;
		if(pErrorContainer){
			this._errorContainer = $(pErrorContainer);
		}
		if(pLangue){
			this._langue = pLangue;
		}
		Event.observe(this._champ, "change", this._test.bindAsEventListener(this));
		
		pChamp = null;
		pChampB = null;
		pDifference = null;
		pComparison = null;
		pErrorMessage = null;
		pErrorContainer = null;
		pLangue = null;
		
	},
	
	//Methodes
	
	_test : function(){
		
		var df = new DatePickerFormatter(
			this._language_date_format[this._langue][0],
			this._language_date_format[this._langue][1]
		);
		
		var valueA = this._champ.value;
		var valueB = (!this._champB) ? df.current_date() : this._champB.value;

		if(!valueA || !valueB){
			return;
		}
		
		//Recuperer les valeurs, Annee, Mois, Jour
		var dateA_values = df.match(valueA);
		if(!dateA_values){
			return this._showError("Date invalide !!");
		}else{
			this._removeError("Date invalide !!");
		}
		var dateB_values = df.match(valueB);
		if(!dateB_values){
			return this._showError("Date invalide !!");
		}else{
			this._removeError("Date invalide !!");
		}
		//Cr?er les objets Date
		var dateA = new Date(dateA_values[0], (dateA_values[1]-1), dateA_values[2]);
		var dateB = new Date(dateB_values[0], (dateB_values[1]-1), dateB_values[2]);
		
		//TEST
		var diffAB = (dateA-dateB);
		var arrComparisons = this._comparisons;
		var diff = this._difference;
		var boolTestOk = true;
		
		this._comparison.each( function (item){
			var testString = "";
			if(item == "DIFF_POSITIF"){
				testString = (diffAB + arrComparisons[item]);
			}else{
				testString = (diffAB + arrComparisons[item] + diff);
			}
			boolTestOk = eval(testString);
			if(!boolTestOk){
				throw $break;
			}
		});
		
		if(boolTestOk){
			return this._removeError();
		}else{
			return this._showError();
		}
	
	},
	
	//Override "toString" methode
	toString : function(){ return "[object 'TestDateDifference' : extends 'FieldValidation' ]"; }
	
});

/* Copier un valeur d'un champ ? un autre */
var CopyFieldValue = Class.create();
CopyFieldValue.prototype = Object.extend(new FieldValidation(), {
	
	_champB					: null,
	_valueA 				: null,
	_testDate				: false,
	_valueType				: "VALUE",
	_dateFormat 			: [ ["mm", "dd", "yyyy"], "/" ],
	_language_date_format 	: $H({
		"en": [ ["mm", "dd", "yyyy"], "/" ],
		"lt": [ ["yyyy", "mm", "dd"], "-" ],
		"fr": [ ["dd", "mm", "yyyy"], "/" ],
		"sp": [ ["dd", "mm", "yyyy"], "/" ],
		"it": [ ["dd", "mm", "yyyy"], "/" ],
		"de": [ ["dd", "mm", "yyyy"], "/" ],
		"pt": [ ["dd", "mm", "yyyy"], "/" ],
		"hu": [ ["dd", "mm", "yyyy"], "/" ],
		"nl": [ ["dd", "mm", "yyyy"], "-" ]
	}),

	initialize : function(pChamp,pChampB,pTestDate,pLangue,pErrorMessage,pErrorContainer,pValueType){
	
		if(!pChamp || !pChampB){
			return;
		}
		this._champA = $(pChamp);
		this._champB = $(pChampB);
		
		if(!this._champA || !this._champB){
			return;
		}
		this._errorMessage = (!pErrorMessage) ? "" : pErrorMessage;
		this._errorContainer = (!pErrorContainer) ? null : $(pErrorContainer);
		if(pTestDate){
			this._testDate = pTestDate;
		}
		if(pLangue){
			this._langue = pLangue;
		}
		if(pValueType){
			this._valueType =pValueType;
		}
			
		// Ne marche pas avec la touche "Tabulation" : Event.observe(this._champA, "change", this._copy.bindAsEventListener(this));
		Event.observe(this._champA, "blur", this._copy.bindAsEventListener(this));
		Event.observe(this._champA, "change", this._copy.bindAsEventListener(this));
	},
	
	_update : function(){
		this._valueA = this._champA.value;
		if(!this._valueA){
			return;
		}
		//V?rifier que le valeur est un date valide
		if(this._testDate){
			
			var df = new DatePickerFormatter(
				this._language_date_format[this._langue][0],
				this._language_date_format[this._langue][1]
			);
			
			var dateA_values = df.match(this._valueA);
			if(!dateA_values){
				return this._showError("Date invalide !!");
			}else{
				this._removeError("Date invalide !!");
			}
		}
		
		//COPY LABEL ET PAS VALUE
		if(this._champA.tagName.toUpperCase() == "SELECT" && this._valueType == "LABEL"){
			this._valueA = this._champA.options[this._champA.selectedIndex].text;
		}
		
		this._champB.value = this._valueA;
	},
	
	_copy : function(){
		setTimeout( this._update.bind(this), 500);
	},
	
	//Override "toString" methode
	toString : function(){ return "[object 'TestDateDifference' : extends 'FieldValidation' ]"; }
});

/* V?rifier que la somme est plus ou egale ? un valeur */
var TestFieldTotals = Class.create();
TestFieldTotals.prototype = Object.extend(new FieldValidation(), {
	
	//Attributs
	_champs			: new Array(),
	_valeur 		: 0,
	_comparison 	: $H({
						"GT"	: ">",
						"GTE"	: ">=",
						"LT"	: "<",
						"LTE"	: "<=",
						"DIFF_POSITIF"	: ">=0"
	}),
	_errorMessage	: "",
	_errorContainer : "",
	
	//Initialize
	initialize : function (pValeur, pComparison, pFields, pErrorMessage, pErrorContainer) {
		
		if( (!pValeur || isNaN(pValeur)) 
			|| (!pComparison) 
			|| (!pFields || (pFields.indexOf("|") == -1)) ){
				return;
		}
		
		this._valeur = parseInt(pValeur);
		this._champs = $A(pFields.split("|"));
		this._comparison = this._comparison[pComparison];
		this._errorMessage = (!pErrorMessage) ? "" : pErrorMessage;
		this._errorContainer = (!pErrorContainer) ? null : $(pErrorContainer);
		
		var testMethod = this._test;
		var obj = this;
		this._champs.each( function (item) {
			Event.observe(item, "change", testMethod.bindAsEventListener(obj));
		});
		
	},
	
	//Methodes
	_test : function(){
		var _somme = 0;
		var _valeur = this._valeur;
		
		//Somme
		this._champs.each( function (item) {
			_somme = _somme + parseInt($F(item));
		});
		
		var boolTestOk = false;
		var testString = _somme + this._comparison + _valeur;
		boolTestOk = eval(testString);
		
		if(boolTestOk){
			return this._removeError();
		}else{
			return this._showError();
		}
	},
	
	//Override "toString" methode
	toString : function(){ return "[object 'TestFieldTotals' : extends 'FieldValidation']"; }
});

/* Empecher l'utilisateur de coller un texte dans un champ */
var BlockPasteValue = Class.create();
BlockPasteValue.prototype = Object.extend(new FieldValidation(), {
	
	//Attributs
	_champ				: null,
	_errorMessage		: "Le fonction copie/coller est proscrite pour ce champ.",
	_errorContainer		: "",
	_textErrorColor		: "#FF0000",
	_textNormalColor	: "#000000",
	_vKey 				: 86,
	
	//Initialisation
	initialize : function(pChamp,pMessage){
		if(!pChamp){
			return;
		}
		this._champ = $(pChamp);
		if(pMessage){
			this._errorMessage = pMessage;
		}
		Event.observe(this._champ, "keydown", this._checkCopyPaste.bind(this));
	},
	
	//Methodes
	_checkCopyPaste : function(pEvent){
		if( (pEvent.ctrlKey) && (pEvent.keyCode == this._vKey) ){
			Event.stop(pEvent);
			this._champ.style.color = this._textErrorColor;
			this._champ.value = this._errorMessage;
			this._champ.select();
			return false;
		} else {
			this._champ.style.color = this._textNormalColor;
			return true;
		}
	},
	
	//Override "toString" methode
	toString : function(){ return "[object 'BlockPasteValue' : extends 'FieldValidation' ]"; }
});

/* Copier un valeur d'un champ ? un autre */
var GetFieldDifference = Class.create();
GetFieldDifference.prototype = Object.extend(new FieldValidation(), {
	
	_champB					: null,
	_champOut				: null,
	_valueA					: null,
	_valueB					: null,
	_testDate				: false,
	_dateFormat				: [ ["mm", "dd", "yyyy"], "/" ],
	_language_date_format 	: $H({
		"en": [ ["mm", "dd", "yyyy"], "/" ],
		"lt": [ ["yyyy", "mm", "dd"], "-" ],
		"fr": [ ["dd", "mm", "yyyy"], "/" ],
		"sp": [ ["dd", "mm", "yyyy"], "/" ],
		"it": [ ["dd", "mm", "yyyy"], "/" ],
		"de": [ ["dd", "mm", "yyyy"], "/" ],
		"pt": [ ["dd", "mm", "yyyy"], "/" ],
		"hu": [ ["dd", "mm", "yyyy"], "/" ],
		"nl": [ ["dd", "mm", "yyyy"], "-" ]
	}),
	
	initialize : function(pChamp,pChampB,pChampC,pTestDate,pLangue){
		
		if(!pChamp || !pChampB || !pChampC){
			return;
		}
		this._champA = $(pChamp);
		this._champB = $(pChampB);
		this._champOut = $(pChampC);
		
		if(pTestDate){
			this._testDate = pTestDate;
		}
		if(pLangue){
			this._langue = pLangue;
		}
		Event.observe(this._champA, "change", this._calcul.bindAsEventListener(this));
		Event.observe(this._champB, "change", this._calcul.bindAsEventListener(this));
	},
	
	_calcul : function(){
		
		this._valueA = this._champA.value;
		this._valueB = this._champB.value;

		if(!this._valueA || !this._valueB){
			this._champOut.value = "";
			return;
		}
		
		var diff = 0;
		
		if(this._testDate){
			
			var df = new DatePickerFormatter(
				this._language_date_format[this._langue][0],
				this._language_date_format[this._langue][1]
			);
			
			var dateA_values = df.match(this._valueA);
			var dateB_values = df.match(this._valueB);
			
			//Cr?er les objets Date
			var dateA = new Date(dateA_values[0], (dateA_values[1]-1), dateA_values[2]);
			var dateB = new Date(dateB_values[0], (dateB_values[1]-1), dateB_values[2]);
			
			if(dateA > dateB){
				this._champOut.value = "";
				return;
			}
			
			//Difference en MS
			diff = (dateB-dateA);
			
			//Convertir en jours...
			diff = Math.floor((diff/86400000));
			
		} else {
			if(isNaN(this._valueA) || isNaN(this._valueB)){
				return;
			}
			diff = Math.abs(parseInt(this._valueA) - parseInt(this._valueB));
		}
		
		if(this._champOut){
			this._champOut.value = diff;
		}

 	},
	
	//Override "toString" methode
	toString : function(){ return "[object 'GetFieldDifference' : extends 'FieldValidation' ]"; }
	
});


