/* ******************************************
 * Author: Craig MacKenzie    				*
 * Date: Nov 23 2009						*
 * Webforms 2.0 styled form validation		*
 * 							 				*
 *******************************************/
function initFormValidator(){
    // Find language setting
    var langType = document.getElementsByTagName('html')[0].getAttribute('lang').toUpperCase();
    
    
    /*// Skeleton object for form settings/configuration. //*/
    var form = {
        element: {
            current: '',
            id: '',
            pattern: false,
            modifier: false,
            length: false,
            isdisabled: false,
            relevance: false,
            hasErrors: false,
            wrapper: 'li' // cotaining element.
        },
        error: {
            wrapperClass: 'errormsg_field',
            e_class: 'error',
            text: 'em',
            result: {
                EN: {
                    'numErrorText': 'The following #Errors#  fields need to be completed or corrected:',
                    'requiredError': 'This information is required'
                },
                FR: {
                    'numErrorText': 'Vous devez remplir ou corriger les #Errors# champs suivants :',
                    'requiredError': 'Ce renseignement est obligatoire'
                }
            }
        }
    }
    
    
    
    
    /*// form error control. This is where the error classes and text are handled //*/
    // add error classes to input and it's container
    form.addErrorClass = function(input, container){
        input.addClass(form.error.e_class).closest(container).addClass(form.error.wrapperClass);
        $('label[for="' + input.attr('id') + '"]').addClass(form.error.e_class);
    }
    // remove error class from input. 
    // remove error class from container if a target is set
    // Default is form.element.wrapper --> (<li>)
    form.removeErrorClass = function(input, container){
        if (container) {
            input.closest(container).removeClass(form.error.wrapperClass);
            input.siblings(form.error.text + '.' + form.error.e_class).remove();
        }
        input.removeClass(form.error.e_class);
        $('label[for="' + input.attr('id') + '"]').removeClass(form.error.e_class);
    };
    // show relevant error text
    form.showErrorText = function(input, container, pattern){
        // check whether to use specific or generic error messaging
        if (pattern == 'specifc') {
            form.error.alert = input.attr('title');
        }
        else {
            form.error.alert = form.error.result[langType].requiredError;
        }
        // add error messaging
        if (input.siblings(form.error.text + '.' + form.error.e_class).length < 1) {
            input.closest(container).append('<' + form.error.text + ' class="' + form.error.e_class + '" for="' + input.attr('id') + '">' + form.error.alert + '</' + form.error.text + '>');
        }
        else {
            input.siblings(form.error.text + '.' + form.error.e_class).text(form.error.alert)
        }
    };
    
    
    
    
    
    /*// get input's attributes/properties and return them to the form object //*/
    form.grabElementData = function(input){
        form.element.current = $(input);
        form.element.id = form.element.current.attr("id");
        form.element.required = form.element.current.attr('required') || false;
        form.element.maxlength = form.element.current.attr('maxlength') || false;
        form.element.pattern = form.element.current.attr('pattern') || false;
        form.element.modifier = form.element.current.attr('modifier') || false;
        form.element.length = form.element.current.val().length || 0;
        form.element.isdisabled = form.element.current.attr('disabled') || false;
        form.element.relevance = form.element.current.attr('relevant') || false;
        return form;
    }
    
    
    
    
    
    /*// Validate ALL form fields //*/
    form.validate = function(formId){
        $(formId).find('input[type="text"], select, textarea').each(function(){
            // Check fields
            form.validateFields(this);
        });
        // Check for errors
        var numErrors = $(form.element.wrapper + '.' + form.error.wrapperClass, formId).length;
        if (numErrors) {
            // Build an error list and append it to the form
            $('#submit-message', formId).remove();
            var errorList = '<ul>';
            $(form.element.wrapper + '.' + form.error.wrapperClass + ' label.' + form.error.e_class + '', formId).each(function(){
                errorList += '<li><label for="' + $(this).attr('for') + '">' + $(this).text() + '</label></li>';
            });
            $(formId).prepend($('<div id="submit-message"><h2>' + form.error.result[langType].numErrorText.replace('#Errors#', numErrors) + '</h2>' + errorList + '</div>'));
            var errorOffset = $('#submit-message').offset();
			$('html, body').animate({
                scrollTop: errorOffset.top
            }, 700);
        }
        
        // return the number of errors
        return numErrors;
    }
    
    
    
    
    
    /*// Validate form fields //*/
    form.validateFields = function(input){
        form = form.grabElementData(input)
        
        
        // grab input validation rule if available
        // add modifier if the input requires it
        if (form.element.pattern && form.element.modifier) {
            form.element.pattern = new RegExp(form.element.pattern, form.element.modifier)
        }// if the modifier is not present grab the validation rule
        else 
            if (form.element.pattern) {
                form.element.pattern = new RegExp(form.element.pattern)
            }
        
		
		
        // Check required fields
        if ((form.element.required == 'required' || form.element.required == true) && form.element.length < 1) {
            form.addErrorClass(form.element.current, form.element.wrapper)
            form.showErrorText(form.element.current, form.element.wrapper, 'generic')
            return form.element.hasErrors = true;
        }
        else 
            if (form.element.maxlength > 0 && form.element.length >= form.element.maxlength) {
                form.addErrorClass(form.element.current, form.element.wrapper)
                form.showErrorText(form.element.current, form.element.wrapper, 'specifc')
                return form.element.hasErrors = true;
            }
            
            // check input val against it's pattern if pattern exists
            else 
                if (form.element.isdisabled == false && form.element.length > 0 && form.element.pattern != false && form.element.pattern.test(form.element.current.val()) != true) {
                    form.addErrorClass(form.element.current, form.element.wrapper)
                    form.showErrorText(form.element.current, form.element.wrapper, 'specifc')
                    return form.element.hasErrors = true;
                } // check relevant fields (fields that depend on a certain condition being met)
                else 
                    if (form.element.isdisabled == false && form.element.relevance) {
                        form.removeErrorClass(form.element.current);
                        form.element.hasErrors = false;
                        $(':input[relevant=' + form.element.relevance + ']').each(function(){
                            form.element.current = $(this);
                            if (form.element.length < 1 && form.element.required == 'required') {
                                form.addErrorClass(form.element.current, element.wrapper)
                                return form.element.hasErrors = true;
                            }
                            else 
                                if (form.element.current.siblings(':input').hasClass(form.error.e_class)) {
                                    return form.element.hasErrors = true;
                                }
                        });
                    }
                    else {
                        form.element.hasErrors = false;
                    }
        
        // remove error class from validated elements 
        if (!form.element.hasErrors) {
            form.removeErrorClass(form.element.current, form.element.wrapper)
        }
        
        // return the error state of the form
        return form.element.hasErrors;
    }
    
    
    
    
    
    /*// Event Bindings //*/
    
    // blur event on for elements for validation
    $('input:text, input:password, select, textarea').blur(function(){
        form.validateFields(this);
    });
    
    // blur event on form elements for presentation
    $(':input').blur(function(){
        $(this).closest('li').removeClass('focus');
        $(this).removeClass('focus');
    });
    
    // focus event on forms elements for presentation
    $('input[type!=button], select, textarea').focus(function(){
        $(this).closest('li').addClass('focus');
        $(this).addClass('focus');
    })
    
    // check radio button state, reset default HTML state if need be
    $(':input[checked]').each(function(){
        var checkedRB = $(this);
        // reset required attribute on grouped inputs
        $(':input[name="' + checkedRB.attr('name') + '"]').each(function(){
            $(this).siblings().removeAttr('required');;
        });
        // set checked radio buttons siblings to required
        checkedRB.siblings().attr('required', 'required');
    });
    
    // radio button events (mostly resetting the required attribute)
    $(':input[type="radio"]').click(function(){
        var relGroup = $(this).attr('name');
        $(':input[name="' + relGroup + '"]').siblings().removeAttr('required');
        form.validateFields($(':input[name="' + relGroup + '"]').siblings());
        $(this).siblings().attr('required', 'required');
        // remove error class from other radio siblings/container
        form.removeErrorClass($(':input[name="' + relGroup + '"]').siblings(), $(':input[name="' + relGroup + '"]').closest('.' + form.error.wrapperClass));
    })
    
    return form;
}



