﻿var ErrorContainer_Suffix = "_err";
var Container_Suffix = "_ctr";
var ErrMsg_Required = "Value is required.";
var ErrMsg_ValidType = "Please specify valid value.";
var ErrMsg_ValidMinLength = "The value has less than the minimum number of allowable characters.";
var ErrMsg_ValidMaxLength = "The value exceeded the maximum number of allowable characters.";
var ErrMsg_ValidMinValueLength = "The selection has less than the minimum number of values.";
var ErrMsg_ValidMaxValueLength = "The selection exceeded the maximum number of values.";
var ErrMsg_EmailVerify = "Please verify your email address correctly."
var ErrMsg_PasswordVerify = "Please verify your password correctly."
var DefaultErrorMessage = "We're sorry but there are problems with your submission. Please correct the problems and submit again.";

/**
 Definition of a validation of object. Following properties are defined in this entity:
 Name : registratio form field name 
 Type : Alpha, Numeric, Alphanumeric, Date, multiselect, radio, checkbox, checkboxlist, phone, email, url
 Required : field is required or not
 MaximumLength : Maximum chars allowed for the response
                 For Type checkboxlist and multiselect, this restricts the user to select items more than the define maximum value.
 MinimumLength : Minimum chars allowed for the response
                 For Type checkboxlist and multiselect, this restricts the user to select items less than the define minimum value.
RegularExpression : regular expression to be executed to validate the value
ErrorMessage : error message
CustomFunction : function specifically designed for custom validation
**/

function Validation(name, value, type, required, maxlen, minlen, regex, errmsg, customfunc) 
{
    this.Type = type;
    this.Name = name;
    this.Value = value;
    this.Required = required;
    this.MaximumLength = maxlen;
    this.MinimumLength = minlen;
    this.RegularExpression = regex;
    this.ErrorMessage = errmsg;
    this.CustomFunction = customfunc;
}

//retrieve question form id
Validation.prototype.GetFormQuestionId = function ()
{
    return this.Name;
}

// get element in the page by name
function getElement(name)
{
    if (!name)
        return null;
    return document.getElementsByName(name);
}

// Get values of a particular field.
function GetValues(id, type)
{
    var values = "";
    type = type.toLowerCase();
    //iterate through the selections if type is checkbox, radio or checkboxlist
    if ( type == "radio" || type == "checkbox" || type == "checkboxlist")
    {
        var valuelist = document.getElementsByName(id);      
        if (valuelist) 
        {    
            for (var i=0; i<valuelist.length; i++)
                if (valuelist[i].checked || valuelist[i].selected) 
                {
                    if (values == "")
                        values = valuelist[i].value;
                    else
                        values = values + "," + valuelist[i].value;
                }
        }
    }
    //iterate through the list of items if the type is multiselect
    else if (type == "multiselect")
    {
        var list = document.getElementById(id); 
        if (list)
        {
            for (var i=0; i<list.options.length; i++)
                if (list.options[i].selected) 
                {
                    if (values == "")
                        values = list.options[i].value;
                    else
                        values = values + "," + list.options[i].value;
                }
        }
    }
    //otherwise jsut retrieve the data
    else
    {
        var formQuestion = document.getElementById(id);   
        if (formQuestion)
            return formQuestion.value;
    }
        
    return values;
}

//displays the main error message
function setMainErrorMessage(message)
{
        var errDiv = document.getElementById("errorsummary");     
        if (errDiv) 
        {
            errDiv.innerHTML = message;
            if (message=="")
                errDiv.className = "reg_main_err_msg_off"; 
            else
                errDiv.className = "reg_main_err_msg"; 
        }
}
//sets the error message of a particular field
function setErrorMessage(containerId, message)
{
    var errorDivId = containerId + ErrorContainer_Suffix;
    var errDiv = document.getElementById(errorDivId);     

    if (errDiv)
        errDiv.innerHTML = message;
    
    var conDivId = containerId + Container_Suffix;
    var conDiv = document.getElementById(conDivId);     
    
    if (conDiv) 
    {
        if (message == "")
        {
            if (conDiv.className == "reg_err_msg")
                conDiv.className = "reg_err_msg_off";   
        }
        else
        {
            if (conDiv.className == "reg_err_msg_off")
                conDiv.className = "reg_err_msg"; 
        }
    }
}

//Main validation function.
function ValidateRegistration()
{
    
    setMainErrorMessage("");
    var bSuccess = true;
    if(validations)
    {
    
        for(var i=0;i<validations.length;i++)
        {
            
            var questionId = validations[i].GetFormQuestionId();
            setErrorMessage(questionId, "");

            validations[i].Value = GetValues(questionId, validations[i].Type);

            if (!validations[i].HasRequiredValue()) 
            {
                setErrorMessage(questionId, ErrMsg_Required);
                bSuccess = false;
                continue; 
            }

            if (!validations[i].HasValidType())    
            {
                setErrorMessage(questionId, ErrMsg_ValidType);
                bSuccess = false;
                continue;
            }
            
            if (!validations[i].ExecuteExpression())
            {
                setErrorMessage(questionId, validations[i].ErrorMessage);
                bSuccess = false;
                continue;
            }
           
            if (!validations[i].HasValidMinLength())
            {
                if (validations[i].Type.toLowerCase() == "checkboxlist" ||
                    validations[i].Type.toLowerCase() == "multiselect") 
                    setErrorMessage(questionId, ErrMsg_ValidMinValueLength);
                else
                    setErrorMessage(questionId, ErrMsg_ValidMinLength);
                bSuccess = false;
                continue;
            }

            if (!validations[i].HasValidMaxLength())
            {
                if (validations[i].Type.toLowerCase() == "checkboxlist" ||
                    validations[i].Type.toLowerCase() == "multiselect") 
                    setErrorMessage(questionId, ErrMsg_ValidMaxValueLength);
                else
                    setErrorMessage(questionId, ErrMsg_ValidMaxLength);
                bSuccess = false;
                continue;
            }
            
            
            var message = validations[i].ExecuteCustomFunction();
            if (message != "") 
            {
                
                setErrorMessage(questionId, message);
                bSuccess = false;
                continue;
            }
        }
    }
    
    if (!bSuccess)
    {
        setMainErrorMessage(DefaultErrorMessage);
        window.location.href = "#top";
    }
    
    return bSuccess;
}

//validates value give the maximum length
Validation.prototype.HasValidMaxLength = function ()
{
    if(!this.MaximumLength || this.MaximumLength < 0)
        return true;
    
    if (this.Type.toLowerCase() == "checkboxlist" ||
        this.Type.toLowerCase() == "multiselect") 
    {
        var len = 0;
        if (this.Value && this.Value != "")
        {
            var arrvalue = this.Value.split(",");   
            len = arrvalue.length;
        } 
        return (len <= this.MaximumLength);
    }
    else
        return (this.Value.length <= this.MaximumLength);
}

//validates value give the minimum length
Validation.prototype.HasValidMinLength = function ()
{
    if(!this.MinimumLength || this.MinimumLength < 0)
        return true;
        
    if (this.Type.toLowerCase() == "checkboxlist" ||
        this.Type.toLowerCase() == "multiselect") 
    {
        var len = 0;
        if (this.Value && this.Value != "")
        {
            var arrvalue = this.Value.split(",");   
            len = arrvalue.length;
        }
        
        return ( len >= this.MinimumLength);
    }
    else
        return (this.Value.length >= this.MinimumLength);
}


//execute regular expression to validate a particular field
Validation.prototype.ExecuteExpression = function ()
{
    if(!this.Value || this.Value == "" || !this.RegularExpression || this.RegularExpression == "" )
        return true;

    return IsValidRegularExpression(this.Value, this.RegularExpression);
}

// validates the required field
Validation.prototype.HasRequiredValue = function ()
{
    if(!this.Required || this.Required == "")
        return true;
    if (this.Required.toLowerCase() == "y" && (!this.Value || this.Value == "") )
        return false;
    return true;
}

//validate the value according to Type
Validation.prototype.HasValidType = function ()
{
    if(!this.Value || this.Value == "" || !this.Type || this.Type == "" )
        return true;

    switch(this.Type.toLowerCase())
    {
        case "alpha":
            return IsValidRegularExpression(this.Value, "^[A-Za-z ]+$");
        case "numeric":
            return IsValidRegularExpression(this.Value,"^[0-9]+$");
        case "alphanumeric":
            return IsValidRegularExpression(this.Value,"^[A-Za-z0-9 ]+$");
        case "phone":
            return IsValidRegularExpression(this.Value, "^([0-9]+[() .]?)+[xX]?[ ]?[0-9]+$");
        case "zip":
             return IsValidRegularExpression(this.Value, "^[0-9]{5}(-[0-9]{4})?$");
        case "email":
            return IsValidEmailAddress(this.Value);
        case "date":
            return isDate(this.Value);
        case "url":
            return IsValidRegularExpression(this.Value, "^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*$");
        case "radio", "checkbox", "checkboxlist, multiselect":
            return true;
        default: 
            return true;
    }        

}

// execute custom function if there is any
Validation.prototype.ExecuteCustomFunction = function ()
{
    
    if(!this.CustomFunction || this.CustomFunction == "")
    
        return "";
        
    try
    {
        
        var b = eval(this.CustomFunction + "()");
        return b;
    }
    catch(e) {
        return ErrMsg_ValidType;
    }

}

//if the value is a valid email address
function IsValidEmailAddress(value)
{
    if (value == "")
        return true;
    var regExpr = "^[a-zA-Z0-9\-\._]+\@([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9]{2,4})$";
    return IsValidRegularExpression(value, regExpr)
}

//if the value matched the regular expression
function IsValidRegularExpression(value, regExpr)
{
    var rexp = new RegExp(regExpr);
    return rexp.test(value);
}

// following code shows the date validation
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}

function isDate(dtStr){
	var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)
	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		//alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		//alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		//alert("Please enter a valid day")
		return false
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		//alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		//alert("Please enter a valid date")
		return false
	}
    return true
}