/*
* General functions
*/

// Create a hidden field of the specified name and value in the specified form
function createHiddenField(varName,varVal,varForm) {
    var varObject;
    
    if(document.getElementById(varName)) {
        varObject = varForm.elements[varName];
        varObject.setAttribute('value',varVal);
        
        return false;
    } else {
        varObject = document.createElement('input');
        varObject.setAttribute('name',varName);
        varObject.setAttribute('id',varName);
        varObject.setAttribute('type','hidden');
        varObject.setAttribute('value',varVal);
        varForm.appendChild(varObject);
        
        return true;
    }
}

/*
* AJAX form process scripts
*/

var ajaxForm; // Ajax form
var doTimeout = 1;
var ajaxTimeout; // To check if AJAX has responded
var timeout = 10000; // Time in milliseconds until timeout

// Pass form data to AJAX routine "check_mortgage_form" - results get process by "processErrors"
function checkFormAjax(formOrId) {
    // find the form
    var form;
    if(formOrId.nodeType && formOrId.nodeType == 1) form = formOrId; // If it is an element, use it as such
    else if(document.getElementById(formOrId)) form = document.getElementById(formOrId); // Otherwise try to use it as an element id
    else return false; // or return false
    
    // Set up global ajax variables
    ajaxForm = form;
    
    // Set submit button to saying "wait..." and disable it
    var submitButton    = ajaxForm.elements.checkSubmit;
    submitButton.value = 'wait...';
    submitButton.setAttribute('disabled','disabled');
    addClass(submitButton,'disabledButton');
    
    // Hide all incorrect error images
    var images = document.getElementsByTagName('img');
    for(var i=0; i<images.length; i++) {
        var image = images[i];
        var imageClass = image.className;
        if(imageClass.match('(^| )(incorrectImg|missingImg)($| )')) addClass(image,'hidden'); // Add hidden class, if it doesn't have it
    }
    
    // Get all form data into two strings
    var formData = formDataToStrings(ajaxForm);
    
    // Create AJAX variables - (the AJAX routine can only read data from an "input" field)
    createHiddenField('ajax_fieldNames',formData[0],ajaxForm);
    createHiddenField('ajax_fieldValues',formData[1],ajaxForm);
    
    // run AJAX routine
    if(doTimeout) ajaxTimeout = setTimeout("ajaxForm.submit();",timeout); // Set timeout to submit form anyway if it takes longer than "timeout"
    checkForm(['ajax_fieldNames','ajax_fieldValues'],[processErrors]); // Submit to ajax routine
    
    return false;
}

// Get data from form and return it in two semi-colon seperated strings
function formDataToStrings(form) {
    var formElems = form.elements;
    
    // Start retrieving form data
    var fieldNames = new Array(); // Array to contain names of elements
    var fieldValues = new Array(); // Array to contain value of elements
    
    // Add all fields to arrays
    for(var i=0; i<formElems.length; i++) {
        var elem = formElems[i]; // element object
        var nameValue = getFieldNameValue(elem);
        if(nameValue) { // If value name/value returned
            fieldNames.push(nameValue[0]); // Store name
            fieldValues.push(nameValue[1]); // Store value
        }
    }
    
    // Debugging - shows all name - value pairs in alert box
    var printString = "";
    for(var i=0; i< fieldNames.length; i++) {
        printString += fieldNames[i] + " - " + fieldValues[i] + "\n";
    }
    
    if(fieldNames.length != fieldValues.length) alert("script error - field names don't match values");
    
    return new Array(fieldNames.join(';'),fieldValues.join(';'));
}

// Returns the name/value pair of a field
function getFieldNameValue(field) {
    var name = field.name; // to contain the name
    var type = field.type; // to contain the type
    // Get value
    var value = ""; // to contain the value
    if(field.tagName.match('select','i')) {value = field.options[field.selectedIndex].value;} // If select box, store selected index's value
    else if(field.value) {value = field.value;} // Otherwise store regular value
    
    // Store values
    if(name && value != null) {
        if(type && type == 'radio') { // If radio button, find checked one to return
            var form = getAncestor(field,'form');
            var elements = form.elements;
            for(var i = 0; i<elements.length; i++) {
                if(elements[i].name && elements[i].name == name && elements[i].checked) return new Array(name,elements[i].value);
            }
            return new Array(name, ''); // If we've for this far then none of them were checked, so return false
        } else if(type && type == 'checkbox') { // If check box, return value or blank
            if(field.checked) return new Array(name, value);
            else return new Array(name, '');
        } else {
            return new Array(name, value); // Otherwise retrun value
        }
    }
    
    return false;
}

// Handles output of ajax routine "check_mortgage_form" - if there are errors, shows relevent error message/images and re-enables submit, otherwise submits the form
function processErrors(missingNames,incorrectNames) {
    // Ajax has responded - clear timeout
    if(doTimeout && ajaxTimeout) clearTimeout(ajaxTimeout);
    
    // Remove AJAX variables we set up
    removeElem('ajax_fieldNames');
    removeElem('ajax_fieldValues');
    
    // Check if some are missing or incorrect
    var someMissing = 0;
    var someIncorrect = 0;
    if(missingNames && missingNames != '') someMissing = 1;
    if(incorrectNames && incorrectNames != '') someIncorrect = 1;
    
    if(someMissing || someIncorrect) { // Missing or incorrect data, perform relevent operations
        // If some fields are missing
        if(someMissing) {
            // Store names in array
            var missingArr = missingNames.split(';');
            
            // Show images for missing data
            for(var i=0; i<missingArr.length; i++) {
                var missingImg = document.getElementById(missingArr[i]+'_missing');
                removeClass(missingImg,'hidden');
            }
        }
        
        // If some fields are incorrect
        if(someIncorrect) {
            // Store names in array
            var incorrectArr = incorrectNames.split(';');
            
            // Show images for incorrect data
            for(var i=0; i<incorrectArr.length; i++) {
                var incorrectImg = document.getElementById(incorrectArr[i]+'_incorrect');
                removeClass(incorrectImg,'hidden');
            }
        }
        
        // Update error messages
        updateErrorMessages();
        
        // Re-enable submit button
        var submitButton = ajaxForm.elements.checkSubmit;
        submitButton.value = 'submit';
        removeClass(submitButton,'disabledButton');
        submitButton.removeAttribute('disabled');
        
        // Jump to error messages
        window.location.hash = '#errors';
        
        return false; // Don't submit the form
    } else { // No missing or incorrect data, submit the form
        ajaxForm.submit();
        
        return true;
    }
}

// Update showing of error messages according to whether images are showing
function updateErrorMessages() {
    var missingMessage      = document.getElementById('missingMessage');
    var incorrectMessage    = document.getElementById('incorrectMessage');
    var messageBox          = document.getElementById('messageBox');
    var missingImagesShowing    = 0;
    var incorrectImagesShowing  = 0;

    // Check if any missing images are showing
    var missingImages = getElementsByClassName('img','missingImg');
    for(var i=0; i<missingImages.length; i++) {
        if(!hasClass(missingImages[i],'hidden')) missingImagesShowing = 1;
    }

    // Check if any incorrect images are showing
    var incorrectImages = getElementsByClassName('img','incorrectImg');
    for(var i=0; i<incorrectImages.length; i++) {
        if(!hasClass(incorrectImages[i],'hidden')) incorrectImagesShowing = 1;
    }
    
    // If missing images showing
    if(missingImagesShowing) {
        removeClass(messageBox,'hidden'); // Make sure message box is showing
        removeClass(missingMessage,'hidden'); // Make sure missing message is showing
    } else {
        addClass(missingMessage,'hidden'); // Make sure missing message is hidden
    }
    
    // If incorrect images showing
    if(incorrectImagesShowing) {
        removeClass(messageBox,'hidden'); // Make sure message box is showing
        removeClass(incorrectMessage,'hidden'); // Make sure incorrect message is showing
    } else {
        addClass(incorrectMessage,'hidden'); // Make sure missing message is hidden
    }
    
    // If neither are showing then hide the messages
    if(!missingImagesShowing && !incorrectImagesShowing) {
        addClass(messageBox,'hidden');
        return false;
    }
    
    return true;
}
