//http://webcloud.se/article/Form_validation_with_jQuery_from_scratch/?demo-field-1=s&demo-field-1=&demo-field-3=
(function($) {

    /*
    Validation Singleton
    */
    var Validation = function() {
        //debugger;
        var rules = {

            email: {
                check: function(value) {

                    if (value)
                        return testPattern(value);
                    return true;
                },
                msg: "enter a valid e-mail address."
            },
            email2: {
                check: function(value) {

                    if (value)
                        return testPattern(value);
                    return true;
                },
                msg: "invalid email."
            },
            url: {

                check: function(value) {

                    if (value)
                        return testPattern(value, "https?://(.+\.)+.{2,4}(/.*)?");
                    return true;
                },
                msg: "enter a valid URL."
            },
            required: {

                check: function(value) {

                    if (value)
                        return true;
                    else
                        return false;
                },
                msg: "this field is required."
            },
            epos: {
                check: function(value) {

                    if (value)
                        return testPattern(value);
                    return true;
                },
                msg: "voer 'n geldige e-pos adres."
            },
            vereis: {

                check: function(value) {

                    if (value)
                        return true;
                    else
                        return false;
                },
                msg: "hierdie veld is verpligtend."

            }
    }
    var testPattern = function(value) {
        var emailRegEx = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        if (value.match(emailRegEx)) { return true; } else { return false; }
    }
    return {

        addRule: function(name, rule) {

            rules[name] = rule;
        },
        getRule: function(name) {

            return rules[name];
        }
    }
}

/* 
Form factory 
*/
var Form = function(form) {

    var fields = [];
    form.find("input[validation], textarea[validation], select[validation]").each(function() {

        fields.push(new Field(this));
    });
    this.fields = fields;
}
Form.prototype = {
    validate: function() {

        for (field in this.fields) {

            this.fields[field].validate();
        }
    },
    isValid: function() {

        for (field in this.fields) {

            if (!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,
                errorClass = "errorlist",
                errorlist = $(document.createElement("span")).addClass(errorClass),
                types = field.attr("validation").split(" "),
                container = field.parent(),
                errors = [];

        field.next(".errorlist").remove();
        for (var type in types) {

            var rule = $.Validation.getRule(types[type]);
            if (!rule.check(field.val())) {

                container.addClass("error");
                errors.push(rule.msg);
            }
        }
        if (errors.length) {

            obj.field.unbind("keyup")
            obj.attach("keyup");
            field.after(errorlist.empty());
            for (error in errors) {

                errorlist.append("<span>" + errors[error] + "</span>");
            }
            obj.valid = false;
        }
        else {
            errorlist.remove();
            container.removeClass("error");
            obj.valid = true;
        }
    }
}

/* 
Validation extends jQuery prototype
*/
$.extend($.fn, {

    validation: function() {

        var validator = new Form($(this));
        $.data($(this)[0], 'validator', validator);

        //$(this).bind("click", function(e) {
        validator.validate();
        if (!validator.isValid()) { return false; } else { return true; }
        //});
    },
    validate: function() {

        var validator = $.data($(this)[0], 'validator');
        validator.validate();
        return validator.isValid();

    }
});
$.Validation = new Validation();
})(jQuery);

$.Validation.addRule("phonenumber", { check: function(value) { if (value.length != 10) { return false; } return true; }, msg: "please enter a 10 digit number" });
$.Validation.addRule("number", { check: function(value) { if (isNaN(value)) { return false; } else { return true; } }, msg: "please enter a number" });
