// General form validation class.
//
// formId is the ID of the form to be validated.
//
// fields is an array of FieldValidator objects.
function FormValidator(formId, fields) {
    this._isValid = true;
    this._fields = fields;

    // Attach this validator to the form's onsubmit event.
    var form = document.getElementById(formId);
    if (form != null) {
        formValidator = this;
        form.onsubmit = function() {
            return formValidator.onSubmit(form);
        }
    }   
}

// Listens for the form's onsubmit event and passes it on to the
// FieldValidator objects.  Returns true if all the fields are valid.
FormValidator.prototype.onSubmit = function(form) {
    this._isValid = true;
    for (var i = 0; i < this._fields.length; i++) {
        if (!this._fields[i].onSubmit(form)) {
            this._isValid = false;
        }
    }
    if (!this._isValid) {
        alert('Please fill in / correct the highlighted fields before submitting again.');
    }
    return this._isValid;
}


// Class to apply a validation function to a field or fields.
//
// fieldNames is an array of the names of the fields passed as
// arguments to checkValid.
// 
// isRequired is set to true if the field can't be empty.
//
// checkValid is a function that returns true if the field is valid.
// It takes any number of fields as arguments.  The first field is the
// one that will be highlighted if it is invalid.
function FieldValidator(fieldNames, isRequired, validCheck) {

    // Status flags.
    this._isEmpty    = false;
    this._isValid    = true;

    this._fieldNames = fieldNames;
    this._isRequired = isRequired;
    this._validCheck = validCheck;
}


// Listens (via FormValidator.onSubmit()) for the form's onsubmit
// event and highlights the field it is validating if it's not valid.
// Returns true if the field is valid.
FieldValidator.prototype.onSubmit = function(form) {
    var fields = [];
    for(i = 0; i < this._fieldNames.length; i++) {
        fields[i] = form[this._fieldNames[i]];
    }
    if (this._isEmpty = this._emptyCheck(fields[0])) {
        this._isValid = !this._isRequired;
    } else {
        this._isValid = this._validCheck.apply(this, fields);
    }

    // Set or clear the 'invalid' class.
    var className = fields[0].className;
    if (this._isValid) {
        className = className.replace(/invalid/, '');
    } else {
        if (className.search(/invalid/) == -1) {
            className += ' invalid';
        }
    }
    fields[0].className = className;

    return this._isValid;
}

FieldValidator.prototype._emptyCheck = function(field) {
    return (field.value.search(/\S/) == -1);
}
