// Être compatible avec MSIE...

if ('undefined' == typeof Node)
    Node = { ELEMENT_NODE: 1, TEXT_NODE: 3 };

MSG_BLANK = ' est vide.';
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_TOO_LOW = ' est trop petit(e).';
MSG_TOO_HIGH = ' est trop grand(e).';


REGEX_AUTO_FIELD = /^[^_]+(_Req)?(_(Int|Dbl|Date)(_[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])$/;
// Les multiples groupes vont nous découper l'ID tout seuls...
REGEX_TYPED_FIELD = /_(Int|Dbl|Date)(_([0-9.]+))?(_([0-9.]+))?$/;
REGEX_YEAR = /^[0-9]{2,4}$/;

function addListener(element, baseName, handler) {
    if (element.addEventListener)
        element.addEventListener(baseName, handler, false);
    else if (element.attachEvent)
        element.attachEvent('on' + baseName, handler);
} // addListener

function addFormChecks() {
    var forms = document.forms;
    for (var index = 0; index < forms.length; ++index) {
        var form = forms.item(index);
        addListener(form, 'submit', checkForm);
    }
} // addFormChecks

function checkForm(e) {
    // Compatibilité MSIE / les autres...
    e = e || window.event;
    var form = e.target || e.srcElement;
    var errors = '';
    var faulty = null;
    for (var index = 0; index < form.elements.length; ++index) {
        var field = form.elements.item(index);
        // Vérification de syntaxe
        if (!field.id.match(REGEX_AUTO_FIELD))
            continue;
        var value = getFieldValue(field);
        // Champ requis ?
        if (field.id.match(/_Req/) && value.match(REGEX_BLANK)) {
            errors += getFieldName(field) + MSG_BLANK + '\n';
            faulty = faulty || field;
            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 = checkTypedField(value, type, min, max);
	    if (error) {
		errors += getFieldName(field) + error + '\n';
		faulty = faulty || field;
	    }
	}
    }
    if (!faulty)
        return;
    stopEvent(e);
    alert(errors);
    faulty.focus();
} // checkForm

function getFieldName(field) {
    var label = 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;
        }
    }
    return text;
} // getFieldName

function getFieldValue(field) {
    if ('INPUT' == field.tagName)
        return field.value;
		if ('TEXTAREA' == field.tagName)
        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 '';
} // getFieldValue

function getLabelFor(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;
} // getLabelFor

function stopEvent(e) {
    if (e.stopPropagation) {
        e.stopPropagation();
        e.preventDefault();
    } else {
        e.cancelBubble = true;
        e.returnValue = false;
    }
} // stopEvent

addListener(window, 'load', addFormChecks);

