/*
Validation Singleton
*/
var Validation = function () {
    var rules = {
        email: {
            check: function (value) {
                if (value) {
                    return testPattern(value, "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])");
                }

                return true;
            },
            msg: "E-mail is not valid."
        },
        password: {
            check: function (value) {
                value = $.trim(value);
                if (value.length > 5)
                    return true;
                else
                    return false;
            },
            msg: "Password length is not valid."
        },
        required: {
            check: function (value) {
                value = $.trim(value);
                if (value)
                    return true;
                else
                    return false;
            },
            msg: "The highlighted fields are incorrect/missing. Please try again."
        },
        code: {
            check: function (value) {
                return true;
            },
            msg: ""
        },
        date: {
            check: function (value) {
                var retVal = true;

                var minYear = 1902;
                var maxYear = (new Date()).getFullYear();

                var re = /^(\d{1,2})-(\d{1,2})-(\d{4})$/;
                if (regs = value.match(re)) {
                    if (regs[1] < 1 || regs[1] > 31) {
                        retVal = false;
                    } else if (regs[2] < 1 || regs[2] > 12) {
                        retVal = false;
                    } else if (regs[3] < minYear || regs[3] > maxYear) {
                        retVal = false;
                    }
                } else {
                    retVal = false;
                }

                return retVal;
            },
            msg: ""
        },
        phone: {
            check: function (value) {
                retVal = false;

                if (value) {
                    var re = /^\s*\d+\s*$/;
                    if (value.match(re)) {
                        retVal = true;
                    }
                }

                return retVal;
            },
            msg: "Phone number is not in valid format, only numbers are permitted."
        }
    }
    var testPattern = function (value, pattern) {
        var regExp = new RegExp(pattern, "i");
        return regExp.test(value);
    }
    return {
        addRule: function (name, rule) {
            rules[name] = rule;
        },
        getRule: function (name) {
            return rules[name];
        }
    }
}

/* 
Form factory 
*/
var Form = function(form) {
    var fields = [];

    form.find("[validation]").each(function() {
        var field = jQuery(this);
        if (field.attr('validation') !== undefined) {
            fields.push(new Field(field));
        }
    });

    this.fields = fields;
}

Form.prototype = {
    validate: function() {
        for (field in this.fields) {
            if (field < this.fields.length) {
                this.fields[field].validate();
            }
        }
    },
    isValid: function() {
        for (field in this.fields) {
            if (field < this.fields.length && !this.fields[field].valid) {
                this.fields[field].field.focus();

                return false;
            }
        }

        return true;
    }
}

/* 
Field factory 
*/
var Field = function(field) {
    this.field = field;
    this.valid = false;
    this.attach("change");
}

Field.prototype = {
    attach: function (event) {
        var obj = this;
        if (event == "change") {
            obj.field.bind("change", function () {
                return obj.validate();
            });
        }

        if (event == "keyup") {
            obj.field.bind("keyup", function (e) {
                return obj.validate();
            });
        }
    },
    validate: function () {
        var obj = this,
            field = obj.field,
            types = field.attr("validation").split(" "),
            container = field.parent().parent(),
            message = field.parent().parent().find('li.info div.error-msg p'),
            errors = [],
            isCode = false;

        for (var type in types) {
            if (types[type] && types[type] == "code") {
                //message = message.parent().find('li.info error-msg');
            }

            var rule = jQuery.Validation.getRule(types[type]);
            if ((typeof rule != "undefined") && !rule.check(field.val())) {
                errors.push(rule.msg);
            }
        }

        if (errors.length) {
            obj.field.unbind("keyup")
            obj.attach("keyup");
            obj.valid = false;
            obj.field.parent().addClass("error");
           // message.parent().show();
           // message.text(errors[0]);
        }
        else {
          //  message.parent().hide();
            obj.field.parent().removeClass("error");
            obj.valid = true;
        }
    }
}

/*
Validation extends jQuery prototype
*/
jQuery.extend(jQuery.fn, {
    validation: function() {
        var validator = new Form(jQuery(this));
        jQuery.data(jQuery(this)[0], 'validator', validator);

        jQuery(this).bind("submit", function(e) {
            validator.validate();
            if (!validator.isValid()) {
                e.preventDefault();
            }
        });
    },
    removeValidation: function() {
        jQuery.removeData(jQuery(this)[0], 'validator');
    },
    validate: function() {
        var validator = jQuery.data(jQuery(this)[0], 'validator');
        validator.validate();
        return validator.isValid();
    }
});

jQuery.Validation = new Validation();

