// Requires amutils.js, should possibly be integrated into that file.
// Currently requires 'textbox1err', 'textbox1' classes to be defined
// If you want the error message to be put out, you need Error.message and Error.wrapper elements.


var amvalidate_checks = new Array();
var amvalidate_labels = new Array();
var amvalidate_custom = new Array();

/**
 * Register a function to be called to perform custom validation.
 * The function should return an array of error messages to be
 * appended to any other errors.
 */
function am_validate_register(formId, f) {
    amvalidate_custom[formId] = f;
}

/**
 * am_validate_require(formId, elementId, label, [nameOfValidationCheck ...])
 * label is the pretty name of the label
 */
function am_validate_require(formId, elementId, label) {

    // Create an array to hold validations for this element if we
    // haven't already declared some.
    if (typeof(amvalidate_checks[formId]) == 'undefined') {
        amvalidate_checks[formId] = new Array();
        amvalidate_labels[formId] = new Array();
    }
    if (typeof(amvalidate_checks[formId][elementId]) == 'undefined') {
        amvalidate_checks[formId][elementId] = new Array();
        amvalidate_labels[formId][elementId] = label;
    }

    // Append any checks that were specified to the array of checks for
    // the specified element
  	for (var i = 3; i < arguments.length; i++) {
        amvalidate_checks[formId][elementId].append(arguments[i]);
  	}
}

/**
 * Called by the submit button, returns true if the form can be 
 * submitted, otherwise returns false, highlights problem fields with
 * an error class (which we should turn into an optional param prob.)
 * and optionally displays an error message.  If checkall is 0, stops
 * as soon as it finds a validation error, otherwise, checks all
 * registered validations.
 */
function am_validate_form(formId, checkall) {
    var result = true;
    am_hide('Error.wrapper');

    var elements = amvalidate_checks[formId];
    var errors = new Array();

    for (elementId in elements) {
        // Iterating with 'for..in' unfortunately includes the functions
        // that amutils added to the array prototype.
        if (Array.prototype[elementId]) { continue; }

        // Reset any error formatting from a previous run.
        var el = document.getElementById(elementId);
        am_replaceClassName(el, 'textbox1err', 'textbox1');

        // Perform each check.
        var checks = amvalidate_checks[formId][elementId];
        var label = amvalidate_labels[formId][elementId];
        for (var i = 0; i < checks.length; i++) {
            var check = checks[i];
            try {
                // _am_validate_element_$check($elementId, $label)
                eval('_am_validate_element_' + check.toLowerCase() + '(\'' + elementId + '\', \'' + label + '\')');
            } catch (e) {
                result = false;
                errors.append(e);
                am_replaceClassName(el, 'textbox1', 'textbox1err');
                if (!checkall) { break; }
            }
        }
    }
    
    // If we have been given a custom validator proc to run for this
    // form, take note of any errors it returns.
    if (typeof(amvalidate_custom[formId]) != 'undefined') {
        var custom_errors = eval(amvalidate_custom[formId] + '()');
        if (custom_errors.length > 0) {
            errors = errors.concat(custom_errors);
            result = false;
        }
    }

    if (!result) {
        var msg = document.getElementById('Error.message');
        if (msg) {
            msg.innerHTML = errors.join('<br>\n');
        }
        am_show('Error.wrapper');
        am_firstFocus('textbox1err');
    }
    // Note: Once the validation library is more comprehensive it may
    // be cleaner to submit the form here, since we know its id and the
    // programmer then just has to write something like:
    // onClick="return am_validate_form('infoRequest', 1);"
    // But we don't do that know because there may be extra validation
    // required before submitting.
    return result;
}

/**
 * The procedures below are validation filters.  They are named
 * _am_validate_element_ + filter, e.g. if the validation was declared
 * as am_validate_require('infoRequest', 'Name', 'NotBlank'); then
 * _am_validate_element_notblank would get called to validate the
 * element with id 'Name'.
 */

function _am_validate_element_notblank(elementId, label) {
    if (document.getElementById(elementId).value.length == 0) {
        throw "Please enter " + label;
    }
}

// Ensure that the field is a positive integer (commas OK)
function _am_validate_element_posint(elementId, label) {
    var val = document.getElementById(elementId).value;
    if (val == '') return;
    val = val.replace(/[\s]/g,'');
    if (val.match(/[^\d]/) || parseInt(val) < 0) {
        throw label + " must be a number greater than zero";
    }
}
function _am_validate_element_posintwithcommas(elementId, label) {
    var val = document.getElementById(elementId).value;
    if (val == '') return;
    val = val.replace(/[,\s]/g,'');
    if (val.match(/[^\d]/) || parseInt(val) < 0) {
        throw label + " must be a number greater than zero";
    }
}

// If a non-'' string given, check that it looks like an email addr and
// isn't a hotmail account.  Use in combination with NotBlank to check
// for non-Empty and valid email address.
function _am_validate_element_email(elementId, label) {
    var str = document.getElementById(elementId).value;
    if (str.length == 0) { return; }
    var index = str.indexOf("@");
    if (index <= 0) {
        throw "Please enter a complete email address in the form: yourname@yourdomain.com"
    }
    var pindex = str.indexOf(".", index);
    if ((pindex <= index+1) || (str.length <= pindex+1)) {
        throw "Please enter a complete email address in the form: yourname@yourdomain.com"
    }
    var index = str.toLowerCase().indexOf("hotmail");
    if (index > 0) {
        throw "Hotmail addresses are not allowed. Please use another."
    }
}

