﻿jQuery.validator.addMethod("regex", function(value, element, params) {
    if (this.optional(element)) {
        return true;
    }

    var match = new RegExp(params).exec(value);
    return (match && (match.index == 0) && (match[0].length == value.length));
});

jQuery.validator.addMethod("uniqueEmail", function (value, element, params) {
    if (this.optional(element)) {
        return true;
    }
    // sync ajax
    var isValid = false;
    //this.remote(value, element, '/Validate/Email');
    $.ajax({
        url: '/Validate/Email',
        data: { value: value },
        dataType: "json",
        async: false,
        success: function (result) {
            isValid = result.isValid;
        }
    });

    return isValid;

});

function __MVC_ApplyValidator_Remote(object, options) {
    object["remote"] = options;
};

function __MVC_ApplyValidator_Range(object, min, max) {
    object["range"] = [min, max];
};

function __MVC_ApplyValidator_RegularExpression(object, pattern) {
    object["regex"] = pattern;
};

function __MVC_ApplyValidator_Required(object) {
    object["required"] = true;
};

function __MVC_ApplyValidator_StringLength(object, maxLength) {
    object["maxlength"] = maxLength;
};

function __MVC_ApplyValidator_Unknown(object, validationType, validationParameters) {
    object[validationType] = validationParameters;
};

function __MVC_CreateFieldToValidationMessageMapping(validationFields) {
    var mapping = {};

    for (var i = 0; i < validationFields.length; i++) {
        var thisField = validationFields[i];
        mapping[thisField.FieldName] = "#" + thisField.ValidationMessageId;
    }

    return mapping;
};

function __MVC_CreateErrorMessagesObject(validationFields) {
    var messagesObj = {};

    for (var i = 0; i < validationFields.length; i++) {
        var thisField = validationFields[i];
        var thisFieldMessages = {};
        messagesObj[thisField.FieldName] = thisFieldMessages;
        var validationRules = thisField.ValidationRules;

        for (var j = 0; j < validationRules.length; j++) {
            var thisRule = validationRules[j];
            if (thisRule.ErrorMessage) {
                var jQueryValidationType = thisRule.ValidationType;
                switch (thisRule.ValidationType) {
                    case "regularExpression":
                        jQueryValidationType = "regex";
                        break;

                    case "stringLength":
                        jQueryValidationType = "maxlength";
                        break;
                }

                thisFieldMessages[jQueryValidationType] = thisRule.ErrorMessage;
            }
        }
    }

    return messagesObj;
};

function __MVC_CreateErrorMessagesObjectForField(thisField) {
    
   
    var thisFieldMessages = {};
    var validationRules = thisField.ValidationRules;

    for (var j = 0; j < validationRules.length; j++) {
        var thisRule = validationRules[j];
        if (thisRule.ErrorMessage) {
            var jQueryValidationType = thisRule.ValidationType;
            switch (thisRule.ValidationType) {
                case "regularExpression":
                    jQueryValidationType = "regex";
                    break;

                case "stringLength":
                    jQueryValidationType = "maxlength";
                    break;
            }

            thisFieldMessages[jQueryValidationType] = thisRule.ErrorMessage;
        }
    }
    return thisFieldMessages;
};

function __MVC_CreateRulesForField(validationField, withMessages) {
    var validationRules = validationField.ValidationRules;

    // hook each rule into jquery
    var rulesObj = {
    };

    if (withMessages)
        rulesObj.messages = __MVC_CreateErrorMessagesObjectForField(validationField);

    for (var i = 0; i < validationRules.length; i++) {
        var thisRule = validationRules[i];
        switch (thisRule.ValidationType) {
            case "range":
                __MVC_ApplyValidator_Range(rulesObj,
                    thisRule.ValidationParameters["minimum"], thisRule.ValidationParameters["maximum"]);
                break;

            case "regularExpression":
                __MVC_ApplyValidator_RegularExpression(rulesObj,
                    thisRule.ValidationParameters["pattern"]);
                break;

            case "required":
                __MVC_ApplyValidator_Required(rulesObj);
                break;

            case "remote":
                __MVC_ApplyValidator_Remote(rulesObj,
                    thisRule.ValidationParameters["options"]);
                break;

            case "stringLength":
                __MVC_ApplyValidator_StringLength(rulesObj,
                    thisRule.ValidationParameters["maximumLength"]);
                break;
            case "RequiredIf":
                __MVC_ApplyValidator_RequiredIf(rulesObj,
                    thisRule.ValidationType, thisRule.ValidationParameters, validationField);
                break;

            default:
                __MVC_ApplyValidator_Unknown(rulesObj,
                    thisRule.ValidationType, thisRule.ValidationParameters);
                break;
        }
    }

    return rulesObj;
};

function __MVC_CreateValidationOptions(validationFields, withMessages) {
    var rulesObj = {};
    for (var i = 0; i < validationFields.length; i++) {
        var validationField = validationFields[i];
        var fieldName = validationField.FieldName;
        rulesObj[fieldName] = __MVC_CreateRulesForField(validationField, withMessages);
    }

    return rulesObj;
};

function __MVC_EnableClientValidation(validationContext) {
    // this represents the form containing elements to be validated
    var theForm = $("#" + validationContext.FormId);
    var fields = validationContext.Fields;
    var rulesObj = __MVC_CreateValidationOptions(fields);
    var fieldToMessageMappings = __MVC_CreateFieldToValidationMessageMapping(fields);
    var errorMessagesObj = __MVC_CreateErrorMessagesObject(fields);

    var options = {
        errorClass: "input-validation-error",
        onsubmit: false, // CUSTOM
        errorElement: "span",
        errorPlacement: function(error, element) {
            var messageSpan = fieldToMessageMappings[element.attr("name")];
            $(messageSpan).empty();
            $(messageSpan).removeClass("field-validation-valid");
            $(messageSpan).addClass("field-validation-error");
            error.removeClass("input-validation-error");
            error.attr("_for_validation_message", messageSpan);
            error.appendTo(messageSpan);
        },
        messages: errorMessagesObj,
        rules: rulesObj,
        success: function(label) {
            var messageSpan = $(label.attr("_for_validation_message"));
            $(messageSpan).empty();
            $(messageSpan).addClass("field-validation-valid");
            $(messageSpan).removeClass("field-validation-error");
        }
    };

    // register callbacks with our AJAX system
    var formElement = document.getElementById(validationContext.FormId);
    var registeredValidatorCallbacks = formElement.validationCallbacks;
    if (!registeredValidatorCallbacks) {
        registeredValidatorCallbacks = [];
        formElement.validationCallbacks = registeredValidatorCallbacks;
    }
    registeredValidatorCallbacks.push(function() {
        theForm.validate();
        return theForm.valid();
    });
    
    $.extend(options, ILP.validation.defaults);// CUSTOM
    
    theForm.validate(options);

    theForm.validationEngine({ inlineValidation: false }); // CUSTOM
};

function __MVC_AddAjaxFormFields() {
    var allFormOptions = window.mvcClientValidationMetadata;
    if (allFormOptions) {
        while (allFormOptions.length > 0) {
            var thisFormOptions = allFormOptions.pop();
            var rulesObj = __MVC_CreateValidationOptions(thisFormOptions.Fields, true)
            for (var field in rulesObj) {
                //debugger;
                // add jquery rule to validator.
                if (field) {
                    var $field = $('#' + field);
                    var hasValidator = $.data($field[0].form, 'validator');
                    if (hasValidator)// && hasValidator)
                        $field.rules('add', rulesObj[field]);
                }
            }
        }
    }
};

function __MVC_AjaxFormLoad() {
    var allFormOptions = window.mvcClientValidationMetadata;
    if (allFormOptions) {
        while (allFormOptions.length > 0) {
            var thisFormOptions = allFormOptions.pop();
            __MVC_EnableClientValidation(thisFormOptions);
        }
    }
};

$(document).ready(function () {
    var allFormOptions = window.mvcClientValidationMetadata;
    if (allFormOptions) {
        while (allFormOptions.length > 0) {
            var thisFormOptions = allFormOptions.pop();
            __MVC_EnableClientValidation(thisFormOptions);
        }
    }
});

