﻿//Settings
var hiddenPasswordFieldIDToken = "_hiddenpw";
var errorTypes = { "Required" : 0, "Invalid" : 1, "Mismatch" : 2 };
var errorPostFixes = new Array("req","valid","match");
var debug = true;
var defaultTextColor = "#666";
var onTextColor = "#000";

//Validation Functions
function Validate(id) {
    
    var hasErrors = false;

    if (ElementExists(id)) {
        $("#" + id + " input[type!='submit'][type!='image']:visible," + "#" + id + " select:visible").each(function() {            
            if (!ValidateField(this.id)) hasErrors = true;
        });
    }
    else
    {
       if (console.error) console.error("Couldn't find form to validate");
    }
   
    return !hasErrors
}

function ValidateField(id) {
    if (ElementExists(id)) {
        el = $("#" + id);

        if (IsRequiredField(el)) {
            if (IsBlankValue(el.val())) {
                ShowError(el, errorTypes.Required);
                return false;
            }
            ClearError(el, errorTypes.Required);

            if (HasDefaultAttribute(el)) {
                if (el.val() == el.attr("default")) {
                    ShowError(el, errorTypes.Required);
                    return false;
                }
            }
            ClearError(el, errorTypes.Required);
        }        

        if (IsEmailField(el)) {

            if (HasDefaultAttribute(el)) {
                if (el.val() != el.attr("default")) {
                    if (!IsValidEmailAddress(el.val())) {
                        ShowError(el, errorTypes.Invalid);
                        return false;
                    }
                }
            }                
            ClearError(el, errorTypes.Invalid);
        }

        if (IsCreditCardField(el)) {
            var payMethodField = el.attr("paymethod");

            if (payMethodField != "") {
                var payMethod = $("#" + payMethodField).val();

                if (!IsValidCreditCard(el.val(), payMethod)) {
                    ShowError(el, errorTypes.Invalid);
                    return false;
                }
                ClearError(el, errorTypes.Invalid);
            }

        }

        if (IsNumericField(el)) {
            if (!IsNumeric(el.val())) {
                ShowError(el, errorTypes.Invalid);
                return false;
            }
            ClearError(el, errorTypes.Invalid);
        }

        if (IsDateField(el)) {            
        
            var day = null, month = null, year = null;

            if (el.attr("day")) {
                if (ElementExists(el.attr("day"))) day = parseInt($("#" + el.attr("day")).val(),10);
            }
            if (el.attr("month")) {
                if (ElementExists(el.attr("month"))) month = parseInt($("#" + el.attr("month")).val(), 10);
            }
            if (el.attr("year")) {
                if (ElementExists(el.attr("year"))) year = parseInt($("#" + el.attr("year")).val(), 10);
            }

            if (!IsValidDate(day, month, year)) {
                ShowError(el, errorTypes.Invalid);
                return false;
            }
            ClearError(el, errorTypes.Invalid);
        }

        if (IsMatchedField(el)) {
            if (ElementExists(GetMatchedField(el))) {

                var fieldToMatch = GetMatchedField(el); 
                var el2 = $("#" + GetMatchedField(el));

                if (el2.is(":visible")) {
                    if (!ValuesMatch(el, el2)) {
                        ShowError(el, errorTypes.Mismatch);
                        return false;
                    }
                }
                else {
                    ShowError(el, errorTypes.Mismatch);
                    return false;
                }

                ClearError(el, errorTypes.Mismatch);
            }
        }
    }
    return true;
}

function ShowError(el,errorType)
{
    var typePostFix = errorPostFixes[errorType];

    if (el.attr("erroroverride")) el = $("#" + el.attr("erroroverride"));

    var errorId = el.attr("id") + "_" + typePostFix;
    
    if (ElementExists(errorId)) $("#" + errorId).show();    
}

function ClearError(el,errorType)
{
    var typePostFix = errorPostFixes[errorType];

    if (el.attr("erroroverride")) el = $("#" + el.attr("erroroverride"));

    var errorId = el.attr("id") + "_" + typePostFix;

    if (ElementExists(errorId)) $("#" + errorId).hide();

    if (el.attr("id").indexOf(hiddenPasswordFieldIDToken) >= 0 && errorType == errorTypes.Required) {
        ClearError($("#" + el.attr("id").replace(hiddenPasswordFieldIDToken, "")), errorType);     
    }    
}

function IsRequiredField(element) {
    if (element.attr("validation")) {        
        if (element.attr("validation").indexOf("req") >= 0) return true;
    }
    return false;
}

function IsEmailField(element) {
    if (element.attr("validation")) {
        if (element.attr("validation").indexOf("email") >= 0) return true;
    }
    return false;
}

function IsCreditCardField(element) {
    if (element.attr("validation")) {
        if (element.attr("validation").indexOf("cc") >= 0) return true;
    }
    return false;
}

function IsNumericField(element) {
    if (element.attr("validation")) {
        if (element.attr("validation").indexOf("numeric") >= 0) return true;
    }
    return false;
}

function IsLengthLimitedField(element) {
    if (element.attr("validlength")) {
        return true;
    }
    return false;
}

function IsDateField(element) {
    if (element.attr("validation")) {
        if (element.attr("validation").indexOf("date") >= 0) return true;
    }

    return false;
}


function IsMatchedField(element) {
    if (element.attr("match")) return true;

    return false;
}

function GetMatchedField(element) {
    if (element.attr("match")) return element.attr("match");
    return null;
}

function GetMaxLength(element) {
    if (element.attr("validlength")) {
        return parseInt(element.attr("validlength"), 10);
    }

    return 0;
}

function ValuesMatch(element1, element2) {
    if (HasDefaultAttribute(element1) && HasDefaultAttribute(element2))
    {
        if (element1.val() == element1.attr("default") && element2.val() == element2.attr("default")) return true;
    }
    
    if (element1.val() == element2.val()) return true;        

    return false;
}

function IsValidEmailAddress(value) {
    var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    if (!filter.test(value)) {
        return false;
    }

    return true;
}

function IsNumeric(val) {
    if (val.match(/^[0-9]+$/)) { return true; } else { return false; }
}
 
 
function IsValidDate(day, month, year) {

    var now = new Date();
    var userDay = day;
    var userMonth = month - 1;
    var userYear = year;

    if (userDay == null) userDay = now.getDate();
    if (userMonth == null) userMonth = now.getMonth();
    if (userYear == null) userYear = now.getFullYear();
    
    var userDate = new Date();
    userDate.setDate(userDay);
    userDate.setMonth(userMonth);
    userDate.setFullYear(userYear);
    
    if (userDate < now) return false;
    
    return true;   
}   

function IsValidCreditCard(cardnumber, cardname) {
    var ccErrorNo = 0;
    var cards = new Array();

    cards[0] = { name: "VI",
        length: "13,16",
        prefixes: "4",
        checkdigit: true
    };
    cards[1] = { name: "MC",
        length: "16",
        prefixes: "51,52,53,54,55",
        checkdigit: true
    };
    cards[2] = { name: "AX",
        length: "15",
        prefixes: "34,37",
        checkdigit: true
    };
    cards[3] = { name: "DI",
        length: "16",
        prefixes: "6011,622,64,65",
        checkdigit: true
    };

    // Establish card type
    var cardType = -1;
    for (var i = 0; i < cards.length; i++) {

        // See if it is this card (ignoring the case of the string)
        if (cardname.toLowerCase() == cards[i].name.toLowerCase()) {
            cardType = i;
            break;
        }
    }

    // If card type not found, report an error
    if (cardType == -1) {
        ccErrorNo = 0;
        return false;
    }

    // Ensure that the user has provided a credit card number
    if (cardnumber.length == 0) {
        ccErrorNo = 1;
        return false;
    }

    // Now remove any spaces from the credit card number
    cardnumber = cardnumber.replace(/\s/g, "");

    // Check that the number is numeric
    var cardNo = cardnumber
    var cardexp = /^[0-9]{13,19}$/;
    if (!cardexp.exec(cardNo)) {
        ccErrorNo = 2;
        return false;
    }

    // Now check the modulus 10 check digit - if required
    if (cards[cardType].checkdigit) {
        var checksum = 0;                                  // running checksum total
        var mychar = "";                                   // next char to process
        var j = 1;                                         // takes value of 1 or 2

        // Process each digit one by one starting at the right
        var calc;
        for (i = cardNo.length - 1; i >= 0; i--) {

            // Extract the next digit and multiply by 1 or 2 on alternative digits.
            calc = Number(cardNo.charAt(i)) * j;

            // If the result is in two digits add 1 to the checksum total
            if (calc > 9) {
                checksum = checksum + 1;
                calc = calc - 10;
            }

            // Add the units element to the checksum total
            checksum = checksum + calc;

            // Switch the value of j
            if (j == 1) { j = 2 } else { j = 1 };
        }

        // All done - if checksum is divisible by 10, it is a valid modulus 10.
        // If not, report an error.
        if (checksum % 10 != 0) {
            ccErrorNo = 3;
            return false;
        }
    }

    // The following are the card-specific checks we undertake.
    var LengthValid = false;
    var PrefixValid = false;
    var undefined;

    // We use these for holding the valid lengths and prefixes of a card type
    var prefix = new Array();
    var lengths = new Array();

    // Load an array with the valid prefixes for this card
    prefix = cards[cardType].prefixes.split(",");

    // Now see if any of them match what we have in the card number
    for (i = 0; i < prefix.length; i++) {
        var exp = new RegExp("^" + prefix[i]);
        if (exp.test(cardNo)) PrefixValid = true;
    }

    // If it isn't a valid prefix there's no point at looking at the length
    if (!PrefixValid) {
        ccErrorNo = 3;
        return false;
    }

    // See if the length is valid for this card
    lengths = cards[cardType].length.split(",");
    for (j = 0; j < lengths.length; j++) {
        if (cardNo.length == lengths[j]) LengthValid = true;
    }

    // See if all is OK by seeing if the length was valid. We only check the 
    // length if all else was hunky dory.
    if (!LengthValid) {
        ccErrorNo = 4;
        return false;
    };

    // The credit card is in the required format.
    return true;
}

function IsBlankValue(value) {
    var whitespace = /^\s*$/;

    if (value.match(whitespace)) return true;

    return false;
}


//Default Value Functions

function SetDefaultFormValues(id, ignoreExisitingValues) {
    if (ElementExists(id)) {
        $("#" + id + " input," + "#" + id + " select:visible").each(function() {
            if (this.id != null & this.id != "") SetDefaultValue(this.id, ignoreExisitingValues);                        
        });           
    }
}

function SetDefaultValue(id, ignoreExisitingValue) {
    if (ElementExists(id)) {        
        var el = $("#" + id);
        if (HasDefaultAttribute(el) && el.attr("default") != "") {
            if (el.val() == "" || ignoreExisitingValue) el.val(el.attr("default"));
        }

        if (id.indexOf(hiddenPasswordFieldIDToken) >= 0) {
            if (el.val() != "") {
                el.show();
                $("#" + id.replace(hiddenPasswordFieldIDToken, "")).hide();
            }                    
        }
    }       
}

function SetHandlers(id) {
    SetClickHandler(id);
    SetBlurHandler(id);
}

function SetClickHandler(id) {
    $("#" + id + " input").focus(function() {
        if ($(this).attr("password")) {
            $(this).hide();
            $("#" + $(this).attr("id") + hiddenPasswordFieldIDToken).show();
            $("#" + $(this).attr("id") + hiddenPasswordFieldIDToken).css("color", onTextColor);
            $("#" + $(this).attr("id") + hiddenPasswordFieldIDToken).focus();
        }
        else {
            if (HasDefaultAttribute($(this)) && $(this).val() == $(this).attr("default")) {
                $(this).val("");
                $(this).css("color", onTextColor);
            }
        }
    });       
}

function SetBlurHandler(id) {

    $("#" + id + " input").blur(function() {
        if ($(this).attr("id").indexOf(hiddenPasswordFieldIDToken) > 0 && IsBlankValue($(this).val())) {
            $(this).hide();
            $("#" + $(this).attr("id").replace(hiddenPasswordFieldIDToken, "")).show();
        }
        else {
            if (HasDefaultAttribute($(this)) && IsBlankValue($(this).val())) {
                $(this).css("color", defaultTextColor);
                $(this).val($(this).attr("default"));
            }
        }
    });
}

function ClearDefaultValues(id) {
    if (ElementExists(id)) {
        $("#" + id + " input").each(function() {
            ClearDefaultValue(this.id);
        });
    }
}

function ClearDefaultValue(id) {
    if (ElementExists(id))
    {
        var el = $("#" + id);
        if (HasDefaultAttribute(el) && el.attr("default") != "") {
            if (el.val() == el.attr("default")) el.val("");            
        }
    }        
}

function HasDefaultAttribute(element) {
    if (element.attr("default") != "") return true;
    return false;
}

function ElementExists(id) {
    if (id != "") {
        if ($("#" + id).length > 0) return true;
    }
    return false;
}

