﻿if(!$.aspnet)
    $.aspnet = {};

$.extend($.aspnet, {
    getWebForm: function () {
        return $('form#aspnetForm').validate({ onsubmit: false, onkeyup: false }).currentForm;
    },
    getGroupValidator: function (group) {
        if (typeof group == 'undefined')
            group = 'default';

        var key = 'aspnet_validation_group_' + group;
        var aspnetForm = $.aspnet.getWebForm();

        var validator = $.data(aspnetForm, key);

        if (validator) {
            return validator;
        }

        validator = new $.validator($.aspnet.defaultValidatorOptions, aspnetForm);
        $.data(aspnetForm, key, validator);

        return validator;
    },
    defaultValidatorOptions: {
        ignore: ".ignore",
        errorClass: "error",
        errorElement: "span",
        onkeyup: false,
        onsubmit: false
    }
});

$.extend($.fn, {
    aspnet_validate: function (arg1, arg2, arg3, arg4) {
        if (!this.length) {
            return;
        }

        if (!$(this[0]).is('input') && !$(this[0]).is('button') && !$(this[0]).is('select')) {
            return;
        }

        if (arguments.length == 0) {
            var valGroup = $(this[0]).attr('valgroup');

            if (!valGroup || valGroup == '')
                return false;

            var formValidator = $($.aspnet.getWebForm()).validate();
            var groupValidator = $.aspnet.getGroupValidator(valGroup);

            $.extend(true, formValidator.settings, groupValidator.settings);
            $.extend(true, formValidator.groups, groupValidator.groups);

            return !formValidator.element(this[0]);
        }

        var addRule = function (el, options) {
            var validationGroup = $(el).attr('valgroup');
            var groupValidator = $.aspnet.getGroupValidator(validationGroup);

            if (!groupValidator) {
                alert('Must have group validator.');
                return;
            }

            // try to aggregate options together;
            var validationOptions = $.data(el, 'aspnet_validation_rule_options');

            if (validationOptions) {
                var mergedOptions = $.extend(true, {}, validationOptions, options);
                $.data(el, 'aspnet_validation_rule_options', mergedOptions);
            }
            else {
                $.data(el, 'aspnet_validation_rule_options', options);
            }

            validationOptions = $.data(el, 'aspnet_validation_rule_options');

            var argument = validationOptions['rule'];

            if (argument) {
                var element = el;
                var settings = groupValidator.settings;

                var validatorRules = settings.rules;
                validatorRules[element.name] = $.validator.normalizeRule(argument);

                if (argument.messages)
                    settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages);
            }
        };

        var getOptions = function (method, message, errorPlacement) {
            var options = {
                rule: {
                    messages: {}
                }
            };

            if (typeof method == 'string')
                options.rule[method] = true;
            else
                return null;

            if (typeof message == 'string')
                options.rule.messages[method] = message;

            if (typeof errorPlacement == 'function')
                $.extend(options, { errorPlacement: errorPlacement });

            return options;
        };

        var addFieldGroup = function (el, fieldGroup) {
            var validationGroup = $(el).attr('valgroup');
            var groupValidator = $.aspnet.getGroupValidator(validationGroup);

            if (!groupValidator) {
                alert('Must have group validator.');
                return;
            }
            groupValidator.groups[el.name] = fieldGroup;
        };

        if (arguments.length <= 1) {
            if (typeof arg1 == 'string') {
                var opt = getOptions(arg1);
                if (opt) addRule(this[0], opt);
            }
            else if (typeof arg1 == 'object') {
                addRule(this[0], arg1);
            }
        }
        else {
            if (typeof arg3 == 'function') {
                var opt = getOptions(arg1, arg2, arg3);
                if (opt) addRule(this[0], opt);
            }
            else {
                var opt = getOptions(arg1, arg2);
                if (opt) addRule(this[0], opt);
            }

            var fieldGroup = null;
            if (typeof arg3 == 'string')
                fieldGroup = arg3;
            else if (typeof arg4 == 'string')
                fieldGroup = arg4;

            if (fieldGroup) {
                addFieldGroup(this[0], fieldGroup);
            }
        }
    },
    aspnet_validate_errorPlacement: function () {
        if (!this.length)
            return null;

        var ruleOptions = $.data(this[0], 'aspnet_validation_rule_options');

        if (ruleOptions && ruleOptions.errorPlacement && typeof ruleOptions.errorPlacement == 'function')
            return ruleOptions.errorPlacement;

        return null;
    },
    aspnet_resetValidation: function (elements) {
        for (var i = 0; i < elements.length; ++i) {
            var formValidator = $($.aspnet.getWebForm()).validate();
            var currentElement = elements[i];
            var errorClass = $(currentElement).attr("validation-error-class");
            errorClass && errorClass != '' && $(currentElement).removeClass(errorClass);
            $(formValidator.errorsFor(currentElement)).each(function () { $(this).remove(); });
        }
    },
    aspnet_validateGroup: function (valGroup, opt) {
        var isValid = true;

        if (!this.length) {
            return false;
        }

        var formValidator = $($.aspnet.getWebForm()).validate();
        var groupValidator = $.aspnet.getGroupValidator(valGroup);

        // get elements belonging to validation group;
        var groupElements = $(this[0]).find('*[valgroup="' + valGroup + '"]').not(groupValidator.settings.ignore);

        // reset validation
        $(this).aspnet_resetValidation(groupElements);

        $.extend(true, formValidator.settings, groupValidator.settings);

        opt && $.extend(true, formValidator.settings, opt);

        $.extend(true, formValidator.groups, groupValidator.groups);

        var invalids = [];

        var activeErrorClass = formValidator.settings.errorClass;

        for (var i = 0; i < groupElements.length; ++i) {
            var currentElement = groupElements[i];

            if (!formValidator.element(currentElement)) {
                $(currentElement).attr("validation-error-class", activeErrorClass);
                var func = $(currentElement).aspnet_validate_errorPlacement();
                if (func) {
                    var errors = formValidator.errorsFor(currentElement);
                    for (var j = 0; j < errors.length; ++j)
                        func($(errors[j]));
                }
                invalids.push(currentElement);
                isValid = false;
            }
            else { }
        }

        // :WORKAROUND: force show all generated errors upon validate to work around the fact that
        //  jquery validator doesn't validate fields that grouped together using their native field
        //  grouping feature (which only manages with message rendering, not the actual validate)

        for (var i = 0; i < invalids.length; ++i) {
            var el = invalids[i];
            try {
                var errors = formValidator.errorsFor(el);
                $(errors).show();
            } catch (e) { };
        }

        return isValid;
    }
});
$.validator.addMethod('aiim_website', function (value, element) {
    if (value.indexOf('://') <= -1) {
        value = 'http://' + value;
    }
    return $.validator.methods['url'].call(this, value, element);
}, "");
