﻿//Written by Trevor Scharf


var validation_extensions = new Array();


function proxyValidator(elm, selector) {
    this.element = elm;
    this.selector = selector;
    this.validClasses = new Array();
    this.invalidClasses = new Array();
    this.required = function (val, dependency) {
        if (val == null) {
            $(this.element).validationProperty("required", true, null, dependency);
        } else {
            if (typeof val == "Boolean") {
                $(this.element).validationProperty("required", true, null, dependency);
            } else {
                $(this.element).validationProperty("required", true, val, dependency);
            }
        }
        return this;
    }
    this.validClass = function (_class) {
        $(this.selector).validationProperty("successClass", _class);
        return this;
    }
    this.invalidClass = function (_class) {
        $(this.selector).validationProperty("errorClass", _class);
        return this;
    }
    this.minLength = function (val, message, dependency) {
        $(this.element).validationProperty("minLength", val, message, dependency);
        return this;
    }
    this.maxLength = function (val, message, dependency) {
        $(this.element).validationProperty("maxLength", val, message, dependency);
        return this;
    }
    this.min = function (val, message, dependency) {
        $(this.element).validationProperty("min", val, message, dependency);
        return this;
    }
    this.max = function (val, message, dependency) {
        $(this.element).validationProperty("max", val, message, dependency);
        return this;
    }
    this.fixedLength = function (val, message, dependency) {
        $(this.element).validationProperty("fixedLength", val, message, dependency);
        return this;
    }
    this.bindUpperCase = function (startIndex, endIndex) {
        $(this.element).bindUpperCase(startIndex, endIndex);
        return this;
    }
    this.bindLowerCase = function (startIndex, endIndex) {
        $(this.element).bindLowerCase(startIndex, endIndex);
        return this;
    }
    this.addValidator = function (validator, errorMessage, callback, tokenName) {
        $(this.element).addValidationFunction(validator, errorMessage, "", callback, tokenName);
        return this;
    }

    this.onInvalid = function (oninvalid, keyup) {
        $(this.selector).onInvalid(oninvalid, keyup);
        return this;
    }
    this.onValid = function (onvalid, keyup) {
        $(this.selector).onValid(onvalid, keyup);
        return this;
    }
    this.afterValidation = function (failure, success, keyup) {
        $(this.selector).onInvalid(failure, keyup);
        $(this.selector).onValid(success, keyup);
        return this;
    }
    this.beforeValidation = function (beforeValidation) {
        var that = $(this.selector);
        var before = $(that).data("beforeValidation");
        if (before == null || before == undefined) {
            before = new Array();
        }
        before.push(beforeValidation);
        $(that).data("beforeValidation", before);
        return this;
    }
    this.bindMessage = function (label, modifier, keyup) {
        $(this.element).keyup(function () {
            var val_object = $(this).validateField();
            if (!val_object.isValid) {
                if (modifier == null) {
                    $(label).text(val_object.errorMessage);
                } else {
                    $(label).text(modifier(val_object.errorMessage));
                }
            } else {
                $(label).text((val_object.successMessage != undefined ? val_object.successMessage : ""));
            }
        });
        return this;
    }
    this.phone = function (message, dependency) {
        $(this.element).addValidationFunction(function () {
            var _t = dependency != null;
            if (_t) {
                _t = dependency();
            } else {
                _t = true;
            }
            if (_t) {
                var regex = /^(\()?([0-9]{3}(\)?)-)?[0-9]{3}-[0-9]{4}$/;
                return regex.test($(this).val());
            } else {
                return true;
            }
        }, message);
        return this;
    }
    this.creditCard = function (types, message, successMessage, dependency) {
        $(this.element).addValidationFunction(function () {
            var _t = dependency != null;
            if (_t) {
                _t = dependency();
            } else {
                _t = true;
            }
            if (_t) {
                var _types = types.split(',');
                var _validNumber = false;
                for (var i = 0; i < _types.length; i++) {
                    var _regex;
                    if (!_validNumber) {
                        switch (_types[i]) {
                            case "visa":
                                _regex = /^4[0-9]{12}(?:[0-9]{3})?$/;
                                break;
                            case "mastercard":
                                _regex = /^5[1-5][0-9]{14}$/;
                                break;
                            case "americanexpress":
                                _regex = /^3[47][0-9]{13}$/;
                                break;
                            case "discover":
                                _regex = /^6(?:011|5[0-9]{2})[0-9]{12}$/;
                                break;
                        }
                        _validNumber = _regex.test($(this).val());
                    }
                }
                return _validNumber;
            } else {
                return true;
            }
        }, message, successMessage);
        return this;
    }
    this.email = function (errorMessage, dependency) {
        var _t = dependency != null;
        if (_t) {
            _t = dependency();
        } else {
            _t = true;
        }
        if (_t) {
            if (errorMessage == null) {
                errorMessage = "Email must be properly formatted";
            }
            $(this.element).addValidationFunction(function () {
                return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test($(this).val());
            }, errorMessage);
        } else {
            return true;
        }
        return this;
    }
    //Big thanks for Paulo P. Marinas for his jQuery Plugin "AlphaNumeric" which I used for the next three functions
    this.alphanumeric = function (obj) {
        if (obj != null) {
            $(this.element).alphanumeric(obj);
        } else {
            $(this.element).alphanumeric();
        }
        return this;
    }
    this.alpha = function (obj) {
        $(this.element).alpha(obj);
        return this;
    }
    this.numeric = function (obj) {
        if (obj != null) {
            $(this.element).numeric(obj);
        } else {
            $(this.element).numeric();
        }
        return this;
    }
    this.password = function () {
        $(this.element).addValidationFunction(function () {
            return /^([A-Za-z]+[^A-Za-z]+.)$/.test($(this).val());
        }, "Weak Password");
        return this;
    }
    this.DropDownNotEmptyOrZero = function () {
        $(this.element).addValidationFunction(function () {
            var val = $(this).val();
            var valid = true;
            if (val == 0) {
                valid = false;
            }
            return valid;
        }, "Empty not Accepted");
        return this;
    }
    this.money = function () {
        $(this.element).numeric({allow: "." });
        $(this.element).addValidationFunction(function () {
            return /^[0-9]+\.[0-9]{1,2}$/.test($(this).val());
        },"Invalid Format(Example: '5.55')");
        return this;
    }
    this.matchField = function (selector, message, dependency) {
        $(this.element).validationProperty("matchField", selector, message, dependency);
        return this;
    }
    this.minDate = function (date, message, dependency) {
        if (date == "now") {
            date = new Date().getMonth() + "/" + new Date().getDate() + "/" + new Date().getYear();
        }
        $(this.element).validationProperty("minDate", date, message, dependency);
        return this;
    }
    this.maxDate = function (date, message, dependency) {
        if (date == "now") {
            date = new Date().getMonth() + "/" + new Date().getDate() + "/" + new Date().getYear();
        }
        $(this.element).validationProperty("maxDate", date, message);
        return;
    }

    this.regex = function (reg, errorMessage, dependency) {
        $(this.element).validationProperty("regex", reg, errorMessage, dependency);
        return this;
    }
    this.validationOff = function () {
        $(this.element).validationProperty("validate", false);
        return this;
    }
    this.validationOn = function () {
        $(this.element).validationProperty("validate", true);
        return this;
    }
    this.isValid = function () {
        return $(this.element).isValid();
    }
    this.ifElementValue = function (selector, val) {
        $(this.element).keyup(function () {
            if ($(selector).val() == val) {
                $(this).validationOff();
            } else {
                $(this).validationOn();
            }
        });
        return this;
    }
    this.stopIf = function (boolean) {
        $(this.element).keyup(function () {
            if (boolean.call(this.element)) {
                $(this).validationOff();
            } else {
                $(this).validationOn();
            }
        });
        return this;
    }

}

function vManager(selector) {
    if (selector == "" || selector == null) {
        selector = "form";
    }
    var proxy_object = new Object();
    proxy_object.form = $(selector);
    proxy_object.hookupValidation = function (failure, success, keyup) {
        $(selector).hookupFormValidation(failure, success);
    }
    $(selector + " > input," + selector + " > select ").each(function (i) {
        var name = $(this).attr("name");
        var _selector = selector + " > input[name=" + name + "]," + selector + " > select ";
        if (name == null || name == "") {
        } else {
            proxy_object[name] = new proxyValidator($(this),_selector);
        }
    });
    return proxy_object;
}
vManager.prototype.field = function (selector) {
    return new proxyValidator($(selector));
}

function validationMessage(element, errorMessage, valid, errorName, value, successMessage,isdefaultMessage) {
    this.element = element;
    this.errorName = errorName;
    this.errorMessage = errorMessage;
    this.successMessage = successMessage;
    this.isValid = valid;
    this.value = value;
    this.isDefaultMessage = isdefaultMessage;
}

function validationFormWrapper(valMsgs, valid, form) {
    this.validationMessages = valMsgs;
    this.isValid = valid;
    this.form = form;
}
$.validateMax = function (val, max) {
    return (val <= max);
}
$.validClass = function (name) {
    $("form input[type=text],input[type=password],form textarea,form select").each(function () {
        $.validator(this).validClass(name);
    });
}
$.invalidClass = function (name) {
    $("form input[type=text],input[type=password],form textarea, form select").each(function () {
        $.validator(this).invalidClass(name);
    });
}
$.validateMin = function (val, min) {
    return (val >= min);
}
$.validateRange = function (val, min, max) {
    return (val >= min && val <= max);
}
$.validateLength = function (val, min, max) {
    if (max != null) {
        return val.length >= min && val.length <= max;
    } else {
        return val.length >= min;
    }
}
$.validateRegExp = function (val, reg) {
    return reg.test(val);
}

$.validateDateMin = function (val, minDate) {
    var md = Date.parse(minDate);
    var vd = Date.parse(val);
    return vd >= md;
}
$.validateDateMax = function (val, maxDate) {
    var md = Date.parse(maxDate);
    var vd = Date.parse(val);
    return vd <= md;
}
$.validateDateRange = function (val, minDate, maxDate) {
    return $.validateDateMin(val, minDate) && $.validateDateMax(val, maxDate);
}
$.formatString = function (format) {
    for (var i = 1, l = arguments.length; i < l; i++) {
        format = format.replace("{" + (i - 1) + "}", arguments[i]);
    }
    return format;
};

function dynamicList(elem) {
    $(elem).dynamicList();
    this.element = $(elem);
    this.push = function (params) {
        if (typeof params === typeof new Array()) {
            $(this.element).dynamicPush(params)
        } else {
            $(this.element).dynamicPush([params]);
        }
        return this;
    }
    this.clearList = function () {
        $(this.element).dynamicClear();
        return this;
    }
    this.reset = function (items) {
        $(this.element).dynamicReset(items);
        return this;
    }
    this.deleteItem = function (item) {
        $(this.element).dynamicRemove(item);
        return this;
    }
    this.liveHookup = function (form,success) {
        var _that = this;
        $.hookupFieldValidation(function (token) { if ($(form).wasAttempted()) { _that.reset($.errors(form)); } }, function (token) { if ($(form).wasAttempted()) { _that.reset($.errors(form)); } }, $(form).find("input[type=text],textarea,select"), true);
    }
}
$.fn.extend({


    validateField: function (custom_val, silent) {
        var that = $(this);
        var value = "";
        if (custom_val == null) {
            value = $(this).val();
        } else {
            value = custom_val;
        }
        var isvalid = true;
        var valMessage = null;
        var validation_props;

        var beforeValidation = $(this).data("beforeValidation");
        if (beforeValidation != undefined) {
            for (var i = 0; i < beforeValidation.length; i++) {
                beforeValidation[i].call(that);
            }
        }
        if ($(this).data("validation-token") == null) {
            var o = "{" + ($(this).attr("data-validate") == undefined ? "" : $(this).attr("data-validate")) + "}";
            validation_props = eval("(" + o + ")");
            $(this).data("validation-token", validation_props);
        } else {
            validation_props = $(this).data("validation-token");
        }


        if (validation_props.validate || validation_props.validate == undefined) {
            if (validation_props.required != undefined && isvalid) {
                var _t = validation_props.requiredDependency;
                if (_t != undefined) {
                    _t = validation_props.requiredDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = value != "" && value != null;
                    if (!isvalid) {
                        var message = validation_props.requiredMessage;

                        var successMessage = (validation_props.requiredSuccessMessage != undefined ? validation_props.requiredSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "This field is required"), false, "required", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.min != undefined && isvalid) {
                var _t = validation_props.minDependency;
                if (_t != undefined) {
                    _t = validation_props.minDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateMin(value, validation_props.min);
                    if (!isvalid) {
                        var message = validation_props.minMessage;
                        var successMessage = (validation_props.minSuccessMessage != undefined ? validation_props.minSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "The minimum required is " + validation_props.min + "."), false, "min", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.min != undefined && isvalid) {
                var _t = validation_props.maxDependency;
                if (_t != undefined) {
                    _t = validation_props.maxDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateMax(value, validation_props.max);
                    if (!isvalid) {
                        var message = validation_props.maxMessage;
                        var successMessage = (validation_props.maxSuccessMessage != undefined ? validation_props.maxSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "The maximum required is " + validation_props.max + "."), false, "max", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.minLength != undefined && isvalid) {
                var _t = validation_props.minLengthDependency;
                if (_t != undefined) {
                    _t = validation_props.minLengthDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateLength(value, validation_props.minLength);
                    if (!isvalid) {
                        var message = validation_props.minLengthMessage;
                        var successMessage = (validation_props.maxSuccessMessage != undefined ? validation_props.maxSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Minimum length of " + validation_props.minLength + " not met"), false, "minLength", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.maxLength != undefined && isvalid) {
                var _t = validation_props.maxLengthDependency;
                if (_t != undefined) {
                    _t = validation_props.maxLengthDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateLength(value, 0, validation_props.maxLength);
                    if (!isvalid) {
                        var message = validation_props.maxLengthMessage;
                        var successMessage = (validation_props.maxLengthSuccessMessage != undefined ? validation_props.maxLengthSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Maximum length of " + validation_props.maxLength + " met"), false, "maxLength", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.fixedLength != undefined && isvalid) {
                var _t = validation_props.fixedLengthDependency;
                if (_t != undefined) {
                    _t = validation_props.fixedLengthDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = value.length == validation_props.fixedLength;
                    if (!isvalid) {
                        var message = validation_props.fixedLengthMessage;
                        var successMessage = (validation_props.fixedLengthSuccessMessage != undefined ? validation_props.fixedLengthSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Fixed length of " + validation_props.fixedLength + " met"), false, "fixedLength", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.minDate != undefined && isvalid) {
                var _t = validation_props.minDateDependency;
                if (_t != undefined) {
                    _t = validation_props.minDateDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateDateMin(value, validation_props.minDate);
                    if (!isvalid) {
                        var message = validation_props.minDateMessage;
                        var successMessage = (validation_props.minDateSuccessMessage != undefined ? validation_props.minDateSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Min Date of " + validation_props.minDate + " met"), false, "minDate", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.maxDate != undefined && isvalid) {
                var _t = validation_props.maxDateDependency;
                if (_t != undefined) {
                    _t = validation_props.maxDateDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateDateMax(value, validation_props.maxDate);
                    if (!isvalid) {
                        var message = validation_props.maxDateMessage;
                        var successMessage = (validation_props.maxDateSuccessMessage != undefined ? validation_props.maxDateSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Max Date of " + validation_props.maxDate + " met"), false, "maxDate", value, successMessage, message == undefined);
                    }
                }
            }
            if (validation_props.regex != undefined && isvalid) {
                var _t = validation_props.regexDependency;
                if (_t != undefined) {
                    _t = validation_props.regexDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $.validateRegExp(value, validation_props.regex);
                    if (!isvalid) {
                        var message = validation_props.regexMessage;
                        var successMessage = (validation_props.regexSuccessMessage != undefined ? validation_props.regexSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Regex failed"), false, "regex", value, successMessage, message == undefined);
                    }
                }
            }

            if (validation_props.matchField != undefined && isvalid) {
                var _t = validation_props.matchFieldDependency;
                if (_t != undefined) {
                    _t = validation_props.matchFieldDependency.call($(this)); ;
                } else {
                    _t = true;
                }
                if (_t) {
                    isvalid = $(this).val() == $(validation_props.matchField).val();
                    if (!isvalid) {
                        var message = validation_props.matchFieldMessage;
                        var successMessage = (validation_props.matchFieldSuccessMessage != undefined ? validation_props.matchFieldSuccessMessage : null);
                        valMessage = new validationMessage(that, (message != undefined ? message : "Field does not match " + validation_props.matchField + "."), false, "matchField", value, successMessage, message == undefined);
                    }
                }
            }
            if ($(this).data("validation-functions") != undefined && $(this).data("validation-functions") != null) {
                for (var i = 0; i < $(this).data("validation-functions").length; i++) {
                    var _fun = $(this).data("validation-functions")[i];
                    if (isvalid && (_fun.dependency != null ? _fun.dependency() : true)) {
                        isvalid = _fun.validator.call($(this), validation_props);
                        if (!isvalid) {
                            var message = _fun.errorMessage;
                            var tokenName = _fun.tokenName;
                            if (tokenName == undefined || tokenName == null) {
                                tokenName == "custom-validation";
                            }
                            valMessage = new validationMessage(that, (message != null ? message : ""), false, tokenName, value);
                            if (_fun.callback != undefined) {
                                _fun.callback();
                            }
                        }
                    }
                }
            }
        }

        if (isvalid) {

            valMessage = new validationMessage(that, "", true, "", value, "");
            if (silent == null) {
                $("#error-" + $(this).attr("id")).text("").css("color", "red").addClass("error-message");
                if ($(this).data("error-classes") != undefined) {
                    for (var i = 0; i < $(this).data("error-classes").length; i++) {
                        $(this).removeClass($(this).data("error-classes")[i]);
                    }
                }
                if ($(this).data("success-classes") != undefined) {
                    for (var i = 0; i < $(this).data("success-classes").length; i++) {
                        $(this).addClass($(this).data("success-classes")[i]);
                    }
                }
                $(this).removeClass(validation_props.errorClass).addClass(validation_props.successClass);
            }
        } else {
            if (silent == null) {
                if ($("body").data("format:" + valMessage.errorName) != null && valMessage.isDefaultMessage) {
                    valMessage.errorMessage = $.formatString($("body").data("format:" + valMessage.errorName), $(that).attr("name"));
                }
                $("#error-" + $(this).attr("id")).addClass("error-message").text(valMessage.errorMessage);
                if ($(this).data("error-classes") != undefined) {
                    for (var i = 0; i < $(this).data("error-classes").length; i++) {
                        $(this).addClass($(this).data("error-classes")[i]);
                    }
                }
                if ($(this).data("success-classes") != undefined) {
                    for (var i = 0; i < $(this).data("success-classes").length; i++) {
                        $(this).removeClass($(this).data("success-classes")[i]);
                    }
                }
                $(this).removeClass(validation_props.successClass).addClass(validation_props.errorClass);
            }
        }

        return valMessage;
    },
    validateForm: function (silent) {
        var that = $(this);
        var validation_objects = new Array();
        var isValid = true;
        $(this).find("input:not([data-validate]),select").each(function () {
            if ($(this).parent(that).length > 0) {
                if ($(this).data("validation-token") != null) {
                    validation_objects.push($(this).validateField(silent));
                }
            }
        });
        $(this).find("[data-validate]").each(function () {
            if ($(this).parent(that).length > 0) {
                validation_objects.push($(this).validateField(silent));
            }
        });
        for (var i = 0; i < validation_objects.length; i++) {
            if (!validation_objects[i].isValid) {
                isValid = false;
            }
        }
        var form_val = new validationFormWrapper(validation_objects, isValid, that);
        if (silent == null) {
            $(this).data("attempted", true);
        }
        return form_val;
    },
    bindValidationMessage: function (label, modifier, keyup) {
        $.bindValidationMessage($(this), label, modifier, keyup);
    },
    validationProperty: function (property, val, errMessage, dependency, successMessage) {
        var that = $(this);
        if (val != null) {
            if ($(this).data("validation-token") == null) {
                var o = "{" + ($(this).attr("data-validate") == undefined || $(this).attr("data-validate") == null ? "" : $(this).attr("data-validate")) + "}";
                validation_props = eval("(" + o + ")");
                $(this).data("validation-token", validation_props);
                if ($(this).attr("data-validate") == null || $(this).attr("data-validate") == "") {
                    $(this).attr("data-validate", "");
                }
            }
            var token = $(this).data("validation-token");
            if (typeof val == "string") {
                token[property] = val;
            } else {
                token[property] = val;
            }
            if (errMessage != null) {
                token[property + "Message"] = errMessage;
            }
            if (successMessage != null) {
                token[property + "SuccessMessage"] = successMessage;
            }
            if (dependency != null) {
                token[property + "Dependency"] = dependency;
            }
        } else {
            if ($(this).data("validation-token") == null) {
                var o = "{" + ($(this).attr("data-validate") == undefined || $(this).attr("data-validate") == null ? "" : $(this).attr("data-validate")) + "}";
                validation_props = eval("(" + o + ")");
                $(this).data("validation-token", validation_props);
                if ($(this).attr("data-validate") == null || $(this).attr("data-validate") == "") {
                    $(this).attr("data-validate", "");
                }
            }
            var token = $(this).data("validation-token");
            return token[property];
        }
    },
    validationOn: function () {
        $(this).validationProperty("validate", true);
    },
    validationOff: function () {
        $(this).validationProperty("validate", false);
    },
    validationProperties: function (properties) {
        $(this).data("validation-token", properties);
    },
    maxSelections: function (num) {
        $(this).bind("click mouseup", function () {
            var selected = $(this).find("option:selected");
            var size = $(selected).size();
            if (size > num) {
                $(selected).each(function () {
                    if ($(this).data("selected")) {
                        $(this).removeAttr("selected");
                    }
                });
            }
        });
        $(this).find("option").click(function () {
            $(this).siblings("option").data("selected", false);
            if ($(this).is(":selected")) {
                $(this).data("selected", true);
            }
        });
        return this;
    },
    preventCombination: function (values) {
        $(this).click(function () {
            var selected = $(this).find("option:selected");
            var valid = [];
            if ($(selected).size() >= values.length) {
                $(selected).each(function (i, v) {
                    var val = $(this).val();
                    valid.push($.inArray(val, values) > -1);
                });
                if ($.inArray(false, valid) < 0) {
                    $(selected).each(function () {
                        if ($(this).data("selected")) {
                            $(this).removeAttr("selected");
                        }
                    });
                }
            }
        });
        $(this).find("option").click(function () {
            $(this).siblings("option").data("selected", false);
            if ($(this).is(":selected")) {
                $(this).data("selected", true);
            }
        });
        return this;
    },
    beforeValidation: function (beforeVal) {
        var that = $(this);
        var before = $(this).data("beforeValidation");
        if (before == null || before == undefined) {
            before = new Array();
        }
        before.push(beforeVal);
        $(this).data("beforeValidation", before);
    },
    addValidationFunction: function (func, errorMessage, successMessage, callback, tokenName) {
        var that = $(this);
        var validation_functions = ($(this).data("validation-functions") != null ? $(this).data("validation-functions") : new Array());
        validation_functions.push({ validator: func, errorMessage: errorMessage, successMessage: successMessage, callback: callback, tokenName: tokenName });
        $(this).data("validation-functions", validation_functions);
    },
    clearValidationFunctions: function () {
        $(this).data("validation-functions", null);
    },
    onInvalid: function (oninvalid, keyup) {
        var that = $(this);
        $.hookupFieldValidation(function (token) {
            oninvalid.call(that, token);
        }, null, that, keyup);
    },
    onValid: function (onvalid, keyup) {
        var that = $(this);
        $.hookupFieldValidation(null, function (token) {
            onvalid.call(that, token);
        }, that, keyup);
    },
    addValidClass: function (name) {
        if ($(this).data("success-classes") == undefined || $(this).data("success-classes") == null) {
            $(this).data("success-classes", new Array());
        }
        var newArray = $(this).data("success-classes");
        newArray.push(name);
        $(this).data("success-classes", newArray); ;
    },
    addInvalidClass: function (name) {
        if ($(this).data("error-classes") == undefined || $(this).data("error-classes") == null) {
            $(this).data("error-classes", new Array());
        }
        var newArray = $(this).data("error-classes");
        newArray.push(name);
        $(this).data("error-classes", newArray);
    },
    bindUpperCase: function (from, to) {
        $(this).keyup(function () {
            $(this).val($.rangeToUpperCase($(this).val(), from, to));
        });
    },
    bindLowerCase: function (from, to) {
        $(this).keyup(function () {
            $(this).val($.rangeToLowerCase($(this).val(), from, to));
        });
    },

    dynamicList: function (list) {
        $(this).find("li").remove();
        for (var i = 0, length = list.length; i < length; i++) {
            $(this).append("<li>" + list[i] + "</li>");
        }
    },
    clearChildren: function (selector) {
        $(this).find(selector).remove();
        return $(this);
    },
    hookupFormValidation: function (failure, success) {
        var that = $(this);
        $.hookupFormValidation(failure, success, that);
    },
    dynamicList: function () {
        $(this).data("data-list", new Array());
        return $(this);
    },
    dynamicPush: function (params) {
        var arr = $(this).data("data-list");
        for (var i = 0; i < params.length; i++) {
            arr.push(params[i]);
        }
        $(this).data("data-list");
        $(this).listRefresh();
        return $(this);
    },
    dynamicRemove: function (item) {
        var arr = $(this).data("data-list");
        var index = $.inArray(item, arr);
        arr[index] = null;
        arr = $.grep(arr, function (i, v) {
            return i != null;
        });
        $(this).data("data-list", arr);
        $(this).listRefresh();
        return $(this);
    },
    dynamicClear: function () {
        $(this).data("data-list", new Array());
        return $(this);
    },
    dynamicReset: function (items) {
        $(this).dynamicClear().dynamicPush(items);
        return $(this);
    },
    listRefresh: function () {
        $(this).find("li").remove();
        var arr = $(this).data("data-list");
        for (var i = 0; i < arr.length; i++) {
            $(this).append("<li>" + arr[i] + "</li>");
        }
    },
    isValid: function () {
        return $(this).validateField().isValid;
    },
    openXMLTemplate: function (url, field, templ) {
        $.ajax({
            type: "GET",
            url: url,
            dataType: "xml",
            success: function (xml) {
                var object = new Object();
                var that = $(this);
                for (var p in $(xml).find(field).get(0).properties) {
                    object[p] = $(this).attr(p);
                }
                $(templ).tmpl(object).appendTo(that);
            }
        });
    },
    wasAttempted: function () {
        var _attempted = false;
        if ($(this).data("attempted") != null) {
            _attempted = $(this).data("attempted");
        }
        return _attempted;
    },

    liveErrorList: function (list, success) {
        var lst = new dynamicList(list);
        lst.liveHookup($(this), success);
        $.hookupFormValidation(function (token, errors) { lst.reset(errors); return false; });
        return this;
    },
    starOn: function (alternate, nextcolumn) {
        if (alternate == null) {
            alternate = "*";
        }
        $(this).find("input,textarea").each(function () {
            var _required = $(this).validationProperty("required");
            if (_required != null && _required) {
                var _that = $(this);
                if (nextcolumn == null) {
                    $("<span class='validation-star'>" + alternate + "</span>").insertAfter($(_that));
                } else {
                    $("<span class='validation-star'>" + alternate + "</span>").insertAfter($($(_that).parents("td")[0]).next("td"));
                }
            }
        });
        return this;
    },
    validationImage: function (image, invalid, valid) {
        var that = $(this);
        $.liveFormValidation($(that), function () { $(image).show().attr("src", invalid); }, function () { $(image).attr("src", valid); });

    }
});
$.errors = function (form) {
    var errorList = new Array();
    var val_object = $(form).validateForm();
    for (var i = 0; i < val_object.validationMessages.length; i++) {
        if (!val_object.validationMessages[i].isValid) {
            errorList.push(val_object.validationMessages[i].errorMessage);
        }
    }
    return errorList;
}
$.postJson = function (url,object,success,failure) {
    $.ajax({
        contentType: "application/json; charset=utf-8",
        type: "POST",
        url: url,
        dataType: "json",
        data: JSON.stringify(object),
        success: success,
        failure: failure
    });
}
$.liveFormValidation = function (form, failure, success) {
    $(form).find("input,textarea").keyup(function () {
        var _isvalid = [];
        $(form).find("[data-validate]").each(function (v, i) {
            _isvalid.push($(this).validateField(null, true).isValid);
        });
        var invalid = $.inArray(false, _isvalid);
        if (invalid == -1) {
            if (success != null) {;
                success();
            }
        } else {
            if (failure != null) {
                failure();
            }
        }
    });

}
var submittable = true;
$.hookupFormValidation = function (failure, success, element, keyup) {
    var target = (element != null ? element : "form");
    var no_params = (failure == null && success == null && element == null && keyup == null);
    if (no_params) {
        keyup = true;
    }

    $(target).submit(function (e) {
        var errorList = new Array();
        var val_object = $(this).validateForm();
        e.stopPropagation();
        for (var i = 0; i < val_object.validationMessages.length; i++) {
            if (!val_object.validationMessages[i].isValid) {
                errorList.push(val_object.validationMessages[i].errorMessage);
            }
        }
        if (!val_object.isValid) {

            if (failure != null) {
                return failure(val_object, errorList, e);
            } else {
                return false;
            }
        } else {

                if (success != null) {
                    return success(val_object, errorList, e);
                } else {

                    return true;

                }

        }

        return false;
    });
}
$.validator = function (selector) {
    var _v = new proxyValidator($(selector), selector);
    _v.bindMessage("#error-" + $(selector).attr("name"));
    return _v;
}
$.validationFormat = function (validatorName, format) {
    $("body").data("format:" + validatorName, format);
}
$.rangeToUpperCase = function (value, from, to) {
    return (from == 0 ? "" : value.substring(0, from)) + value.substring(from, to + 1).toUpperCase() + value.substring(to + 1);
}
$.rangeToLowerCase = function (value, from, to) {
    return (from == 0 ? "" : value.substring(0, from)) + value.substring(from, to + 1).toLowerCase() + value.substring(to + 1);
}
$.fireError = function (message, label) {

}
$.fireSuccess = function (message, label) {

}
$.hookupFieldValidation = function (failure, success, element, keyup) {
    $("*:not([data-validate])").each(function () {
        if ($(this).data("validation-token") != null) {
            $(this).attr("data-validate", "");
        }
    });
    var target = (element != null ? element : "[data-validate]");
    $(target).live("blur change", function (e) {
        var that = this;
        var val_object = $(this).validateField();
        if (!val_object.isValid) {
            $(this).siblings(".validation-star").show();
            if (failure != null) {
                failure(val_object, e);
            }
        } else {
            $(this).siblings(".validation-star").hide();
            if (success != null) {
                success(val_object, e);
            }
        }
    });
    if (keyup != null && keyup) {
        $(target).live("keyup change", function (e) {

            var val_object = $(this).validateField();
            if (!val_object.isValid) {
                $("[data-validation-target=" + $(val_object.element).attr("id") + "]").text(val_object.errorMessage);
                $(this).siblings(".validation-star").show();
                if (failure != null) {
                    failure(val_object, e);
                }
            } else {
                $("[data-validation-target=" + $(val_object.element).attr("id") + "]").text((val_object.successMessage != undefined ? val_object.successMessage : ""));
                $(this).siblings(".validation-star").hide();
                if (success != null) {
                    success(val_object, e);
                }
            }
        });
    }
}
$.bindValidationMessage = function (input, label, modifier, keyup) {
    $.hookupFieldValidation(function (obj) {
        if (modifier == null) {
            $(label).text(obj.errorMessage);
        } else {
            $(label).text(modifier(obj));
        }
    }, function (obj) {
        $(label).text((obj.successMessage != undefined ? obj.successMessage : ""));
    }, input, keyup)
}
$.errorBox = function (form_val, properties) {
    var error_box = $("<div class='errorBox'></div>");
    $(error_box).css(properties.css);
    var w_width = $(window).width();
    var w_height = $(window).height();
    $(error_box).append("<ul class='error-box-list'>");
    for (var i = 0; i < form_val.validationMessages.length; i++) {
        if (!form_val.validationMessages[i].isValid) {
            $(error_box).append("<li class='error-box-error'>" + form_val.validationMessages[i].errorMessage + "</li>");
        }
    }
    $(error_box).append("</ul>");
    $(error_box).appendTo("body").hide();
    var e_height = $(error_box).height();
    var e_width = $(error_box).width();
    $(error_box).css({ position: "fixed", left: (w_width - e_width) / 2, top: (w_height - e_height) / 2 });
    if (properties.style == "traditional") {
        $(error_box).css({ backgroundColor: "red", color: "white", border: "2px solid pink", textAlign: "center" }).css("borderRadius", "7px");
    }
    if (properties.title != null) {
        $(error_box).prepend("<p style='font-weight:bold'>" + properties.title + "</p>");
    }
    $(error_box).show();
    return $(error_box);
}
$.removeErrorBoxes = function () {
    $(".errorBox").remove();
}
$.preventCheckCombination = function (elements) {

}


