/* formValidationDotNet.js */
/* Written from use with A2 Generic Controls only */
// How to call validation functions...
// validate(nStr, ElementName, ElementLabel)

// Where nStr is a string containing a number referring to the type of validation (Listed below)
// Where ElementName is the name of the form input element
// Where Label is the name used to identify the element to the user.

// Validation Codes.

// A negative validation code indicates a mandatory form element.
//    1  = GENERAL (All characters allowed)
//    2  = ALPHA-NUMERIC (Only Characters in the Charset and whitespace are permitted)
//    3  = ALPHA ONLY (Upper or lowercase)
//    4  = NUMBER (integer with commas)
//    5  = NUMBER (real with commas)
//    6_min_max = NUMBER (range between min and max)
//    7  = EMAIL (a@b.c)
//    8  = ONLY ALPHA-NUMERIC (Leters and numbers only - no whitespace or symbols)
//    9  = DATE (Any UTC date, of format: YYYY-MM-DDThh:mm:ss.sssZ, or normal date of format: DD/MM/YYYY)
//    10 = TIME (TIMES of format: HH, or,HH:MM, or, HH:MM:SS )

// Special Validation Codes.

//    50 = Compares 2 strings (Used with password when confirm = true)
//    51 = Compares a string with an array of strings. (The array must be the same name as the textbox)
//    60 = DATE-TIME (ONLY DD/MM/YYYY:HH:MM:SS, SQL uses date-times of this format but uses whitespace at subString(10,11))

// VARIABLE DECLARATIONS
var specialchars = "";
var basicpunc = ".,?£$()-!+=#@_&^~*{}[];:|\/";
var numbers = "0123456789";
var numbersonly = "0123456789";
var alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
var whitespace = " \t\n\r";
var strValidClassName = "FormItem";
var strInValidClassName = "FormItemInvalid";

// This function is designed to check, and maybe change, the format of a submitted date
// you can have a standard ISO or UTC date (YYYY-MM-DDThh:mm:ss.sssZ), or all the possible permutations
// of a character from 'basicPunc' as the delimiter, with the date in british format.
function isDate(date) {
    var allValid;
    var delimitType = "";
    var dArr = new Array();
    if ((date.length == 25) && (date.substring(24, 25) == "Z") && (date.substring(10, 11) == "T")) {
        allValid = true;
    } else if ((date.length == 9) || (date.length == 10) || (date.length == 8)) {
        for (var aa = 0; aa < basicpunc.length; aa++) {
            var ab = (aa + 1);
            if (date.indexOf(basicpunc.substring(aa, ab)) != Number(-1)) {
                delimitType = basicpunc.substring(aa, ab);
            }
        }
        if (delimitType != "") {
            dArr = date.split(delimitType);
            if ((Number(dArr[0]) <= 31) && (Number(dArr[1]) <= 12) && (Number(dArr[2]) <= 9999) && (Number(dArr[0]) > 0) && (Number(dArr[1]) > 0) && (Number(dArr[2] > 0))) {
                allValid = true;
            } else {
                allValid = false;
            }
        } else {
            allValid = false;
        }
    }
    return allValid;
}
// Times can be passed as HH, HH:MM, or HH:MM:SS, the delimiter MUST be a colon.
function isTime(time) {
    if (time.indexOf(":") != Number(-1)) {
        var allValid = false;
        if ((time.length == 2) && (isFinite(Number(time.subString(0, 2)))) && ((Number(time.subString(0, 2))) < 24) && ((Number(time.subString(0, 2))) >= 0)) {
            allValid = true;
        } else if ((time.length == 5) && (isFinite(Number(time.subString(0, 2)))) && (isFinite(Number(time.subString(3, 5)))) && ((Number(time.subString(0, 2))) < 24) && ((Number(time.subString(0, 2))) >= 0) && ((Number(time.subString(3, 5))) < 60) && ((Number(time.subString(3, 5))) >= 0)) {
            allValid = true;
        } else if ((time.length == 8) && (isFinite(Number(time.subString(0, 2)))) && (isFinite(Number(time.subString(3, 5)))) && (isFinite(Number(time.subString(6, 8)))) && ((Number(time.subString(0, 2))) < 24) && ((Number(time.subString(0, 2))) >= 0) && ((Number(time.subString(3, 5))) < 60) && ((Number(time.subString(3, 5))) >= 0) && ((Number(time.subString(6, 8))) < 60) && ((Number(time.subString(6, 8))) >= 0)) {
            allValid = true;
        }
    }
    return allValid;
}
// Abuses the isDate and isTime functions because SQL server doesn't use any 'standard' delimiters
// to split the date from the time.  It's lovely really.
function isDateTime(dateTime) {
    var allValid = false;
    if (dateTime.length == 19) {
        var strDate = dateTime.subSting(0, 10);
        var strTime = dateTime.subString(11, 19);
        if ((isDate(strDate)) && (isTime(strTime))) {
            allValid = true;
        }
    }
    return allValid;
}
// isEmpty returns true if TestString is not empty or whitespace.
function isEmpty(TestString) {
    if ((TestString == null) || (TestString.length == 0)) return true
    else {
        for (i = 0; i < TestString.length; i++) {
            // Check that current character isn't whitespace.
            var c = TestString.charAt(i);
            if (whitespace.indexOf(c) == -1) return false;
        }
    }
    return true;
}
// fullOf returns true if every character is 'car'
function fullOf(TestString, car) {
    for (i = 0; i < TestString.length; i++)
        if (TestString.charAt(i) != car)
        return false;
    return true;
}
// isValid returns true if all characters in TestString are also in ValidChars
function isValid(TestString, ValidChars) {
    for (i = 0; i < TestString.length; i++) {
        var c = TestString.charAt(i);
        if (ValidChars.indexOf(c) == -1) return false;
    }
    return true;
}
// isValid returns true if all characters in TestString are also in ValidChars
function isValidDomain(TestString, ValidChars) {
    var blnHasFullStop = false;

    for (i = 0; i < TestString.length; i++) {
        var c = TestString.charAt(i);
        if (ValidChars.indexOf(c) == -1) return false;
        if (c == ".") blnHasFullStop = true;
    }

    return blnHasFullStop;
}

function isInRange(testValue, minValue, maxValue) {
    if (testValue == NaN) return false;
    if ((testValue >= minValue) && (testValue <= maxValue)) return true;
    else return false;
}
function isEmail(TestString) {
    i = 1;
    StringLength = TestString.length;
    while ((i < StringLength) && (TestString.charAt(i) != "@")) { i++ }
    if ((i >= StringLength) || (TestString.charAt(i) != "@")) return false;
    else i += 2;
    while ((i < StringLength) && (TestString.charAt(i) != ".")) { i++ }
    if ((i >= StringLength - 1) || (TestString.charAt(i) != ".")) return false;
    else return true;
}
// This function is used to show 'non-mandatory' validation errors
function displaySubErrorMsg() {
    // alert(SubErrorMsg)
    ProblemField = document.forms[0].elements[SubErrorMsg[0]]
    ProblemField.className = strInValidClassName
    if (ProblemField.type != "hidden") {
        ProblemField.select();
        ProblemField.focus();
    }
    //alert("The value in \"" + SubErrorMsg[1] + "\" field is invalid because\n" + SubErrorMsg[2]);
    fcnShowPopupBySize2('ifPopup', 330, 150, '/Public/Alert.aspx?PopupName=ifPopup&Msg=The value in \'' + SubErrorMsg[1] + '\' field is invalid because[br]' + SubErrorMsg[2]);
}
// ----------------------------------------- VALIDATE STARTS HERE -----------------
function validate(CodeInput, ElementName, ElementLabel) {
    /*alert('validate');
    alert('CodeInput = ' + CodeInput)
    alert('ElementName = ' + ElementName)
    alert('Elementlabel = ' + Elementlabel)*/
    
    CodeNumber = parseInt(CodeInput);
    InputField = document.forms[0].elements[ElementName];
    if (InputField.tagName == "TEXTAREA") InputField.className = strValidClassName + " PSelectScroll";
    else InputField.className = strValidClassName
    if (isNaN(CodeNumber)) {
        alert("formValidation Error:\n\"" + CodeInput + "\" is not a valid code number");
        return false;
    }
    // ------------- This bit checks all required fields are completed --------------------------
    if (CodeNumber < 0) {
        CodeNumber = Math.abs(CodeNumber)
        if (isEmpty(InputField.value)) {
            ErrorMsg = "Please fill in all required fields.";
            InputField.className = strInValidClassName
            return false;
        }
    }
    // ------------- This bit checks that inputs are correct to their validation type ----------
    if ((!isEmpty(InputField.value)) && (ErrorMsg == "") && (SubErrorMsg[2] == "")) {
        switch (CodeNumber) {
            case 0:
                break;
            case 1:
                break;
            case 2: if (!isValid(InputField.value, alpha + numbers + whitespace + basicpunc)) SubErrorMsg[2] = "this field cannot contain special characters.";
                break;
            case 3: if (!isValid(InputField.value, alpha)) SubErrorMsg[2] = "this field can only contain alphabetical characters.";
                break;
            case 4: if (!isValid(InputField.value, numbers + ",") || fullOf(InputField.value, ",")) SubErrorMsg[2] = "this field must be an integer.";
                break;
            case 5: if (!isValid(InputField.value, numbers + ",.-") || !(InputField.value.indexOf(".") == InputField.value.lastIndexOf(".")) || fullOf(InputField.value, ",")) SubErrorMsg[2] = "this field must be a number.";
                break;
            case 6: CodeInput = CodeInput.split("_");
                minValue = parseFloat(CodeInput[1]);
                maxValue = parseFloat(CodeInput[2]);
                if (!isInRange(parseFloat(InputField.value), minValue, maxValue)) SubErrorMsg[2] = "this field must be a number between " + minValue + " and " + maxValue + ".";
                break;
            case 7: if (!isEmail(InputField.value)) SubErrorMsg[2] = "this field must be a valid e-mail address."
                break;
            case 8: if (!isValid(InputField.value, alpha + numbers)) SubErrorMsg[2] = "this field must not contain whitespace or symbols.";
                break;
            case 9: if (!isDate(InputField.value)) SubErrorMsg[2] = "this field must be a valid date, ie: 02/04/1983.";
                break;
            case 10: if (!isDate(InputField.value)) SubErrorMsg[2] = "this field must be a valid 24 hour time, ie: 17:30:00.";
                break;
            case 11: if (!isValid(InputField.value, numbersonly)) SubErrorMsg[2] = "this field must contain numbers only. (no spaces!)";
                break;
            case 12: if (!isValid(InputField.value, alpha + whitespace)) SubErrorMsg[2] = "this field can only contain alphabetical characters.";
                break;
            case 13: if (!isValid(InputField.value, alpha + SpecialNameCharacters + whitespace)) SubErrorMsg[2] = "this field can only contain characters used within a name.";
                break;
            case 14: if (!isPcodeNum(InputField.value, numbersonly)) SubErrorMsg[2] = "this field must contain 5 numreic characters only.";
                break;
            case 15: if (!isZipCode(InputField.value, numbersonly)) SubErrorMsg[2] = "this field must contain either 5 numeric characters only\nor 5 numeric, a hyphen and 4 numeric characters.";
                break;
            case 16: if (!isValid(InputField.value, numbersonly + ".")) SubErrorMsg[2] = "this field must contain a currency value only.";
                break;
            case 17: if (!isValidDomain(InputField.value, alpha + numbers + ".")) SubErrorMsg[2] = "this field must be a valid domain name.";
                break;

            case 50: if (InputField.value != document.forms[0].elements["Confirm" + ElementName].value) {
                    SubErrorMsg[2] = "this field and Confirm " + ElementLabel + " are not the same value.";
                    document.forms[0].elements["Confirm" + ElementName].className = strInValidClassName;
                }
                break;
            case 51: CheckArray = eval(ElementName);
                for (GFcount = 0; GFcount < CheckArray.length; GFcount++) {
                    if (InputField.value.toLowerCase() == CheckArray[GFcount].toLowerCase()) {
                        SubErrorMsg[2] = InputField.value + " already exists in the database.";
                        break;
                    }
                }
                break;
            case 60: if (!isDateTime(InputField.value)) SubErrorMsg[2] = "this field must be a valid date-time\nie: 02/04/1983:17:30:00.";
                break;
        }

        if (SubErrorMsg[2] != "") {
            SubErrorMsg[0] = ElementName;
            SubErrorMsg[1] = ElementLabel;
        }
    }
    else return false;
}
//-------------In case needing to validate with a different form number------------
//----------------------------- VALIDATE STARTS HERE ------------------------------
function validateform(CodeInput, ElementName, ElementLabel, formno) {
    CodeNumber = parseInt(CodeInput);
    InputField = document.forms[formno].elements[ElementName];
    if (InputField.tagName == "TEXTAREA") InputField.className = "FormItem PSelectScroll";
    else InputField.className = strValidClassName;
    if (isNaN(CodeNumber)) {
        alert("formValidation Error:\n\"" + CodeInput + "\" is not a valid code number");
        return false;
    }
    // ------------- This bit checks all required fields are completed --------------------------
    if (CodeNumber < 0) {
        CodeNumber = Math.abs(CodeNumber)
        if (isEmpty(InputField.value)) {
            ErrorMsg = "Please fill in all required fields.";
            InputField.className = strInValidClassName;
            return false;
        }
    }
    // ------------- This bit checks that inputs are correct to their validation type ----------
    if ((!isEmpty(InputField.value)) && (ErrorMsg == "") && (SubErrorMsg[2] == "")) {
        switch (CodeNumber) {
            case 0:
                break;
            case 1:
                break;
            case 2: if (!isValid(InputField.value, alpha + numbers + whitespace + basicpunc)) SubErrorMsg[2] = "this field cannot contain special characters.";
                break;
            case 3: if (!isValid(InputField.value, alpha)) SubErrorMsg[2] = "this field can only contain alphabetical characters.";
                break;
            case 4: if (!isValid(InputField.value, numbers + ",") || fullOf(InputField.value, ",")) SubErrorMsg[2] = "this field must be an integer.";
                break;
            case 5: if (!isValid(InputField.value, numbers + ",.-") || !(InputField.value.indexOf(".") == InputField.value.lastIndexOf(".")) || fullOf(InputField.value, ",")) SubErrorMsg[2] = "this field must be a number.";
                break;
            case 6: CodeInput = CodeInput.split("_");
                minValue = parseFloat(CodeInput[1]);
                maxValue = parseFloat(CodeInput[2]);
                if (!isInRange(parseFloat(InputField.value), minValue, maxValue)) SubErrorMsg[2] = "this field must be a number between " + minValue + " and " + maxValue + ".";
                break;
            case 7: if (!isEmail(InputField.value)) SubErrorMsg[2] = "this field must be a valid e-mail address."
                break;
            case 8: if (!isValid(InputField.value, alpha + numbers)) SubErrorMsg[2] = "this field must not contain whitespace or symbols.";
                break;
            case 9: if (!isDate(InputField.value)) SubErrorMsg[2] = "this field must be a valid date, ie: 02/04/1983.";
                break;
            case 10: if (!isDate(InputField.value)) SubErrorMsg[2] = "this field must be a valid 24 hour time, ie: 17:30:00.";
                break;
            case 50: if (InputField.value != document.forms[0].elements["Confirm" + ElementName].value) {
                    SubErrorMsg[2] = "this field and Confirm " + ElementLabel + " are not the same value.";
                    document.forms[0].elements["Confirm" + ElementName].className = strInValidClassName;
                }
                break;
            case 51: CheckArray = eval(ElementName);
                for (GFcount = 0; GFcount < CheckArray.length; GFcount++) {
                    if (InputField.value.toLowerCase() == CheckArray[GFcount].toLowerCase()) {
                        SubErrorMsg[2] = InputField.value + " already exists in the database.";
                        break;
                    }
                }
                break;
            case 60: if (!isDateTime(InputField.value)) SubErrorMsg[2] = "this field must be a valid date-time\nie: 02/04/1983:17:30:00.";
                break;
        }
        if (SubErrorMsg[2] != "") {
            SubErrorMsg[0] = ElementName;
            SubErrorMsg[1] = ElementLabel;
        }
    }
    else return false;
}
//--------------------------
function isFormValid() {
    //alert(ErrorMsg);
    //alert(SubErrorMsg[0]);

    if ((ErrorMsg == "") && (SubErrorMsg[0] == "")) return true;
    else {
        if (ErrorMsg == "") displaySubErrorMsg();
        else fcnShowPopupBySize2('ifPopup', 330, 150, '/Public/Alert.aspx?PopupName=ifPopup&Msg=' + ErrorMsg);
        return false;
    }
}