// Per compatibilità con MSIE...
if ('undefined' == typeof Node)
    Node = { ELEMENT_NODE: 1, TEXT_NODE: 3 };

MSG_BLANK = ' è vuoto.';
MSG_NOCHECK = 'Devi selezionare "';
MSG_NOT_A_DATE = ' non è una data.';
MSG_NOT_A_DOUBLE = ' non è un numero.';
MSG_NOT_AN_INTEGER = ' non è un numero intero.';
MSG_NOT_AN_EMAIL = ' non è un indirizzo email.';
MSG_NOT_VALID = ' non è un valore valido.';
MSG_TOO_LOW = ' è troppo piccolo.';
MSG_TOO_HIGH = ' è troppo grande.';

REGEX_AUTO_FIELD = /^[^_]+(_Req)?(_(Int|Dbl|Date|Email|UserPass)(_[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|Email|UserPass)(_([0-9.]+))?(_([0-9.]+))?$/;
REGEX_YEAR = /^[0-9]{2,4}$/;

function checkForm(e) {
	Event.stop(e);
	var form= Event.element(e);
    var errors = '';
    var faulty = null;
    for (var index = 0; index < form.elements.length; ++index) {
		var field = form.elements.item(index);
        // Verifica sintassi
        if (!field.id.match(REGEX_AUTO_FIELD))
            continue;
        var value = $F(field);
        // Campo obbligatorio?
        if (field.id.match(/_Req/)){
			//type text
			if(field.type=="text" && value.match(REGEX_BLANK)) {
            errors += getFieldName(field) + MSG_BLANK + '\n';
            faulty = faulty || field;
            continue;
			}
			//type checkbox
			if(field.type=="checkbox" && !field.checked) {
            errors += MSG_NOCHECK + getFieldName(field) + '".\n';
            faulty = faulty || field;
            continue;
			}
        }
		// Campo tipizzato?
		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;
				continue;//così altri controlli lo fa solo se non sono stati trovati errori fin qui
			}
		}
		
		//ulteriori controlli particolari a seconda del campo
		var error=altriControlli(field, value, form.id);
		if (error) {
			errors += getFieldName(field) + error + '\n';
			faulty = faulty || field;
		}
		
	}//chiude il for

	//ultimi controlli fuori dal for
	var error=altriControlli('', '', form.id);
	if (error) {
		errors += error + '\n';
	}
	
	if (!faulty){
		form.submit();
	}else{
		alert(errors);
		faulty.focus();
	}
} // checkForm

function checkTypedField(value, type, min, max) {
    // Valori predefiniti
    min = min || Number.NEGATIVE_INFINITY;
    max = max || Number.POSITIVE_INFINITY;
    var val;
    if ('Int' == type) {
		if(value){
			try {
				val = parseInt(value, 10);
			if (String(val) != value)
				throw val;
			} catch (e) {
				return MSG_NOT_AN_INTEGER;
			}
		}
    }
    if ('Dbl' == type) {
   		if(value){
			try {
				val = parseFloat(value);
			if (String(val) != value)
				throw val;
			} catch (e) {
				return MSG_NOT_A_DOUBLE;
			}
		}
    }
    if ('Int' == type || 'Dbl' == type) {
		if(value){
			if (val < min)
				return MSG_TOO_LOW;
			if (val > max)
				return MSG_TOO_HIGH;
		}
    }
    if ('Date' == type) {//formato aaaa-mm-gg
		if(value){
			var comps = value.split('-');
			if (3 != comps.length || !comps[2].match(REGEX_DAY) ||
				!comps[1].match(REGEX_MONTH) ||
				!comps[0].match(REGEX_YEAR))
				return MSG_NOT_A_DATE;
		}
    }
    if ('Email' == type) {
		if(value){
			pattern=/^[a-z0-9][_\.a-z0-9-]+@([a-z0-9][0-9a-z-]+\.)+([a-z]{2,4})$/;
			if(!pattern.exec(value)){
				return MSG_NOT_AN_EMAIL;
			}
		}
    }
    if ('UserPass' == type) {
		if(value){
			pattern=/^[a-zA-Z0-9_.-]+$/;
			if(!pattern.exec(value)){
				return MSG_NOT_VALID;
			}
		}
    }
    return null;
} // checkTypedField

function getFieldName(field) {
    //console.log(field);
	var label = getLabelFor(field);
    if (!label)
        return field.name;
    var text = '';
    var node = label.firstChild;
    // Percorso in profondità, eliminata la ricorsione, del frammento sotto l'etichetta
    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 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
