//*************************************\\
//-------- FORM VALIDATOR -------------\\
//--------    Version 4   -------------\\
//*************************************\\
//-------- Simone Del Tozzotto --------\\
//-------- Date: 15/01/2009    --------\\
//-------- Updated: 19/03/2009 --------\\
//*************************************\\

val = {
    _form: null, _pnlError: null,
    _formElems: null, _button: null,

    _controls: null, _ctrlCounter: 0,
    _buttons: null, _btnCounter: 0,
    _fileInputs: null, _filesCounter: 0,
    _btnUploads: null, _uploadsCounter: 0,

    _phoneFields: 0, _emailFields: 0,

    //---- Public variables ----\\
    phoneRequired: true,
    emailRequired: true,

    hideShowInitText: true,
    capitaliseInput: true,
    validateInput: true,
    checkUploads: true,
    uppercaseErrors: true,
    
    scrollUpOnError: false,
    scrollUpTo: 150,

    preWord: 'your',
    //---- end ----\\

    init: function(formId, pnlErrorId) {
        if (!document.getElementsByTagName) return false;
        if (!document.getElementById) return false;

        val._form = document.getElementById(formId);
        val._pnlError = document.getElementById(pnlErrorId);

        if (!val._form || !val._form.hasChildNodes()) return false;

        val._controls = new Array();
        val._buttons = new Array();
        val._fileInputs = new Array();
        val._btnUploads = new Array();

        val._formElems = val._form.getElementsByTagName('*');

        for (var i = 0; i < val._formElems.length; i++) {

            if (val._formElems[i].nodeName == 'SELECT') {

                val._controls[val._ctrlCounter] = val._formElems[i];
                val._ctrlCounter++;
            }
            else if (val._formElems[i].nodeName == 'TEXTAREA') {

                val._controls[val._ctrlCounter] = val._formElems[i];

                var textarea = val._controls[val._ctrlCounter];

                val._ctrlCounter++;

                if (!textarea.title) continue;

                if (val.hideShowInitText) {
                    if (!textarea.defaultValue)
                        textarea.value = textarea.title;

                    textarea.onfocus = function() {
                        if (this.value == this.title) {
                            this.value = '';
                        }
                    }

                    textarea.onblur = function() {
                        if (this.value == '') {
                            this.value = this.title;
                        }

                        this.value = this.value.charAt(0).toUpperCase() + this.value.substring(1);
                    }
                }
                else {
                    textarea.value = '';
                }
            }
            else if (val._formElems[i].nodeName == 'INPUT') {

                if (val._formElems[i].getAttribute('type') == 'text') {

                    val._controls[val._ctrlCounter] = val._formElems[i];

                    var input = val._controls[val._ctrlCounter];

                    val._ctrlCounter++;

                    if (!input.title) continue;

                    if (val.hideShowInitText) {

                        if (!input.defaultValue)
                            input.value = input.title;

                        input.onfocus = function() {
                            if (this.value == this.title) {
                                this.value = '';
                            }
                        }

                        input.onblur = function() {
                            if (this.value == '') {
                                this.value = this.title;
                            } else {
                                if (val.capitaliseInput) {
                                    // Capitalise all words in all inputs boxes 
                                    // except the email input box
                                    if (this.className.indexOf('email') == -1) {
                                        this.value = val._capitalise(this.value);
                                    }

                                    if (this.className.indexOf('upper') != -1) {
                                        this.value = this.value.toUpperCase();
                                    }
                                }
                            }
                        }
                    }
                    else {
                        input.value = '';

                        if (val.capitaliseInput) {
                            input.onblur = function() {
                                if (this.className.indexOf('email') == -1) {
                                    this.value = val._capitalise(this.value);
                                }

                                if (this.className.indexOf('upper') != -1) {
                                    this.value = this.value.toUpperCase();
                                }
                            }
                        }
                    }

                    if (input.className.indexOf('email') != -1) {
                        val._emailFields++;
                    }

                    if (input.className.indexOf('phone') != -1) {
                        val._phoneFields++;
                    }
                }
                else if (val._formElems[i].getAttribute('type') == 'file') {
                    
                    val._fileInputs[val._filesCounter] = val._formElems[i];
                    val._filesCounter++;
                }
                else if ((val._formElems[i].getAttribute('type') == 'button'
		                || val._formElems[i].getAttribute('type') == 'submit'
		                || val._formElems[i].getAttribute('type') == 'image')
		                && val._formElems[i].className.indexOf('submit') != -1) {

                    val._buttons[val._btnCounter] = val._formElems[i];
                    val._btnCounter++;
                }
                else if ((val._formElems[i].getAttribute('type') == 'button'
		                || val._formElems[i].getAttribute('type') == 'submit'
		                || val._formElems[i].getAttribute('type') == 'image')
		                && val._formElems[i].className.indexOf('upload') != -1) {
                    
                    val._btnUploads[val._uploadsCounter] = val._formElems[i];
                    val._uploadsCounter++;
                }
            }
        }
        
        if (val._buttons.length < 1) return false;

        //*************************
        // Validate on button click
        //*************************
        if (val.validateInput) {
            for (var b = 0; b < val._buttons.length; b++) {
                var button = val._buttons[b];

                button.onclick = function() {
                    return val._validate();
                }
            }
            
            for (var u = 0; u < val._btnUploads.length; u++) {
                var upload = val._btnUploads[u];

                upload.onclick = function() {
                    return val._validateUpload();
                }
            }
        }
    },

    _validate: function() {
        var errors = new Array();
        var errCounter = 0;

        var phonesChecked = 0, phonesFilled = 0;

        var emailInputs = new Array();
        var emailsChecked = 0, emailValid = false;

        for (var i = 0; i < val._controls.length; i++) {
            var control = val._controls[i];

            var ctrlTitle = '';

            if (control.title) {
                if (val.uppercaseErrors)
                    ctrlTitle = val._capitalise(control.title);
                else
                    ctrlTitle = control.title.toLowerCase();
            }

            if (control != null) {
                if (control.nodeName == 'SELECT') {
                    if (control.className.indexOf('required') != -1 && control.style.display != 'none') {
                        if (!val.isSelected(control)) {
                            errors[errCounter] = control.value;
                            errCounter++;
                        }
                    }
                }
                else if (control.nodeName == 'TEXTAREA') {
                    if (control.className.indexOf('required') != -1 && control.style.display != 'none') {
                        if (!val.isFilled(control)) {
                            errors[errCounter] = 'Please enter ' + val.preWord + ' ' + ctrlTitle;
                            errCounter++;
                        }
                    }
                }
                else if (control.nodeName == 'INPUT') {
                    if (control.getAttribute('type') == 'text') {

                        if (control.className.indexOf('required') != -1 && control.style.display != 'none') {
                            if (!val.isFilled(control)) {
                                errors[errCounter] = 'Please enter ' + val.preWord + ' ' + ctrlTitle;
                                errCounter++;
                            }
                        }
                        //*****
                        if (control.className.indexOf('numeric') != -1 && control.style.display != 'none') {
                            if (val.isFilled(control)) {
                                if (!val.isNumeric(control)) {
                                    errors[errCounter] = 'Please enter a number in the field "' + ctrlTitle + '"';
                                    errCounter++;
                                }
                            }
                        }
                        //*****
                        if (control.className.indexOf('price') != -1 && control.style.display != 'none') {
                            if (val.isFilled(control)) {
                                if (!val.isPrice(control)) {
                                    errors[errCounter] = 'Please enter the price in a valid format';
                                    errCounter++;
                                }
                            }
                        }
                        //*****
                        if (control.className.indexOf('email') != -1 && control.style.display != 'none') {

                            emailInputs[emailsChecked] = control;

                            if (val.isFilled(control)) {
                                if (!val.isValidEmail(control)) {
                                    errors[errCounter] = 'Please enter a valid email address (eg. name.surname@domain.com)';
                                    errCounter++;
                                }
                            }

                            emailsChecked++;

                            if (emailsChecked == val._emailFields) {

                                if (val.emailRequired) {

                                    var emailTitle = '';

                                    if (emailInputs[0].title) {
                                        if (val.uppercaseErrors)
                                            emailTitle = val._capitalise(emailInputs[0].title);
                                        else
                                            emailTitle = emailInputs[0].title.toLowerCase();
                                    }

                                    if (!val.isFilled(emailInputs[0])) {
                                        errors[errCounter] = 'Please enter ' + val.preWord + ' ' + emailTitle + ' address';
                                        errCounter++;
                                    }
                                    else if (val._emailFields == 2) {
                                        // If there are two email fields, suppose the
                                        // second is used to confirm the email address

                                        if (val.isFilled(emailInputs[0]) && val.isValidEmail(emailInputs[0]) && !val.isFilled(emailInputs[1])) {
                                            errors[errCounter] = 'Please confirm ' + val.preWord + ' email address';
                                            errCounter++;
                                        }
                                        else if ((val.isFilled(emailInputs[0]) && val.isValidEmail(emailInputs[0]))
                                        && (val.isFilled(emailInputs[1]) && val.isValidEmail(emailInputs[1]))
                                        && (emailInputs[0].value != emailInputs[1].value)) {
                                            errors[errCounter] = 'The email addresses entered do not match';
                                            errCounter++;
                                        }
                                    }
                                }
                            }
                        }
                        //*****
                        if (control.className.indexOf('phone') != -1 && control.style.display != 'none') {

                            if (val.isFilled(control)) {
                                if (!val.isValidPhoneNum(control)) {
                                    errors[errCounter] = 'Please enter a valid ' + ctrlTitle + ' number';
                                    errCounter++;
                                }
                                phonesFilled++;
                            }

                            phonesChecked++;

                            if (phonesChecked == val._phoneFields) {

                                if (val.phoneRequired) {

                                    if (val._phoneFields > 1) {
                                        if (phonesFilled < 1) {
                                            errors[errCounter] = 'Please enter at least one telephone number';
                                            errCounter++;
                                        }
                                    }
                                    else if (val._phoneFields == 1) {
                                        if (!val.isFilled(control)) {
                                            errors[errCounter] = 'Please enter ' + val.preWord + ' ' + ctrlTitle + ' number';
                                            errCounter++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        if (errors.length < 1) {
            if (val._pnlError) val._pnlError.innerHTML = ''; //can be removed
            return true;
        } else {
            if (val._pnlError) {
                val._displayErrors(errors, val._pnlError, true);
            } else {
                val._displayErrors(errors, val._pnlError, false);
            }
            
            if (val.scrollUpOnError)
                window.scroll(0, val.scrollUpTo);
                
            return false;
        }
    },

    _validateUpload: function() {
        for (var i = 0; i < val._fileInputs.length; i++) {
            var file = val._fileInputs[i];

            if (val.checkUploads) {
                if (val.isFilled(file)) {
                    var filename = file.value.toLowerCase();
                    //alert(filename);

                    if (filename.indexOf('.gif', 0) == -1
                        && filename.indexOf('.jpg', 0) == -1
                        && filename.indexOf('.jpeg', 0) == -1) {
                        alert('Please make sure you are uploading only gif/jpg images');
                        return false;
                    }
                    else {
                        return true;
                    }
                }
                else {
                    alert('Please select an image file from your computer');
                    return false;
                }
            }
        }
    },

    _displayErrors: function(errors, pnlError, panelExist) {
        var errMsg = "";

        if (panelExist) {
            errMsg += '<ul>';
            for (var i = 0; i < errors.length; i++) {
                errMsg += '<li>';
                errMsg += errors[i];
                errMsg += '</li>';
            }
            errMsg += '</ul>';

            pnlError.innerHTML = errMsg;

            if (pnlError.style.display == 'none')
                pnlError.style.display = 'block';
        }
        else {
            for (var i = 0; i < errors.length; i++) {
                errMsg += '- ' + errors[i] + '\n';
            }
            alert(errMsg);
        }
    },

    isFilled: function(field) {
        if (field.value.length < 1 || field.value == field.title) {
            return false;
        } else {
            return true;
        }
    },

    isSelected: function(field) {
        if (field.options[0].selected == true) {
            return false;
        } else {
            return true;
        }
    },

    isValidEmail: function(field) {
        var emailFilter = /^\w+[\+\.\w-]*@([\w-]+\.)*\w+[\w-]*\.([a-z]{2,4}|\d+)$/i
        return emailFilter.test(field.value);
    },

    isValidPhoneNum: function(field) {
        field.value = field.value.replace(/ /g, '');
        if (field.value.substring(0, 1) != '0' || field.value.length < 10 || isNaN(field.value)) {
            return false;
        } else {
            return true;
        }
    },

    isNumeric: function(field) {
        if (isNaN(field.value)) {
            return false;
        } else {
            return true;
        }
    },

    isPrice: function(field) {
        var price = field.value;
        var valid = false;

        if (price.indexOf(',', 0) > -1) {
            price = price.replace(/,/g, '');
        }

        price = parseFloat(price).toFixed(2);

        if (!isNaN(price)) {
            return true;
        } else {
            return false;
        }
    },

    _capitalise: function(text) {
        var words = text.split(' ');
        var noWords = words.length;
        var strOutput = '';

        for (var i = 0; i < words.length; i++) {
            var firstChar = words[i].substring(0, 1);
            if (noWords > 1) {
                strOutput += words[i].replace(firstChar, firstChar.toUpperCase()) + ' ';
            }
            else {
                strOutput += words[i].replace(firstChar, firstChar.toUpperCase());
            }
        }

        return strOutput;
    }
}