﻿// does vsworx exist? if not set empty constructor
var vsworx = vsworx ? vsworx : {};
// does vsworx.global exist? if not set empty constructor
vsworx.validator = vsworx.validator ? vsworx.validator : { rules: [], failedElements: [], errorContainer: "" };

vsworx.validator.clearRules = function() {
    //re-initialize the arrays for each call of teh function because on one page we will have number of different forms
    this.rules = [];
    this.messages = [];
    this.failedElements = [];
};

vsworx.validator.validate = function() {
    //traverse through all teh rules
    $.each(this.rules, function(i, val) {
        var elId = val.split(":")[0];
        //elements & their respective rule list & message is separated by a ":", eg. "Text1:required,maxlength[5]:Please enter Text1"
        var elRules = val.split(":")[1];
        //get the error msg
        var elMsg = val.split(":")[2];
        //ruels for an element are separated by a comma
        var elRulesArr = elRules.split(",");
        //extract the element Id
        var element = $("#" + elId);
        //get the element value
        var value = $(element).val();

        //set is valid = true by default for each rule
        var isValid = true;

        //vsworx.validator.debug(elRulesArr.length);
        $.each(elRulesArr, function() {
            var ruleText = this.toString();
            var rule = "";
            var ruleParam = "";
            //if rule has some params then segregate the params from teh rule name, eg. maxlength[5]
            if (ruleText.indexOf("[", 0) > 0) {
                rule = ruleText.substr(0, ruleText.indexOf("[", 0)).toLowerCase();
                //extract teh param from within "[]"
                ruleParam = ruleText.substring(ruleText.indexOf("[", 0) + 1, ruleText.length - 1);
            } else {
                rule = this.toLowerCase();
            }
            //vsworx.validator.debug(rule + " - " + ruleParam);
            switch (rule) {
                case "required":
                    isValid = vsworx.validator.required(element, value);
                    break;
                case "email":
                    isValid = vsworx.validator.email(element, value);
                    break;
                case "url":
                    isValid = vsworx.validator.url(element, value);
                    break;
                 case "domain":
                    isValid = vsworx.validator.domain(element,ruleParam);
                     break;
                case "password":
                    isValid = vsworx.validator.password(element, value);
                     break;
                case "digits":
                    isValid = vsworx.validator.digits(element, value);
                    break;
                case "number":
                    isValid = vsworx.validator.number(element, value);
                    break;
                case "min":
                    isValid = vsworx.validator.min(element, value, ruleParam);
                    break;
                case "max":
                    isValid = vsworx.validator.max(element, value, ruleParam);
                    break;
                case "minlength":
                    isValid = vsworx.validator.minlength(element, value, ruleParam);
                    break;
                case "maxlength":
                    isValid = vsworx.validator.maxlength(element, value, ruleParam);
                    break;
                 case "comparepassword":
                    isValid = vsworx.validator.comparepassword(element, value, ruleParam);
                    break;
                default:
                    break;
            } // end of switch statement for rule
            //if any of the validation fails for the element, break out of the rules array each loop
            if (isValid == false) {
                return false;
            }
        }); // end of rules [each loop] for 1 single element
        //if any rule fails for ANY of the element, add it to the failed elements array
        if (isValid == false) {
            vsworx.validator.failedElements.push({ id: elId, msg: elMsg });
            //implement the errorInput class on the failing fields
            $("#" + elId).addClass("errorInput");
        }
        else {
            $("#" + elId).removeClass("errorInput");
        }
    }); //end of all elemenets array

    var errMsg = "";
    //showing teh error msg on teh screen
    if (vsworx.validator.failedElements.length > 0) {
        errMsg = errMsg + "<ul>"
        $.each(vsworx.validator.failedElements, function() {
            var elId = this.id;
            var elMsg = this.msg;
            errMsg = errMsg + "<li>" + elMsg + "</li>";
        });
        errMsg = errMsg + "</ul>";
    }
     $(vsworx.validator.errorContainer).hide();
    // if the error msg container "jquery selector ['.' or '#']"  is passed then that is used else the script tries to put the error messages in a div with class "messages"
    //if there are no errors the errors shown on previous validation should also be cleaned up
    if (vsworx.validator.errorContainer == "") { $(".messages").empty().append(errMsg); }
    else { $(vsworx.validator.errorContainer).show().empty().append(errMsg); }
    if( vsworx.validator.failedElements.length==0) $(vsworx.validator.errorContainer).hide();
};

/******************************************************/
/********************VALIDATORS************************/
// Email validation
vsworx.validator.email = function(element, value) {
    return (/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value));
};
// URL validation
vsworx.validator.url = function(element, value) {
    return (/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value));
};
// Domain validation
vsworx.validator.domain = function(element, value) {
    value="http://" + value;   
    return (/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value));
};
// Number length validation
vsworx.validator.number = function(element, value) {
    return (/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value));
};
// Digits length validation
vsworx.validator.digits = function(element, value) {
    return (/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value));
};
// Minimum number validation
vsworx.validator.min = function(element, value, param) {
    return value >= param;
};
// maximum number validation
vsworx.validator.max = function(element, value, param) {
    return value <= param;
};
//password validation
vsworx.validator.password = function(element, value) {
   return (/^[\w~!@#$%^&()+~?*=_-]{6,}$/.test(value));
};
// min length validation
vsworx.validator.minlength = function(element, value, param) {
    return $.trim(value).length >= param;
};
// max length validation
vsworx.validator.maxlength = function(element, value, param) {
    return $.trim(value).length <= param;
};
// Compare password validation
vsworx.validator.comparepassword = function(element, value, param) {
    return $.trim(value) == param;
};
//required validation
vsworx.validator.required = function(element, value) {
    switch (element.attr("nodeName").toLowerCase()) {
        case 'select':
            var options = $("option:selected", element);
            return options.length > 0 && (element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
        case 'input':
            if (vsworx.validator.checkable(element))
                return $.trim(value).length > 0;
        default:
            return $.trim(value).length > 0;
    }
};
/********************VALIDATORS************************/
/******************************************************/

/********************HELPERS************************/
vsworx.validator.debug = function(msg) {
    $("#debugJs").append("<br>" + msg);
};
vsworx.validator.checkable = function(element) {
    return /radio|checkbox/i.test(element.type);
};

