REGEX_AUTO_FIELD = /^[^_]+(_Req)?(_(Int|Dbl|Date|Mail)(_[0-9.]+){0,2})?$/;
REGEX_BLANK = /^\s*$/;
REGEX_DAY = /^(0?[1-9]|[1-2][0-9]|3[01])$/;
REGEX_MONTH = /^(0?[1-9]|1[0-2])$/;
REGEX_TYPED_FIELD = /_(Int|Dbl|Date|Mail)(_([0-9.]+))?(_([0-9.]+))?$/;
REGEX_YEAR = /^[0-9]{2,4}$/;

MSG_BLANK = 'doit être renseigné.';
MSG_NOT_A_DATE = 'n\'est pas une date.';
MSG_NOT_A_DOUBLE = 'n\'est pas un nombre.';
MSG_NOT_AN_INTEGER = 'n\'est pas un nombre entier.';
MSG_NOT_A_VALID_MAIL = 'n\'est pas une adresse e-mail valide.';
MSG_TOO_LOW = 'est trop petit(e).';
MSG_TOO_HIGH = 'est trop grand(e).';

/* Declaration de la classe FormChecker */
var myFormsChecker;
var FormsChecker = Class.create();
FormsChecker.prototype = {  
    myForms: null,
    /**
     * Constructeur
     */
    initialize: function() { 
        var forms = document.forms;
        for (var index = 0; index < forms.length; ++index) {
            var form = document.forms[index];
            //addListener(form, 'submit', checkForm);
            myFormChecker = new FormChecker(form);
        }
    }
}


/* Declaration de la classe FormChecker */
var myFormChecker;
var ajaxCallback = null;
var FormChecker = Class.create();
FormChecker.prototype = {  
    //Declaration des variables
    internErrorDisplay: true,
    formId: null,
    formElt: null,
    formErrors: [],
    displayErrorType: 'alert',
    errorAlertMsg: 'Les éléments suivants nécéssitent votre attention avant de poursuivre :\n',
    callbackFunction: null,
    /**
     * Constructeur
     */
    initialize: function(form_id, submitFunc) { 
        
        this.callbackFunction = submitFunc;
        this.formId = form_id;
        //Test de l'existence du formulaire
        if (!$(this.formId)) {
            if (this.internErrorDisplay) {
                alert ('Erreur : aucun formulaire ne corresond à l\'identifiant renseigné.');
            }
            return;
       }
       this.formElt = $(this.formId);
       this.listenToSubmission();
    },
    listenToSubmission: function() {
        var obj = this;
        Event.observe(obj.formElt, 'submit', obj.checkForm, false);
    },
    checkForm: function(event) {
        Event.stop(event);
        var formToCheck = Event.element(event);
        var formName = formToCheck.name;
        var formErrors = [];
        var errorsIndex = 0;
        var faulty = null;
        
        
        for (var index = 0; index < formToCheck.elements.length; ++index) {
            var field = formToCheck.elements.item(index);
            // Verification de syntaxe
            if (!field.id.match(REGEX_AUTO_FIELD))
                continue;
            var value = FormChecker.prototype.getFieldValue(field);
            // Champ requis ?
            var aChecker = true;
            if (field.id == 'utilisateurTaillejardin_Req') {
                if ($('utilisateurJardin').checked == false) var aChecker = false;
            }
            if (aChecker) {
	            if (field.id.match(/_Req/) && value.match(REGEX_BLANK)) {
	                //alert ('champ requis');
	                var error = '';
	                if ($(formName).hasClassName('php')) {
	                   if (eval('MSG_'+field.id) != '') {
		                    error = eval('MSG_'+field.id)+'';
		                }
		                else {
		                    error = FormChecker.prototype.getFieldName(field)+''+MSG_BLANK+'';
		                }
		            }
		            else {
		              error = FormChecker.prototype.getFieldName(field)+''+MSG_BLANK+'';
		            }
	                formErrors[errorsIndex] =  error;
	                faulty = faulty || field;
	                errorsIndex++;
	                continue;
	            }
	        }
            // Champ typé ?
            var match = field.id.match(REGEX_TYPED_FIELD);
            if (match) {
                var type = match[1];
                var min = match[3];
                var max = match[5];
                var error = FormChecker.prototype.checkTypedField(value, type, min, max);
                if (error) {
                    //alert ('champ erroné');
                    var err = '';
	                if (eval('MSGINVALID_'+field.id) != '')
	                    err = eval('MSGINVALID_'+field.id)+'';
	                else
	                    err = FormChecker.prototype.getFieldName(field)+''+MSG_BLANK+'';
                    formErrors[errorsIndex] =  err;
                    faulty = faulty || field;
                    errorsIndex++;
                }
            }
        }
        if (!faulty) {
            if (myFormChecker.callbackFunction != undefined) {
                eval(myFormChecker.callbackFunction);
            }
            else {
                mySubmitFormHandler = new SubmitFormHandler(formToCheck);
            }
        }
        else {
            //faulty.focus();
            FormChecker.prototype.displayErrors(formErrors);
        }
    },
    
    displayErrors: function(formErrors) {
        switch (this.displayErrorType) {
            default:
            case "alert":
                 var errorMsg = this.errorAlertMsg;
                 for (var i=0; i < formErrors.length; i++) {
                    errorMsg += '- '+formErrors[i]+'\n';
                 }
                 alert (errorMsg);
            break;
        }
       
    },
    
    checkTypedField: function(value, type, min, max) {
        // Valeurs par defaut pour les bornes
        min = min || Number.NEGATIVE_INFINITY;
        max = max || Number.POSITIVE_INFINITY;
        var val;
        if ('Int' == type) {
            try {
                val = parseInt(value, 10);
            if (String(val) != value)
                throw val;
            } catch (e) {
                return MSG_NOT_AN_INTEGER;
            }
        }
        if ('Dbl' == type) {
            try {
                val = parseFloat(value);
            if (String(val) != value)
                throw val;
            } catch (e) {
                return MSG_NOT_A_DOUBLE;
            }
        }
        if ('Int' == type || 'Dbl' == type) {
            if (val < min)
                return MSG_TOO_LOW;
            if (val > max)
                return MSG_TOO_HIGH;
        }
        if ('Date' == type) {
            var comps = value.split('/');
            if (3 != comps.length || !comps[0].match(REGEX_DAY) ||
                !comps[1].match(REGEX_MONTH) ||
                !comps[2].match(REGEX_YEAR))
                return MSG_NOT_A_DATE;
        }
        if ('Mail' == type) {
           testm = true;
           if (value != '') {
               testm = false ;
               for (var j=1 ; j<(value.length) ; j++) {
                   if (value.charAt(j)=='@') {
                       if (j<(value.length-4)){
                           for (var k=j ; k<(value.length-2) ; k++) {
                               if (value.charAt(k)=='.') testm = true;
                           }
                       }
                   }
               }
           }       
           if (testm==false) return MSG_NOT_A_VALID_MAIL;
       }
        return null;
    },
        
    getFieldName: function(field) {
        var label = FormChecker.prototype.getLabelFor(field);
        if (!label)
            return field.name;
        var text = '';
        var node = label.firstChild;
        // Parcours en profondeur, d�r�cursifi�, du fragment sous le libell�
        while (true) {
            if (Node.ELEMENT_NODE == node.nodeType && node.hasChildNodes())
                node = node.firstChild;
            else if (Node.TEXT_NODE == node.nodeType)
                text += node.nodeValue;
            if (node.nextSibling)
                node = node.nextSibling;
            else {
                node = node.parentNode;
                if (node == label)
                    break;
                node = node.nextSibling;
            }
        }
        text = text.replace(':', '');
        return text.replace('*', '');
    },
    getFieldValue: function(field) {
        if ('INPUT' == field.tagName || 'TEXTAREA' == field.tagName) {
            if (field.type == "checkbox"){
              if (field.checked)
                  return "1";
              else
                  return '';
            }
            /*else if (field.type == "radio"){
              //alert (field.id);
              if (field.checked)
                return Form.Element.getValue(field);
              else
                return '';
            }*/
            else
                return field.value;
        }
        if ('SELECT' == field.tagName) {
            var value = '';
            if (-1 < field.selectedIndex) {
                var opt = field.options[field.selectedIndex];
                value = opt.value;
                if (!value && !('value' in opt))
                    value = opt.text;
            }
            return value;
        }
        return '';
    },
    getLabelFor: function(field) {
        var labels = document.getElementsByTagName('label');
        for (var index = 0; index < labels.length; ++index) {
            var label = labels.item(index);
            if (label.htmlFor == field.id)
                return label;
        }
        return null;
    }
}

Event.observe(window, 'load', initForms, false);
function initForms() {
    myFormsChecker = new FormsChecker();
}