// Revision: $Revision: 1.12 $
var VAL_failed_fields = new Array ();
var VAL_saved_color = '';

function validateForm ()
{
    var i;
    var value;
    var validation;
    var errors = new Array ();

    if  (this.validation == null)
    {
        return true;
    }

    var obj;
    var len = VAL_failed_fields.length;
    var color = VAL_saved_color;
    if  (color == '')   color = '#000000';
    for (i = 0; i < len; i++)
    {
        obj = document.getElementById('x_id__' + VAL_failed_fields[i]);
        if  (obj != null)
            obj.style.color = VAL_saved_color;
    }
    VAL_failed_fields.length = 0;

    var p_val = this.validation.data;

    // For each field in validation array
    for (i = 0; i < p_val.length; i++)
    {
        // Save the size of errors array - later we'll use it to determine
        // if validation of current field failed
        len = errors.length;
        validation = p_val[i];
        //  Get current field value
        value = getCurrentValue (this, validation.field);

        // Check 'required' flag
        if  ((validation.required != null)&&(validation.required != '0')&&
             (value.length == 0))
        {
            errors.push('No data is provided for field "' +
                validation.label + '"');
        }

        // Now check field type
        if  (validation.type == 'numeric')
        {
            //  Make sure it's a number
            if  (value.match(/\D/))
                errors.push('Field "' + validation.label +
                    '" can contain only digits');

            //  Check for minimum value
            if  ((validation.min != null)&&(value.length > 0))
            {
                if  (value < validation.min)
                    errors.push('Value of field "' + validation.label +
                        '" is too small. Minimum value is ' + validation.min);
            }
            //  Check for maximum value
            if  ((validation.max != null)&&(value.length > 0))
            {
                if  (value > validation.max)
                    errors.push('Value of field "' + validation.label +
                        '" is too large. Maximum value is ' + validation.max);
            }
        }

        if  (validation.type == 'money')
        {
            var amount = value.replace(/^\s*\$/, '');
            //  Make sure it's a number
            if  ((amount.match(/^\d+$/) == null)&&
                 (amount.match(/^\d+\.\d?\d?$/) == null))
                errors.push('Field "' + validation.label +
                    '" should contain a number prefixed by optional "$" character');

            //  Check for minimum value
            if  ((validation.min != null)&&(value.length > 0))
            {
                if  (amount < validation.min)
                    errors.push('Value of field "' + validation.label +
                        '" is too small. Minimum value is ' + validation.min);
            }
            //  Check for maximum value
            if  ((validation.max != null)&&(value.length > 0))
            {
                if  (amount > validation.max)
                    errors.push('Value of field "' + validation.label +
                        '" is too large. Maximum value is ' + validation.max);
            }
        }

        // Validation of ZIP codes
        if  (validation.type == 'zip')
        {
            //  ZIP validation should be done for US
            var country = validation.country;
            if  (country != null)
            {
                if  (eval('this.' + country) != null)
                {
                    country = getCurrentValue (this, country);
                    if  ((country.match(/^\s*United\s+States/i))||
                         (country.match(/^\s*USA?\s*$/i)))
                            country = '840';
                }
                else
                    country = '840';
            }
            else
                country = '840';
            if  (country == '840')
            {
                if  ((value.length > 0)&&(value.length != 5))
                {
                    errors.push('Field "' + validation.label +
                        '" should contain 5-digit ZIP code.');
                }
                else
                {
                    //  Make sure it's a number
                    if  (value.match(/\D/))
                        errors.push('Field "' + validation.label +
                            '" can contain only digits');
                }
            }
        }

        // Now check field type
        if  (validation.type == 'ccnumber')
        {
            var cctype = eval('form_object.' + validation.cctype);
            cctype = (cctype == null)? validation.cctype: cctype.value;
            var error = validateCCNumber(value, cctype);
            if  (error != '')
                errors.push("Field '" + validation.label +
                    "' contains invalid data: " + error);
        }

        if  ((value != '')&&(validation.type == 'email'))
        {
            // Make sure it's an e-mail
            // Validation code is vary simple, as it was taken from CAjsform.js
            if (!value.match(/\w+-*@\w+/)||(value.match(/\w+\,\w+/)))
                errors.push('Field "' + validation.label +
                    '" should be a valid e-mail address');
        }

        //  Check for alphanumeric type
        if  ((validation.type == 'alphanumeric')&&
             (value.search("^[0-9A-Za-z]*$") == null))
        {
            errors.push('Field "' + validation.label +
                '" can contain only alphanumeric characters');
        }

        //  Check for alphabetic type
        if  ((validation.type == 'alphabetic')&&
             (value.search("^[A-Za-z]*$") == null))
        {
            errors.push('Field "' + validation.label +
                '" can contain only alphabetic characters');
        }

        //  Check for minimum length
        if  ((validation.minlength != null)&&
             (value.length < validation.minlength)&&
             (value.length > 0))
        {
            errors.push('Text in the field "' + validation.label +
                '" is too short. Minimum length is ' +
                validation.minlength + ' characters');
        }
        //  Check for maximum length
        if  ((validation.maxlength != null)&&
             (value.length > validation.maxlength))
        {
            errors.push('Text in the field "' + validation.label +
                ' is too long. Maximum length is ' +
                validation.maxlength + ' characters');
        }
        if  (len < errors.length)
            VAL_failed_fields.push(validation.field);
    }

    if  (errors.length > 0)
    {
        len = VAL_failed_fields.length;
        for (i = 0; i < len; i++)
        {
            obj = document.getElementById('x_id__' + VAL_failed_fields[i]);
            if  (obj == null)  continue;
            if  (VAL_saved_color == '')
                VAL_saved_color = obj.style.color;
            obj.style.color = '#C00000';
        }

        //  Show error
        var err = "_________________________________________________\n\nThe form could not be submitted due to the following error(s)\n_________________________________________________\n\n" + errors.join ("\n\n");
        var ferror_handler = eval('this.onsubmit_error');
        if  (ferror_handler != null)
            ferror_handler(err);
        else
            alert (err);
        return false;
    }

    if  (this.onsubmit_next_js != null)
        return this.onsubmit_next_js(this);

    return true;
}

function getCurrentValue (p_form, p_field)
{
    var value = '';

    var field = eval ('p_form.' + p_field);
    if  (field == null)
    {
        if  (eval('window.' + p_field))
            return eval('window.' + p_field + '()');
        alert ('Internal error: field "' + p_field + '" is not defined in the form');
        return '';
    }

    var type = field.type;
    if  ((type == 'text')||(type == 'textarea')||(type == 'hidden'))
    {
        value = field.value;
    }
    else if (type == 'select-one')
    {
        value = (field.selectedIndex == -1)? '':
            field.options[field.selectedIndex].value;
    }
    else if (type == 'checkbox')
    {
        value = (field.checked)? field.value: '';
    }
    else if (type == 'radio')
    {
        value = (field.checked)? field.value: '';
    }
    else if ((type == null)&&(field.length > 0)&&
             (field[0].type == 'radio'))
    {
        var len = field.length;
        for (var i = 0; i < len; i++)
        {
            if  (field[i].checked)
                value = field[i].value;
        }
    }
    else
    {
        alert ('Internal error: don\'t know how to get value of field "' +
            p_field + '" of type "' + type + '"');
    }

    return value;
}

function validateCCNumber (p_number, p_type)
{

    var cc_type = p_type.toUpperCase();
    var cc_number = p_number.replace(/\s*/g,'');
    var len = cc_number.length;
    if  (len == 0)
        return 'Please enter credit card number';
    if  (cc_number.match('\D'))
        return 'Credit card number can contain only digits and spaces';
    if  (cc_type == 'VISA')
    {
        if  ((len != 13)&&(len != 16))
            return 'VISA credit card number can contain only 13 or 16 digits';
        if  (!cc_number.match('^4'))
            return "VISA credit card number should start with digit '4'";
    }

    if  (cc_type == 'MASTERCARD')
    {
        if  (len != 16)
            return 'MasterCard credit card number can contain only 16 digits';
        if  (!cc_number.match('^5'))
            return "MasterCard credit card number should start with digit '5'";
    }

    if  (cc_type == 'DISCOVER')
    {
        if  (len != 16)
            return 'Discover credit card number can contain only 16 digits';
        if  (!cc_number.match('^6011'))
            return "Discover credit card number should start with digits '6011'";
    }

    if  (cc_type == 'AMERICAN EXPRESS')
    {
        if  (len != 15)
            return 'America Express credit card number can contain only 15 digits';
        if  (!cc_number.match('^3[47]'))
            return "America Express credit card number should start with digits '34' or '37'";
    }

    return '';
}

function validationObject (p_form)
{
    //  Get current form if form object was not provided
    if  ((arguments.length == 0)||(p_form == ''))
    {
        //  Get the last form from the list
        if  (document.forms.length == 0)
        {
            alert ('Internal error: There are no forms in this document yet');
            // Let it fail now
        }
        else
        {
            p_form = document.forms[document.forms.length - 1];
        }
    }

    //  Save pointer to old onsubmit function
    if  (p_form.onsubmit_next_js == null)
    {
        if  (p_form.onsubmit != null)
            p_form.onsubmit_next_js = p_form.onsubmit;
    }
    //  Assign new onsubmit function
    p_form.onsubmit = validateForm;
    p_form.validation = this;

    this.form_object = p_form;
    this.data = new Array ();
    this.addValidation = addValidationFunction;
}

function addValidationFunction (p_field, p_label, p_type)
{
    var i;
    var param;
    var value;

    // Create validation object for one field
    var validation = new fieldValidation (p_field, p_label, p_type);
    // Copy validation parameters
    for (i = 3; i < arguments.length; i += 2)
    {
        param = arguments[i];
        value = (i < arguments.length + 1)?
            arguments[i + 1]: 0;
        eval ('validation.' + param + ' = value');
    }
    // Store the object
    i = this.data.length;
    this.data[i] = validation;
}

function fieldValidation (p_field, p_label, p_type)
{
    this.field = p_field;
    this.label = p_label;
    this.type  = p_type;
}

