﻿/// <module>
///     validation.js
/// </module>
/// <summary>
///     Javascript validation for the E-License web application.
/// </summary>
/// <copyright>
///     Copyright © 2011.  Michigan Department of Natural Resources.
///     All Rights Reserved.
///
///     The contents of this file are subject to the Michigan RSS License
///     (the 'License'); you may not use this file except in compliance
///     with the License.
///
///     THE SOFTWARE IS PROVIDED 'AS-IS' AND WITHOUT WARRANTY OF ANY KIND,
///     EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
///     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
///
///     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING
///     NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY OTHER
///     CONTRIBUTOR, OR ANY DEVELOPER OF COVERED CODE, OR ANY SUPPLIER OF ANY OF
///     SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT,
///     SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
///     WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
///     FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES,
///     EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH
///     DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH
///     OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT
///     APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW
///     THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
///     THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
///     Call Hewlett-Packard Development Company for more information.
///
///     Notices of copyright and/or attribution that appear at the beginning
///     of any file included in this distribution must remain intact.
///
///     See the License for the specific language governing rights and limitations
///     under the License.
/// </copyright>
/// <history>
///     <change date="10/18/2010" author="James Kircoff, MaoShen Taur, Paul Olszewski" release="1">
///         First revision.
///     </change>
///     <change date="11/08/2010" author="MaoShen Taur" release="1">
///         Added functions validate_customer_identification and validate_customer
///     </change>
///     <change date="11/27/2010" author="MaoShen Taur" release="1">
///         Updated validate_customer_identification function per WPR comments.
///     </change>
///     <change date="11/27/2010" author="MaoShen Taur" release="1">
///         Added the validate_checkpointsorchances_form function.
///     </change>
///     <change date="11/27/2010" author="MaoShen Taur" release="1">
///         Added the validate_disputepointsorchances_form function.
///     </change>
///     <change date="11/29/2010" author="MaoShen Taur" release="1">
///         Added validation functions for the Checkout screen.
///     </change>
///     <change date="12/08/2010" author="MaoShen Taur" release="1">
///         Added validation function for the EnterCustomerForReprint screen.
///     </change>
///     <change date="12/08/2010" author="MaoShen Taur" release="1">
///         Added validation function for the ReprintLicenseTransList screen.
///     </change>
///     <change date="12/15/2010" author="Greg Flynn" release="1  CC 31">
///         Updated radio button name.
///     </change>
///     <change date="01/11/2011" author="Greg Flynn" release="1  CC 998 CR 70713">
///         Updated "DNRE /SPORTCARD" to "DNRE/SPORTCARD".
///     </change>
///     <change date="01/13/2011" author="MaoShen Taur" release="1 CR 70761">
///         Updated function validate_customer_address to check if city name is alphabetic data.
///     </change>
///     <change date="01/21/2011" author="MaoShen Taur" release="1 CR 70948">
///         Added first character of Legacy ID and Last Name validation for Checkout.
///     </change>
///     <change date="01/21/2011" author="MaoShen Taur" release="1 CR 70980">
///         Added future transaction date validation for Customer Reprint.
///     </change>
///     <change date="01/21/2011" author="Greg Flynn" release="1  CC 998 CR 70885">
///         Fixed Luhn check for hunt party and fixed hunt party/hunt area check.
///     </change>
///     <change date="01/22/2011" author="James Kircoff" release="1 CR 70995">
///         Updated validate_disputepointsorchances_form to look at element IDs instead of names, as the name lookup
///         was failing.
///     </change>
///     <change date="01/24/2011" author="James Kircoff" release="1 CR 71028">
///         Added code to validate_checkout_form to check for null value in the customerID variable.
///     </change>
///     <change date="01/24/2011" author="Greg Flynn" release="1  CC 998 CR 71033">
///         Added new error validation to display which character(s) is wrong within Additional Questions.
///     </change>
///     <change date="01/25/2011" author="James Kircoff" release="1 CR 71085">
///         Modified validate_customer_address to require 5 digit ZIP codes for the USA and 7 digit ZIP codes for Canada.
///     </change>
///     <change date="01/26/2011" author="Paul Olszewski" release="1 CC998 CR71113">
///         Added effective date validation to notify customer when effective date is null.
///     </change>
///     <change date="01/26/2011" author="James Kircoff" release="1 CR 71133">
///         Modified validate_disputepointsorchances_form to validate preference points correctly.
///     </change>
///     <change date="01/27/2011" author="MaoShen Taur" release="1 CC998 CR 71086">
///         Added validation for 6th and 7th digits of the Sportcard ID and and updated error message for
///         birthdate more than 150 years and bad email address.
///     </change>
///     <change date="01/28/2011" author="Greg Flynn" release="1  CC998">
///         CR 71141 - Added a for loop in hunt area to verify no blank selections between hunt area.
///         CR 71122 - Updated validate_checkout_form to correctly get last name letter, and then browser issues.
///         CR 71197 - Move gift certificate getElementsByName logic into the if statement where it is
///                    guaranteed that the element exists.
///     </change>
///     <change date="01/29/2011" author="James Kircoff" release="1 CR 71219">
///         Modified validate_customer to perform numeric checks on "DNRE Sportcard OR DNRE ID" properly.
///     </change>
///     <change date="01/29/2011" author="James Kircoff" release="1 CR 71137">
///         Modified validate_customer_information return message that specify which fields need correction.
///     </change>
///     <change date="02/03/2011" author="James Kircoff" release="1 CR 71137">
///         Modified validate_customer_information return messages further to specify which fields need correction.
///     </change>
///     <change date="02/08/2011" author="MaoShen Taur" release="1 CR 71077">
///         Modified validate_disputepointsorchances_form to only validate the fields on the page when the
///         "Submit Request" button is clicked.
///     </change>
///     <change date="02/08/2011" author="Greg Flynn" release="1  CC 998">
///         CR 71345 - Added 'must' to City Alpha message.
///         CR 71350 - Added focus to fields in error.
///         CR 71373 - Added dteEffectiveDate declaration for style sheets error.
///         CR 71384 - Added client error message for last name/11 char MI ID mismatch.  Updated regexAlpha
///                    to search entire string.  Fixed weight validation.
///     </change>
///     <change date="04/07/2011" author="Mike Terranova" release="11.2 CR 72033">
///         Updated "DNRE" in displayed text to "DNR".
///     </change>
///     <change date="04/18/2011" author="Greg Flynn" release="11.2 CRs 72036/72037">
///         Fixed alphabetic-only text checks to disregard special characters for First, Middle, and Last Name, Suffix
///         and City.  Updated gift certificate validation for new panel.
///     </change>
///     <change date="04/28/2011" author="Mike Terranova" release="11.2 CR 72033">
///         Updated department/state name to read from resources provided by Site.master
///     </change>
///     <change date="05/10/2011" author="Greg Flynn" release="11.2">
///         Updated the focus event for btnClearChoice.
///     </change>
/// </history>

//10/19/10 JK - Provides client-side validation for the Welcome screen.
function validate_form(thisform) {
    with (thisform) {
        var radioButtons = document.getElementsByName("ctl00$MainContent$ASPxRoundPanel1$rboCertify");
        var checked = false;
        for (var x = 0; x < radioButtons.length; x++) {
            if (radioButtons[x].checked) {
                checked = true;
                break;
            }
        }

        if (checked == false) {
            alert("Please select the person for whom you are certifying.");
            document.getElementById("ctl00_MainContent_ASPxRoundPanel1_rboCertify_0").focus();
        }

        return checked;
    }
}

//11/08/10 MST - Provides client-side validation for the CustomerIdentification screen.
function validate_customer_identification(thisform, usercontrolname) {
    with (thisform) {
        var residency = document.getElementsByName("ctl00$MainContent$roundPanelCustomerIdentification$rdoResidency")[0].value;
        var disability = document.getElementsByName("ctl00$MainContent$roundPanelCustomerIdentification$rdoDisability")[0].value;
        var dateOfBirthPanel = "ctl00$MainContent$roundPanelCustomerIdentification$";

        if (residency == -1) {
            alert("Please respond to the RESIDENCY question.");
            document.getElementById("ctl00_MainContent_roundPanelCustomerIdentification_rdoResidency_RB0_I").focus();
            return false;
        }

        if (disability == -1) {
            alert("Please respond to the DISABILITY question.");
            document.getElementById("ctl00_MainContent_roundPanelCustomerIdentification_rdoDisability_RB0_I").focus();
            return false;
        }

        if (validate_date_of_birth(thisform, dateOfBirthPanel) == false) {
            return false;
        }

        // Check the inputs in the user control
        if (document.activeElement.title == "Validate ID") {
            if (validate_customer(thisform, usercontrolname) == false) {
                return false;
            }
        }

        var sportcardDNRE = document.getElementsByName(usercontrolname + "txtSportcardDNRE")[0];
        var driverLicenseMichiganID = document.getElementsByName(usercontrolname + "txtDriverLicenseMichiganID")[0];
        var michiganID = document.getElementsByName(usercontrolname + "txtMichiganID")[0];
        var rescode = sportcardDNRE.value.charAt(6); // 7th character: 0 = A, M, or S, 1 = N

        var departmentName = document.getElementById("DepartmentResource").value;
        var stateAbbr = document.getElementById("StateAbbrResource").value;

        // 12/13/10 MST - residency is the index number of the radio buttons: 0 = A, 1 = M, 2 = S, and 3 = N
        // Customer's Sportcard or DNR ID does not match the selected residency information if
        // rescode = 0 and residency > 2 (or N) OR
        // rescode = 1 and residency < 3 (or A, M, S)
        if (((rescode == "0") && (residency > 2)) || ((rescode == "1") && (residency < 3))) {
            alert("Your residency information is not consistent with the " + departmentName + " ID that you have entered. Please change your residency selection or order a new ID.");
            document.getElementById("ctl00_MainContent_roundPanelCustomerIdentification_rdoResidency_RB0_I").focus();
            return false;
        }

        if ((document.activeElement.title == "Buy Sportcard") && (sportcardDNRE.value + driverLicenseMichiganID.value + michiganID.value != "")) {
            alert("You cannot choose to Purchase a " + departmentName + " Sportcard if you have entered a " + departmentName + " Sportcard, " + departmentName + " ID, " + stateAbbr + " Driver License, 13 Character State of " + stateAbbr + " ID, or 11 Character State of " + stateAbbr + " ID.  Please clear this information.");

            // Determine which field is in error.  If there are multiple, just focus on the first only.
            if (sportcardDNRE.value != "") {
                sportcardDNRE.focus();
            }
            else if (driverLicenseMichiganID.value != "") {
                driverLicenseMichiganID.focus();
            }
            else {
                michiganID.focus();
            }

            return false;
        }

        if ((document.activeElement.title == "Obtain " + departmentName + " ID Card") && (sportcardDNRE.value + driverLicenseMichiganID.value + michiganID.value != "")) {
            alert("You cannot choose to Obtain a " + departmentName + " ID if you have entered a " + departmentName + " Sportcard, " + departmentName + " ID, " + stateAbbr + " Driver License, 13 Character State of " + stateAbbr + " ID, or 11 Character State of " + stateAbbr + " ID.  Please clear this information.");

            // Determine which field is in error.  If there are multiple, just focus on the first only.
            if (sportcardDNRE.value != "") {
                sportcardDNRE.focus();
            }
            else if (driverLicenseMichiganID.value != "") {
                driverLicenseMichiganID.focus();
            }
            else {
                michiganID.focus();
            }
            return false;
        }
    }
}

//11/08/10 MST - Provides client-side validation for the CustomerID user control.
function validate_customer(thisform, usercontrolname) {
    with (thisform) {
        var sportcardDNRE = document.getElementsByName(usercontrolname + "txtSportcardDNRE")[0];
        var driverLicenseMichiganID = document.getElementsByName(usercontrolname + "txtDriverLicenseMichiganID")[0];
        var michiganID = document.getElementsByName(usercontrolname + "txtMichiganID")[0];

        var idcount = 0;
        var firstCharacter = "";
        var lastCharacters = "";
        var regex1Alpha = /[a-zA-Z]/;

        if (sportcardDNRE.value != "") {
            idcount++;
        }

        if (driverLicenseMichiganID.value != "") {
            idcount++;
        }

        if (michiganID.value != "") {
            idcount++;
        }

        if (idcount == 0) {
            alert("Please enter the appropriate Identification number");
            sportcardDNRE.focus();
            return false;
        }

        // If more than one ID is entered, just focus on the first entered field.
        if (idcount > 1) {
            alert("Please enter only one Identification number");
            if (sportcardDNRE.value != "") {
                sportcardDNRE.focus();
            }
            else {
                driverLicenseMichiganID.focus();
            }

            return false;
        }

        var departmentName = document.getElementById("DepartmentResource").value;

        // Sportcard or DNR ID Validation
        if (sportcardDNRE.value.length > 0) {
            if (sportcardDNRE.value.length < 16) {
                alert("Your " + departmentName + "/SPORTCARD ID is INVALID.  Please re-enter your number.");
                sportcardDNRE.focus();
                return false;
            }

            var regexNumeric = /^\d+$/;
            if (sportcardDNRE.value.search(regexNumeric) == -1) {
                alert("Please enter NUMERIC data only for the " + departmentName + "/SPORTCARD ID.");
                sportcardDNRE.focus();
                return false;
            }

            // Validate the 6th and 7th digit of Sportcard or DNR ID
            var regex01Digit = /[0-1][0-1]/;
            if (sportcardDNRE.value.substring(5, 7).search(regex01Digit) == -1) {
                alert("Your " + departmentName + "/SPORTCARD ID is INVALID.  Please re-enter your number.");
                sportcardDNRE.focus();
                return false;
            }

            // Validate the Sportcard or DNR ID against the Luhn Algorithm
            // PO 12/11/10 - moved to separate function call for reuse with hunt party id
            if (!check_luhn(sportcardDNRE.value.substring(0, sportcardDNRE.value.length - 1), sportcardDNRE.value.substring(sportcardDNRE.value.length - 1, sportcardDNRE.value.length))) {
                alert("Your " + departmentName + "/SPORTCARD ID is INVALID.  Please re-enter your number.");
                sportcardDNRE.focus();
                return false;
            }
        }

        var stateAbbr = document.getElementById("StateAbbrResource").value;
        
        // Driver License or 13 Character MI ID Validation
        if (driverLicenseMichiganID.value.length > 0) {
            var regex12Digit = /[0-9]{12}/;

            firstCharacter = driverLicenseMichiganID.value.substring(0, 1);
            lastCharacters = driverLicenseMichiganID.value.substring(1, driverLicenseMichiganID.value.length);

            if ((driverLicenseMichiganID.value.length < 13) || (firstCharacter.search(regex1Alpha) == -1) || (lastCharacters.search(regex12Digit) == -1)) {
                alert("Your " + stateAbbr + " DRIVER LICENSE or 13 Character State of " + stateAbbr + " ID number is INVALID. Please re-enter your number.");
                driverLicenseMichiganID.focus();
                return false;
            }
        }

        // 11 Character MI ID Validation
        if (michiganID.value.length > 0) {
            var regex10Digit = /[0-9]{10}/;

            firstCharacter = michiganID.value.substring(0, 1);
            lastCharacters = michiganID.value.substring(1, michiganID.value.length);

            if ((michiganID.value.length < 11) || (firstCharacter.search(regex1Alpha) == -1) || (lastCharacters.search(regex10Digit) == -1)) {
                alert("Your 11 Character State of " + stateAbbr + " ID number is INVALID. Please re-enter your number.");
                michiganID.focus();
                return false;
            }
        }
    }
}

//11/27/10 MST - Provides client-side validation for the Customer's date of birth.
//12/13/10 MT - Updated the element names for ddlMonth, ddlDay, and txtYear to include the user control name.
function validate_date_of_birth(thisform, panel) {
    with (thisform) {
        var birthMonth = document.getElementsByName(panel + "userControlDateOfBirth$ddlMonth")[0];
        var birthDay = document.getElementsByName(panel + "userControlDateOfBirth$ddlDay")[0];
        var birthYear = document.getElementsByName(panel + "userControlDateOfBirth$txtYear")[0];

        if (birthMonth.value == "") {
            alert("Please select the MONTH for your Date of Birth.");
            birthMonth.focus();
            return false;
        }

        if (birthDay.value == "") {
            alert("Please select the DAY for your Date of Birth.");
            birthDay.focus();
            return false;
        }

        if (birthYear.value == "") {
            alert("Please enter the YEAR for your Date of Birth.");
            birthYear.focus();
            return false;
        }

        if (birthYear.value.length > 0) {
            if (birthYear.length < 4) {
                alert("Please enter a 4 DIGIT YEAR for Date of Birth.");
                birthYear.focus();
                return false;
            }

            var regex4Digit = /[0-9]{4}/;
            if (birthYear.value.search(regex4Digit) == -1) {
                alert("Please enter a 4 DIGIT YEAR for Date of Birth.");
                birthYear.focus();
                return false;
            }
        }

        // Check if the date of birth entered by the customer is valid
        var birthDate = new Date(birthMonth.value + '/' + birthDay.value + '/' + birthYear.value);
        var currentDate = new Date();

        if (birthDate.getDate() != parseFloat(birthDay.value)) {
            alert("You have entered an INVALID Date of Birth.");
            birthDay.focus();
            return false;
        }

        if (birthDate.getMonth() != (parseFloat(birthMonth.value) - 1)) {  // Month starts from 0 in Javascript
            alert("You have entered an INVALID Date of Birth.");
            birthMonth.focus();
            return false;
        }

        if ((birthDate.getFullYear() != parseFloat(birthYear.value)) ||
            (currentDate.getFullYear() - birthDate.getFullYear() > 150)) {
            alert("You have entered an INVALID Date of Birth.");
            birthYear.focus();
            return false;
        }

        if (birthDate > new Date()) {
            alert("You have entered a birth date in the future. Please re-enter.");
            birthYear.focus();
            return false;
        }
    }
}

//11/27/10 MST - Provides client-side validation for the CheckBearPreferencePointsOrElkChances screen.
function validate_checkpointsorchances_form(thisform, usercontrolname) {
    with (thisform) {
        if (document.activeElement.title == "Submit Request") {
            // Check the inputs in the user control
            if (validate_customer(thisform, usercontrolname) == false) {
                return false;
            }

            var dateOfBirthPanel = "ctl00$MainContent$roundPanelCustomerIdentification$";

            if (validate_date_of_birth(thisform, dateOfBirthPanel) == false) {
                return false;
            }
        }
    }
}

//11/27/10 MST - Provides client-side validation for the DisputeBearPreferencePointsOrElkChances screen.
function validate_disputepointsorchances_form(thisform) {
    with (thisform) {
        if (document.activeElement.title == "Submit Request") {
            var hunttype = document.getElementById("ctl00_MainContent_hiddenHuntType").value;
            var points = document.getElementById("ctl00_MainContent_panPointOrChanceInformation_txtPointsOrChances_I");
            var email = document.getElementById("ctl00_MainContent_panPointOrChanceInformation_txtEmail_I");

            if (points.value == "") {
                if (hunttype == 'B') {
                    alert("Please enter the required preference point information.");
                }
                else {
                    alert("Please enter the required Elk Chance information.");
                }
                points.focus();
                return false;
            }

            var regexNumeric = /^\d+$/;

            if (points.value.search(regexNumeric) == -1) {
                alert("Please enter NUMERIC data only.");
                points.focus();
                return false;
            }

            if ((hunttype == 'B') && (points.value > 15)) {
                alert("The NUMBER OF PREFERENCE POINTS cannot be greater than 15.");
                points.focus()
                return false;
            }

            if (email.value == "") {
                alert("Please enter your E-MAIL ADDRESS.");
                email.focus();
                return false;
            }

            var regexemail = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
            if (email.value.search(regexemail) == -1) {
                alert("Please enter a valid E-MAIL ADDRESS.");
                email.focus();
                return false;
            }
        }
    }
}

//11/29/10 MST - Provides client-side validation for the Checkout screen.
function validate_checkout_form(thisform, panel1, panel2) {
    with (thisform) {
        var customerID = document.getElementById("ctl00_MainContent_divCustomerID");
        var last_name = document.getElementsByName(panel1 + "userControlCustomerInformation$txtLastName")[0];

        if (document.activeElement.title == "Apply Gift Certificate") {
            if (document.getElementsByName("ctl00$MainContent$panAddGiftCertificate$txtGiftCertificate")[0].value == "") {
                alert("Please enter a Gift Certificate.");
                document.getElementsByName("ctl00$MainContent$panAddGiftCertificate$txtGiftCertificate")[0].focus();
                return false;
            }
        }
        else if (document.activeElement.title == "Submit Order") {
            if (validate_customer_information(thisform, panel1, true) == false) {
                return false;
            }

            if (validate_customer_address(thisform, panel2) == false) {
                return false;
            }

            if (customerID != null) {
                var customerValueHolder;

                // Different browsers have a different data field.
                if (customerID.innerText != undefined) {
                    customerValueHolder = customerID.innerText;
                }
                else {
                    customerValueHolder = customerID.textContent;
                }

                if (customerValueHolder.length == 29) {
                    if (customerValueHolder.charAt(13) != last_name.value.charAt(0).toUpperCase()) {
                        var stateAbbr = document.getElementById("StateAbbrResource").value;
                        alert("The first character of your 11 character " + stateAbbr + " ID does not match the first character of your last name.  "
                          + "Please verify the spelling of your last name.  If your last name has changed since you obtained your "
                          + "11 character " + stateAbbr + " ID, you must use your old name or obtain a new ID number before proceeding with this order.");
                        last_name.focus();
                        return false;
                    }
                }
            }

            var response = confirm("By clicking on the OK button below you are confirming your order. If you are sure click on the OK button. If not, click on the Cancel button.");

            if (!response) {
                return false;
            }
        }
    }
}

//11/29/10 MST - Provides client-side validation for the CustomerInformation user control.
function validate_customer_information(thisform, panel, checkPhone) {
    with (thisform) {
        var first_name = document.getElementsByName(panel + "userControlCustomerInformation$txtFirstName")[0];
        var middle_name = document.getElementsByName(panel + "userControlCustomerInformation$txtMiddleName")[0];
        var last_name = document.getElementsByName(panel + "userControlCustomerInformation$txtLastName")[0];
        var name_suffix = document.getElementsByName(panel + "userControlCustomerInformation$txtNameSuffix")[0];
        var height_feet = document.getElementsByName(panel + "userControlCustomerInformation$ddlHeightInFeet")[0];
        var height_inches = document.getElementsByName(panel + "userControlCustomerInformation$ddlHeightInInches")[0];
        var weight = document.getElementsByName(panel + "userControlCustomerInformation$txtWeight")[0];
        var gender = document.getElementsByName(panel + "userControlCustomerInformation$rdoGender")[0].value;
        var email = document.getElementsByName(panel + "userControlCustomerInformation$txtEmail")[0];

        var regexNumeric = /^\d+$/;
        var regex3Digit = /[0-9]{3}/;
        var regex4Digit = /[0-9]{4}/;
        var regexAlpha = /^[a-zA-Z ."\'"-]*$/;
        var regexemail = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

        if (first_name.value == "") {
            alert("Please enter your FIRST NAME.");
            first_name.focus();
            return false;
        }

        if (first_name.value.search(regexAlpha) == -1) {
            alert("FIRST NAME must contain only ALPHABETIC data.");
            first_name.focus();
            return false;
        }

        if ((middle_name.value != "") && (middle_name.value.search(regexAlpha) == -1)) {
            alert("MIDDLE NAME must contain only ALPHABETIC data.");
            middle_name.focus();
            return false;
        }

        if (last_name.value == "") {
            alert("Please enter your LAST NAME.");
            last_name.focus();
            return false;
        }

        if (last_name.value.search(regexAlpha) == -1) {
            alert("LAST NAME must contain only ALPHABETIC data.");
            last_name.focus();
            return false;
        }

        if ((name_suffix.value != "") && (name_suffix.value.search(regexAlpha) == -1)) {
            alert("SUFFIX must contain only ALPHABETIC data.");
            name_suffix.focus();
            return false;
        }

        if (height_feet.value == "") {
            alert("Please select your HEIGHT in FEET.");
            height_feet.focus();
            return false;
        }

        if (height_inches.value == "") {
            alert("Please select your HEIGHT in INCHES.");
            height_inches.focus();
            return false;
        }

        if (weight.value == "") {
            alert("Please enter your WEIGHT.");
            weight.focus();
            return false;
        }

        if (weight.value.search(regexNumeric) == -1) {
            alert("WEIGHT must contain only NUMERIC data.");
            weight.focus();
            return false;
        }

        if (gender == -1) {
            alert("Please select your GENDER.");
            
            // Reformat the incoming panel from 'name' to 'id'.
            var formattedPanel = panel.replace(/\$/g, "_");
            document.getElementById(formattedPanel + "userControlCustomerInformation_rdoGender_RB0_I").focus();
            return false;
        }

        if (checkPhone) {
            var phone_area_code = document.getElementsByName(panel + "userControlCustomerInformation$txtPhoneAreaCode")[0];
            var phone_prefix = document.getElementsByName(panel + "userControlCustomerInformation$txtPhonePrefix")[0];
            var phone_suffix = document.getElementsByName(panel + "userControlCustomerInformation$txtPhoneSuffix")[0];
            var phone = phone_area_code.value + phone_prefix.value + phone_suffix.value;

            if (phone != "") {
                if ((phone_area_code.value == "") || (phone_area_code.value.length < 3)) {
                    alert("Please enter a valid 3 digit AREA CODE.");
                    phone_area_code.focus();
                    return false;
                }

                if (phone_area_code.value.search(regex3Digit) == -1) {
                    alert("PHONE must contain only NUMERIC data.");
                    phone_area_code.focus();
                    return false;
                }

                if ((phone_prefix.value == "") || (phone_prefix.value.length < 3)) {
                    alert("Please enter a valid PREFIX for your phone number.");
                    phone_prefix.focus();
                    return false;
                }

                if (phone_prefix.value.search(regex3Digit) == -1) {
                    alert("PHONE must contain only NUMERIC data.");
                    phone_prefix.focus();
                    return false;
                }

                if ((phone_suffix.value == "") || (phone_suffix.value.length < 4)) {
                    alert("Please enter a valid SUFFIX for your phone number.");
                    phone_suffix.focus();
                    return false;
                }

                if (phone_suffix.value.search(regex4Digit) == -1) {
                    alert("PHONE must contain only NUMERIC data.");
                    phone_suffix.focus();
                    return false;
                }
            }
        }

        if ((email.value != "") && (email.value.search(regexemail) == -1)) {
            alert("Please enter a valid EMAIL ADDRESS.");
            email.focus();
            return false;
        }
    }
}

//11/29/10 MST - Provides client-side validation for the CustomerAddress user control.
function validate_customer_address(thisform, panel) {
    with (thisform) {
        var address1 = document.getElementsByName(panel + "userControlCustomerAddress$txtAddress1")[0];
        var city = document.getElementsByName(panel + "userControlCustomerAddress$txtCity")[0];
        var state = document.getElementsByName(panel + "userControlCustomerAddress$ddlStateOrProvince")[0];
        var zip = document.getElementsByName(panel + "userControlCustomerAddress$txtZipPostalCode")[0];
        var country = document.getElementsByName(panel + "userControlCustomerAddress$ddlCountry")[0];

        var regex5Digit = /[0-9]{5}/;
        var regexAlpha = /^[a-zA-Z ."\'"-]*$/;

        if (address1.value == "") {
            alert("Please enter your STREET ADDRESS.");
            address1.focus();
            return false;
        }

        if (city.value == "") {
            alert("Please enter your CITY name.");
            city.focus();
            return false;
        }
        else if (city.value.search(regexAlpha) == -1) {
            alert("CITY must contain only ALPHABETIC data.");
            city.focus();
            return false;
        }

        if (country.value == "USA") {
            if (zip.value == "") {
                alert("Please enter your ZIP code.");
                zip.focus();
                return false;
            }

            if (zip.value.length != 5) {
                alert("Please enter your 5 digit ZIP code.");
                zip.focus();
                return false;
            }

            if (zip.value.search(regex5Digit) == -1) {
                alert("ZIP must contain only NUMERIC data.");
                zip.focus();
                return false;
            }
        }

        if (country.value == "CAN") {
            if (zip.value == "") {
                alert("Please enter your Postal code.");
                zip.focus();
                return false;
            }

            if (zip.value.length != 7) {
                alert("Please enter your full Postal code.");
                zip.focus();
                return false;
            }
        }
    }
}

//12/09/2010 - Provides client-side validation for the AdditionalQuestions screen.
var rdoElkHunting;
var panHuntAreaChoices;
var rdoHunterSafety;
var txtHuntPartyID;
var rdoLandOwnership;
var txtLandOwnerPhone;
var rdoHipSurveyParticipate;
var rdoHipSurveyDecline;
var txtItemQuantity;
var dteEffectiveDate;

function validate_questions_form(thisform) {
    with (thisform) {
        var txtHuntParty = "";

        if (document.activeElement.name == "ctl00$MainContent$btnContinue") {

            // Validate that the entered number contains only numbers.  If not, display the count of
            // and actual invalid characters to the customer.
            function validNumber(questionValue) {
                var comparisonNumbers = "0123456789";
                var invalidFlag = 0;
                var invalidChars = "";
                var invalidSpace = "";

                for (var i = 0; i < questionValue.length; i++) {
                    testChar = questionValue.substring(i, i + 1);
                    if (comparisonNumbers.indexOf(testChar) < 0) {
                        invalidFlag++;
                        invalidChars += " " + testChar;
                        invalidSpace += testChar;
                    }
                }
                if (invalidFlag != 0) {
                    if (invalidSpace.indexOf(" ") > -1) {
                        invalidChars += " and a space";
                    }
                    alert("This entry must be a number. Detected " + invalidFlag + " unacceptable characters: " + invalidChars + ".");
                    return false;
                }
                return true;
            }

            if (txtHuntPartyID != null) {
                // validate the user has entered a valid hunt party ID
                txtHuntParty = txtHuntPartyID.inputElement.value;
                if (txtHuntParty.length > 0) {
                    if (!validNumber(txtHuntParty)) {
                        txtHuntPartyID.inputElement.focus();
                        return false;
                    }
                    if (txtHuntParty.length < 12) {
                        alert("The Hunt Party ID you entered is invalid.  Please re-enter.");
                        txtHuntPartyID.inputElement.focus();
                        return false;
                    }
                    if (txtHuntParty.search(/^\d{12}$/) == -1) {
                        alert("The Hunt Party ID must be a number.");
                        txtHuntPartyID.inputElement.focus();
                        return false;
                    }
                    if (!check_luhn(txtHuntParty.substring(0, txtHuntParty.length - 2), txtHuntParty.substring(txtHuntParty.length - 1, txtHuntParty.length))) {
                        alert("The Hunt Party ID you entered is invalid.  Please re-enter.");
                        txtHuntPartyID.inputElement.focus();
                        return false;
                    }
                }
            }

            if (rdoElkHunting != null) {
                // validate the user has selected an elk hunting option
                if (rdoElkHunting.GetSelectedIndex() == -1) {
                    alert("Please select 'Bull Only', 'Bull or Antlerless', or 'Chance Only'.");
                    document.getElementById("ctl00_MainContent_ctl00_rdoElkHunting_RB0_I").focus();
                    return false;
                }
            }

            if (panHuntAreaChoices != null) {
                // get all the child hunt area lists to pull their selected values
                var huntAreaChoices = document.getElementById(panHuntAreaChoices.name).getElementsByTagName("select");
                if (huntAreaChoices.length > 0) {
                    // validate the user has selected at least one hunt area
                    // unless the user has entered a valid hunt party
                    if ((huntAreaChoices[0][0].selected) && (txtHuntParty.length == 0)) {
                        alert("You are required to select your first choice of hunt area selection.");
                        huntAreaChoices[0].focus();
                        return false;
                    }
                    // validate the user has not selected a hunt area when the user has entered a valid hunt party
                    else if (txtHuntParty.length == 12) {
                        // iterate the list of hunt areas and make sure nothing other than zero is selectioned
                        for (var choice = 0; choice < huntAreaChoices.length; choice++) {
                            if (huntAreaChoices[choice].selectedIndex != 0) {
                                alert("Hunt area selections are not allowed if you enter an existing Hunt Party ID.  "
                                      + "Please clear your hunt area selection.");

                                // Set the focus onto to correct Clear Choice option.
                                document.getElementById(panHuntAreaChoices.name + "_rptHuntAreaChoices_ctl0" + (choice + 1) +"_btnClearChoice").focus();
                                return false;
                            }
                        }

                    }

                    // iterate the list of hunt areas and make sure there are no duplicate selections
                    for (var choice1 = 0; choice1 < huntAreaChoices.length; choice1++) {
                        var firstChoice = huntAreaChoices[choice1].selectedIndex;
                        if (firstChoice != 0) {
                            for (var next = choice1 + 1; next < huntAreaChoices.length; next++) {
                                if (firstChoice == huntAreaChoices[next].selectedIndex) {
                                    alert("Hunt area '" + huntAreaChoices[choice1][firstChoice].text
                                          + "' has already been selected.  Please select another hunt area.");
                                    huntAreaChoices[next].focus();
                                    return false;
                                }
                            }
                        }
                    }

                    // Iterate the list of hunt areas and make sure there aren't any blank area between selections.
                    // This isn't a processing issue, but a stylistic request.
                    var endOfList = false;

                    for (var choice2 = 0; choice2 < huntAreaChoices.length; choice2++) {
                        if (huntAreaChoices[choice2][0].selected && endOfList == false) {
                            endOfList = true;
                        }
                        else if (!huntAreaChoices[choice2][0].selected && endOfList == true) {
                            alert("You may select fewer hunt area choices than the maximum allowed but you may not "
                                + "skip over a hunt area choice.");

                            // Set the focus onto to correct Clear Choice option.
                            document.getElementById(panHuntAreaChoices.name + "_rptHuntAreaChoices_ctl0" + (choice2 + 1) + "_btnClearChoice").focus();
                            return false;
                        }
                    }
                }
            }

            if (rdoHunterSafety != null) {
                // validate the user has selected a hunter safety option
                if (rdoHunterSafety.GetSelectedIndex() == -1) {
                    alert("Please respond to the hunter safety question.");
                    document.getElementById("ctl00_MainContent_ctl00_rdoHunterSafety_RB0_I").focus();
                    return false;
                }
                // notify the user that their purchase will be cancelled based on responding no to hunter safety
                else if (rdoHunterSafety.GetSelectedIndex() == 1) {
                    var response = confirm("You are not qualified to purchase this license based on Hunter Safety requirements.\n"
                            + "If you Click on the 'OK' button, the purchase of this item will be cancelled and you will be returned to the "
                            + "'Available E-License Items' page.  If you click on the 'Cancel' button, you will be given an opportunity to "
                            + "change your answer.");
                    return response;
                }
            }

            if (rdoLandOwnership != null) {
                // validate the user has selected an ownership basis
                if (rdoLandOwnership.GetSelectedIndex() == -1) {
                    alert("Please indicate the basis (Guest/Renter or Owner) for the Private Land Application.");
                    rdoLandOwnership.Focus();
                    return false;
                }
            }

            if (txtLandOwnerPhone != null) {
                // validate the user has entered a valid land owner's phone number
                var phoneNumber = txtLandOwnerPhone.inputElement.value;
                if (phoneNumber.length == 0) {
                    alert("The Owner's phone number is required.");
                    txtLandOwnerPhone.inputElement.focus();
                    return false;
                }
                if (phoneNumber.length < 10) {
                    alert("The Owner's phone number must be 10 digits long.");
                    txtLandOwnerPhone.inputElement.focus();
                    return false;
                }
                if (!validNumber(phoneNumber)) {
                    txtLandOwnerPhone.inputElement.focus();
                    return false;
                }
            }

            if (rdoHipSurveyParticipate != null && rdoHipSurveyDecline != null) {
                // validate the user has indicated whether they will respond to the HIP survey
                if (!rdoHipSurveyParticipate.GetChecked() && !rdoHipSurveyDecline.GetChecked() ) {
                    alert("Please respond as to whether or not there is a chance you will hunt any migratory birds this year.");
                    rdoHipSurveyParticipate.Focus();
                    return false;
                }
                else if (rdoHipSurveyParticipate.GetChecked()) {
                    // validate the user has indicated whether they hunted snipe last year
                    if (rdoSnipeSurvey.GetSelectedIndex() == -1) {
                        alert("Please respond as to whether or not you hunted for Snipe, Rails, or Gallinules last year.");
                        rdoSnipeSurvey.Focus();
                        return false;
                    }
                }
            }

            if (txtItemQuantity != null) {
                // validate the user has entered a valid quantity for multi item purchase
                var itemQuantity = txtItemQuantity.inputElement.value;
                if (itemQuantity.length == 0) {
                    alert("Please enter the number of licenses you wish to purchase.");
                    txtItemQuantity.inputElement.focus();
                    return false;
                }
                if (!validNumber(itemQuantity)) {
                    txtItemQuantity.inputElement.focus();
                    return false;
                }
                if (itemQuantity < 1 || itemQuantity > 20) {
                    alert("Please enter a number between 1 and 20 (inclusive).");
                    txtItemQuantity.inputElement.focus();
                    return false;
                }
            }

            if (dteEffectiveDate != null) {
                // Validate the user has entered an effective date.  If the date is in error, the control
                // removes the date entirely.
                var effectiveDate = dteEffectiveDate.GetDate();

                if (effectiveDate == null) {
                    alert("Please enter a valid effective date for the license.");
                    dteEffectiveDate.Focus();
                    return false;
                }
            }
        }
    }
}

//12/08/10 MST - Provides client-side validation for the EnterCustomerForReprint screen.
function validate_reprint_form(thisform, panel) {
    with (thisform) {
        if (document.activeElement.title == "Submit Request") {
            var transactionMonth = document.getElementsByName(panel + "ddlTransactionMonth")[0];
            var transactionDay = document.getElementsByName(panel + "ddlTransactionDay")[0];
            var transactionYear = document.getElementsByName(panel + "ddlTransactionYear")[0];

            // Check if the transaction date entered by the customer is valid
            var transactionDate = new Date(transactionMonth.value + '/' + transactionDay.value + '/' + transactionYear.value);

            if (transactionDate.getMonth() != (parseFloat(transactionMonth.value) - 1)) { // Month starts from 0 in Javascript
                alert("Please enter a valid transaction date.");
                transactionMonth.focus()
                return false;
            }

            if (transactionDate.getDate() != parseFloat(transactionDay.value)) {
                alert("Please enter a valid transaction date.");
                transactionDay.focus()
                return false;
            }

            if (transactionDate.getFullYear() != parseFloat(transactionYear.value)) {
                alert("Please enter a valid transaction date.");
                transactionYear.focus()
                return false;
            }
            
            if (transactionDate > new Date()) {
                alert("You have entered a transaction date in the future. Please re-enter.");
                transactionYear.focus()
                return false;
            }

            if (validate_customer(thisform, panel + "userControlCustomerID$") == false) {
                return false;
            }

            var michiganID = document.getElementsByName(panel + "userControlCustomerID$txtMichiganID")[0].value;
            if (michiganID != "") {
                var lastName = document.getElementsByName(panel + "userControlCustomerInformation$txtLastName")[0];

                if (michiganID.charAt(0).toUpperCase() != lastName.value.charAt(0).toUpperCase()) {
                    var stateAbbr = document.getElementById("StateAbbrResource").value;
                    alert("The first character of your 11 character " + stateAbbr + " ID does not match the first character of your last name.  "
                          + "Please verify the spelling of your last name.  If your last name has changed since you obtained your "
                          + "11 character " + stateAbbr + " ID, you must use your old name or obtain a new ID number before proceeding with this order.");
                    lastName.focus();
                    return false;
                }
            }

            if (validate_date_of_birth(thisform, panel) == false) {
                return false;
            }

            if (validate_customer_information(thisform, panel, false) == false) {
                return false;
            }

            if (validate_customer_address(thisform, panel) == false) {
                return false;
            }
        }
    }
}

//12/08/10 MST - Provides client-side validation for the ReprintLicenseTransList screen.
function validate_reprint_list_form(thisform) {
    with (thisform) {
        var selectedTransaction = document.getElementsByName("ctl00$MainContent$roundPanelTransactions$rdoTransactions")[0].value;

        if (selectedTransaction == -1) {
            alert("Please select a transaction");
            document.getElementById("ctl00_MainContent_roundPanelTransactions_rdoTransactions_RB0_I").focus();
            return false;
        }
    }
}

//12/11/10 PO - Validate the ID against the check digit using the Luhn Algorithm
function check_luhn(id, checkDigit) {
    var odd;
    var v_total;
    var v_digit;
    var v_digit2;
    var v_check;

    odd = true;
    v_total = 0;
    for (var index = id.length; index > 0; index--) {
        v_digit = id.substring(index - 1, index);
        if (odd) {
            v_digit2 = (parseInt(v_digit)) * 2;
            if (v_digit2 > 9) {
                v_digit2 = 1 + (parseInt(v_digit2) - 10);
            }
            v_total = v_total + parseInt(v_digit2);
            odd = false;
        }
        else {
            v_total = v_total + parseInt(v_digit);
            odd = true;
        }
    }
    v_check = v_total % 10;
    if (v_check > 0) {
        v_check = 10 - v_check;
    }

    if (v_check == checkDigit) {
        return true;
    }
    else {
        return false;
    }
}

