﻿/// <reference path="MicrosoftLibrary.js" />

Type.registerNamespace("Capitex.Validation")

/***********************************************************************************************
*	Common validator functions
***********************************************************************************************/
function isInteger(s) {
    for (var i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        if (!isDigit(c)) return false;
    }
    return true;
}

function isDigit(c) {
    return ((c >= "0") && (c <= "9"))
}

/***********************************************************************************************
*	Special validator regular expressions that are loaded on demand
***********************************************************************************************/
Capitex.Validation.getSSNRegExp = function() {
    if (Capitex.Validation.ssnRegExp == null) {
        Capitex.Validation.ssnRegExp = new RegExp();
        Capitex.Validation.ssnRegExp.compile("([0-9][0-9])?([0-9][0-9][0-9][0-9][0-9][0-9])[-+]?([0-9][0-9][0-9][0-9])");
    }
    return Capitex.Validation.ssnRegExp;
}


/***********************************************************************************************
*	Validator class
*	Handles client side validators for a component
***********************************************************************************************/
Capitex.Validation.Validator = function() {
}

Capitex.Validation.Validator.prototype.validate = function(source, args) {
    var item = this.getItem(source.attributes.id.value);
    args.IsValid = item.validate(args.Value);
}

Capitex.Validation.Validator.prototype.items = new Object();

Capitex.Validation.Validator.prototype.addItem = function(id, item) {
    this.items[id] = item;
}

Capitex.Validation.Validator.prototype.getItem = function(id) {
    return this.items[id];
}


/***********************************************************************************************
*	RequiredFieldValidatorItem class
*	A validator class that validates fields that are required
***********************************************************************************************/
Capitex.Validation.RequiredFieldValidatorItem = function(errorMessageTemplate) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
}

Capitex.Validation.RequiredFieldValidatorItem.prototype = {
    validate: function(value) {
        return value != null && value != "";
    }
}

/***********************************************************************************************
*	StringLengthValidatorItem class
*	A validator class that validates fields that need to have a specific amount
*	of characters
*	
*	Parameters
*	minLength	- The minimum length of the string
*	maxLength	- The maximum length of the string
***********************************************************************************************/
Capitex.Validation.StringLengthValidatorItem = function(errorMessageTemplate, minLength, maxLength) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
    this.minLength = minLength;
    this.maxLength = maxLength;
}

Capitex.Validation.StringLengthValidatorItem.prototype = {
    validate: function(value) {
        this.errorMessage = String.format(this.errorMessageTemplate, value, this.minLength, this.maxLength);
        return value == null || value.length == 0 || (value.length >= this.minLength && value.length <= this.maxLength);
    }
}


/***********************************************************************************************
*	RegularExpressionValidatorItem class
*	A validator that validates fields with a regular expression
*	
*	Parameters
*	pattern		- The regular expression pattern used to validate the value
*   modifiers   - Regular expression modifiers used when searching, e. g. "g", "i", "gi"
***********************************************************************************************/
Capitex.Validation.RegularExpressionValidatorItem = function(errorMessageTemplate, pattern, modifiers) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
    this.pattern = pattern;

    this.regex = new RegExp();
    this.regex.compile(pattern, modifiers);
}

Capitex.Validation.RegularExpressionValidatorItem.prototype = {
    validate: function(value) {
        this.errorMessage = String.format(this.errorMessageTemplate, value, this.pattern);
        return (value == null || value.length == 0 || this.regex.test(value));
    }
}

/***********************************************************************************************
*	RangeValidatorItem class
*	A validator that validates fields with a specific range of values
*
*	Parameters
*	minValue	- The minimum allowed value
*	maxValue	- The maximum allowed value
***********************************************************************************************/
Capitex.Validation.RangeValidatorItem = function(errorMessageTemplate, minValue, maxValue) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
    this.minValue = minValue;
    this.maxValue = maxValue;
}

Capitex.Validation.RangeValidatorItem.prototype = {
    validate : function(strValue) {
        this.errorMessage = String.format(this.errorMessageTemplate, strValue, this.minValue, this.maxValue);

        if (strValue == null || strValue.length == 0) return true;
        var value;
        try {
            value = parseInt(strValue);
        }
        catch (ex) {
            return false;
        }
        return value >= this.minValue && value <= this.maxValue;
    }
}

/***********************************************************************************************
*	SSNValidatorItem class
*	A validator that validates SSN numbers
***********************************************************************************************/
Capitex.Validation.SSNValidatorItem = function(errorMessageTemplate) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
    this.regex = Capitex.Validation.getSSNRegExp();
}

Capitex.Validation.SSNValidatorItem.prototype = {
    validate: function(value) {
        this.errorMessage = String.format(this.errorMessageTemplate, value);

        if (value == null || value.length == 0) return true;

        var result = this.regex.exec(value);
        if (result != null) {
            var ssn = result[2] + result[3];

            var checkSum = 0;
            var multiplier;
            var n;
            for (var i = 0; i < ssn.length - 1; i++) {
                multiplier = (i + 1) % 2 + 1;
                n = parseInt(ssn.charAt(i)) * multiplier;
                if (n > 9)
                    checkSum += 1 + (n % 10);
                else
                    checkSum += n;
            }
            checkSum = (10 - (checkSum % 10)) % 10;
            var controlNumber = parseInt(ssn.charAt(ssn.length - 1));
            return (controlNumber == checkSum);
        }
        else {
            return false;
        }
    }
}

/***********************************************************************************************
*	NumberValidatorItem class
*	A validator that validates numbers
***********************************************************************************************/
Capitex.Validation.NumberValidatorItem = function(errorMessageTemplate, mustBeInteger) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
    this._mustBeInteger = mustBeInteger;
}

Capitex.Validation.NumberValidatorItem.prototype = {

    validate: function(value) {
        this.errorMessage = String.format(this.errorMessageTemplate, value);

        if (value == null || value.length == 0) return true;

        var v;
        try {
            v = Number.parseLocale(value);
        }
        catch (ex) {
            return false;
        }

        var valid = !isNaN(v);

        if (!valid) {
            try {
                v = Number.parseInvariant(value);
            }
            catch (ex) {
                return false;
            }
            valid = !isNaN(v);
        }

        if (valid && this._mustBeInteger) {
            return isInteger(value);
        }
        return valid;
    }
} 

/***********************************************************************************************
*	DateValidatorItem class
*	A validator that validates dates
***********************************************************************************************/
Capitex.Validation.DateValidatorItem = function(errorMessageTemplate) {
    this.errorMessageTemplate = errorMessageTemplate;
    this.errorMessage = errorMessageTemplate;
}

Capitex.Validation.DateValidatorItem.prototype = {
    validate: function(value) {
        this.errorMessage = String.format(this.errorMessageTemplate, value);

        if (value == null || value.length == 0) return true;

        var v;
        try { v = Date.parseLocale(value); }
        catch (ex) { return false; }
        if (v != null)
            return true;

        try { v = Date.parseLocale(value, "yyyy-mm-dd hh:mm:ss"); }
        catch (ex) { return false; }
        if (v != null)
            return true;

        try { v = Date.parseInvariant(value); }
        catch (ex) { return false; }
        return v != null;
    }
}


/***********************************************************************************************
*	Generic validator methods
***********************************************************************************************/
function ValidateEmail(str) {
    var at = "@";
    var dot = ".";
    var lat = str.indexOf(at);
    var lstr = str.length;
    var ldot = str.indexOf(dot);
    var result = true;
    if (str.indexOf(at) == -1) {
        return false
    }

    if (str.indexOf(at) == -1 || str.indexOf(at) == 0 || str.indexOf(at) == lstr) {
        return false
    }

    if (str.indexOf(dot) == -1 || str.indexOf(dot) == 0 || str.indexOf(dot) == lstr) {
        return false
    }

    if (str.indexOf(at, (lat + 1)) != -1) {
        return false
    }

    if (str.substring(lat - 1, lat) == dot || str.substring(lat + 1, lat + 2) == dot) {
        return false
    }

    if (str.indexOf(dot, (lat + 2)) == -1) {
        return false
    }

    if (str.indexOf(" ") != -1) {
        return false
    }
    return true
}

function ValidateSocialSecurityNumber(str) {
    try {
        if (str != "") {
            var checkSum = 0;
            var CheckNumber = 0;
            while (str.lastIndexOf("-") != -1) {
                str = str.replace("-", "");
            }
            while (str.lastIndexOf(" ") != -1) {
                str = str.replace(" ", "");
            }
        }
        if (str.length == 10) {
            checkSum = GetCheckSum(str);
            if (checkSum > 0) {
                checkSum = parseInt(checkSum.toString().substring(1, 2));
            }
            CheckNumber = parseInt(str.substring(str.length - 1, str.length));
            if (checkSum == CheckNumber) {
                return true;
            }
            else if (CheckNumber = (10 - checkSum)) {
                return true;
            }
        }
        else if (str.length == 12) {
            str = str.substring(2, 11)
            checkSum = GetCheckSum(str);
            if (checkSum > 10) {
                checkSum = parseInt(checkSum.toString().substring(1, 2));
            }
            CheckNumber = parseInt(str.substring(str.length - 1, str.length));
            if (checkSum == CheckNumber) {
                return true;
            }
            else if (CheckNumber = (10 - checkSum)) {
                return true;
            }
        }
        else {
            return false;
        }

    }
    catch (e) {
        return false;
    }
    return false;
}

function GetCheckSum(str) {
    var checkSum = 0;
    var tempSum = 0;
    var multiply = 2;
    var aSSNumber = new Array();
    for (var i = 0; i < str.length - 1; i++) {
        aSSNumber.push(str.substring(i, (i + 1)));
    }
    try {
        for (var i = 0; i <= aSSNumber.length - 1; i++) {
            tempSum = parseInt(aSSNumber[i]);
            tempSum = tempSum * multiply;
            if (multiply == 2) {
                if (tempSum < 10) {
                    checkSum += tempSum;
                }
                else {
                    var tempSumInt;
                    for (var a = 0; a <= 1; a++) {
                        tempSumInt = parseInt(tempSum.toString().substring(a, (a + 1)));
                        checkSum = checkSum + tempSumInt;
                    }
                }
                multiply = 1;
            }
            else {
                if (tempSum < 10) {
                    checkSum += tempSum;
                }
                else {
                    var tempSumInt;
                    for (var a = 0; a <= 1; a++) {
                        tempSumInt = parseInt(tempSum.toString().substring(a, (a + 1)));
                        checkSum = checkSum + tempSumInt;
                    }
                }
                multiply = 2;
            }
        }
        return checkSum;
    }
    catch (e) {
        return 0
    }
}


function ClientValidate(source, clientside_arguments) {
    if (clientside_arguments.Value != "") {
        clientside_arguments.IsValid = true;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "hide";
    }
    else {
        clientside_arguments.IsValid = false;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputErrorlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "show";
    }
}
function ClientValidateSocialSecurityNumber(source, clientside_arguments) {
    var result = ValidateSocialSecurityNumber(clientside_arguments.Value);
    if (result) {
        clientside_arguments.IsValid = true;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "hide";
    }
    else {
        clientside_arguments.IsValid = false;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputErrorlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "show";
    }
}

function ClientValidateEmail(source, clientside_arguments) {
    var result = ValidateEmail(clientside_arguments.Value);
    if (result) {
        clientside_arguments.IsValid = true;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "hide";
    }
    else {
        clientside_arguments.IsValid = false;
        x = document.getElementById(source.controltovalidate);
        x.className = "cpxdesc_inputErrorlayout cpxdesc_tipInput";
        document.getElementById(source.validationGroup).className = "show";
    }
}

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();