﻿/**
* Form Validation
*
*
* @version		1.0
* @author		Paul Navasard
* @copyright	KLAS Enterprises
*/


var CustomValidation = new Class({
    Implements: [Options, Events],
    options: {
        errorMessage: 'Error',
        test: function() { return true; }
    },
    initialize: function(options) {
        this.setOptions(options);
    },
    getError: function() {
        return this.options.errorMessage;
    },
    test: function() {
        return this.options.test();
    }
});

var FormValidation = new Class({
    Implements: [Options, Events],
    options: {
        regEX: null,
        errorMessages: null,
        submitButton: null,
        errorMessage: "Please fix your errors and try submitting the form again.",
        ajaxSubmit: false
    },
    initialize: function(elements, options) {
        this.elements = elements;
        this.setOptions(options);
        this.options.regEX = new Hash({
            required: /\w/,
            onlyNumbers: /^(\d|-)?(\d|,)*\.?\d*$/,
            zipCode: /(^\d{5}$)|(^\d{5}-\d{4}$)/,
            password: /^.{8,}$/,
            email: /^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/,
            year: /(^19\d{2}$)|(^20\d{2}$)/,
            phone: /^(1\s*[-\/\.]?)?(\((\d{3})\)|(\d{3}))\s*[-\/\.]?\s*(\d{3})\s*[-\/\.]?\s*(\d{4})\s*(([xX]|[eE][xX][tT])\.?\s*(\d+))*$/
        });
        this.options.errorMessages = new Hash({
            required: "Required Field",
            onlyNumbers: "Only Numbers",
            zipCode: "Not a Valid Zip Code",
            password: "Password must be at least 8 characters",
            email: "Invalid Email Address",
            year: "Invalid Year",
            phone: "Invalid Phone Number"
        });
        this.build(elements);

        if (this.options.submitButton) {
            this.options.submitButton.addEvent('click', function(evt) {

                if (this.formCheck()) {
                    if (!this.options.ajaxSubmit)
                        $('aspnetForm').submit();
                } else {
                    new Event(evt).stop();
                    if(this.options.errorMessage)
                        alert(this.options.errorMessage);
                }
            } .bind(this));
        }
    },
    build: function(elements) {
        elements.each(function(item) {
            if (item.get('title')) {
                item.store('emptyText', item.get('title'));
                item.removeProperty('title');
                if (item.get('value').clean() == "") {
                    item.set('value', item.retrieve('emptyText'));
                    item.addClass('formOverEmpty');
                }
            }
            item.setStyle('float', 'left');
            item.setStyle('margin-left', '5px');
            this.setEvents(item);
            this.createErrorElement(item);
        } .bind(this));
    },
    elementFocus: function(element) {
        if (element.retrieve('emptyText') != null) {
            if (element.get('value') == element.retrieve('emptyText')) {
                element.set('value', '');
                element.removeClass('formOverEmpty');
            }
        }
    },
    elementBlur: function(element) {
        var passed = true;
        var errorElement = element.retrieve('errorElement');
        errorElement.set('text', '');
        element.get('class').split(' ').each(function(item) {
            if (this.options.regEX.has(item)) {
                if (item != 'required') {
                    if (element.get('value').length > 0) {
                        var temp = this.testValue(element, item, errorElement);
                        if (passed)
                            passed = temp;
                    }
                } else {
                    var temp = this.testValue(element, item, errorElement);
                    if (passed)
                        passed = temp;
                }
            }
        } .bind(this));

        if (!this.testCustom(element, errorElement))
            passed = false;

        if (errorElement.get('text').length == 0)
            errorElement.hide();

        if (element.retrieve('emptyText') != null && element.get('value').length == 0) {
            element.set('value', element.retrieve('emptyText'));
            element.addClass('formOverEmpty');
        }

        return passed;
    },
    testValue: function(element, name, errorElement) {
        var val = element.get('value');

        if (element.retrieve('emptyText') == val)
            val = '';

        if (!val.test(this.options.regEX.get(name))) {
            errorElement.set('text', (this.options.errorMessages.get(name)));
            errorElement.show();
            return false;
        }
        return true;
    },
    testCustom: function(element, errorElement) {
        if (element.retrieve('customValidator')) {
            if (!element.retrieve('customValidator').test()) {
                errorElement.set('text', (element.retrieve('customValidator').getError()));
                errorElement.show();
                return false;
            }
        }
        return true;
    },
    createErrorElement: function(element) {
        var errorElement = new Element('div', {
            'class': 'formError Hide'
        });
        element.store('errorElement', errorElement);
        errorElement.inject(element, 'after');
    },
    setEvents: function(element) {
        element.addEvents({
            'focus': this.elementFocus.bind(this, [element]),
            'blur': this.elementBlur.bind(this, [element])
        });
    },
    formCheck: function() {
        var passed = true;
        this.elements.each(function(item) {
            var temp = this.elementBlur(item);
            if (passed)
                passed = temp;
        } .bind(this));
        return passed;
    }
});