﻿var ErrorContainer_Suffix = "_err";
var Container_Suffix = "_ctr";
var ErrMsg_Required = "[FIELDLABEL] is required.";
var ErrMsg_ValidType = "Ingresa tu [FIELDLABEL].";
var ErrMsg_ValidMinLength = "Ingresa tu código postal";
var ErrMsg_ValidMaxLength = "The value for [FIELDLABEL] exceeded the maximum number of allowable characters.";
var ErrMsg_ValidMinValueLength = "The selection has less than the minimum number of values for [FIELDLABEL].";
var ErrMsg_ValidMaxValueLength = "The selection exceeded the maximum number of values for [FIELDLABEL].";
var ErrMsg_EmailVerify = "Please verify your e-mail address correctly."
var ErrMsg_PasswordVerify = "Please verify your password correctly."
var DefaultErrorMessage = "Lamentablemente hay problemas con su envío. Corríjalos y vuelva a intentarlo.";


//Switch on/off debug alerts.
var DEBUG_ALERTS_ON = false; 
function valert(arg) {
	if (DEBUG_ALERTS_ON) { alert(arg); }
	else { return; }
}


/**
 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, label, value, type, typemsg, required, requiredmsg, minlen, minlenmsg, maxlen, maxlenmsg, regex, errmsg, customfunc) 
{
    this.Name = name;
    this.Label = label;
    this.Value = value;
    this.Type = type;
    this.TypeMessage = typemsg;
    this.Required = required;
    this.RequiredMessage = requiredmsg;
    this.MinimumLength = minlen;
    this.MinimumLengthMsg = minlenmsg;
    this.MaximumLength = maxlen;
    this.MaximumLengthMsg = maxlenmsg;
    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, label, message, defaultmsg)
{
    var errorDivId = containerId + ErrorContainer_Suffix;
    var errDiv = document.getElementById(errorDivId);     

    if (message == "") {
        message = defaultmsg;
        message = message.replace(/\[FIELDLABEL\]/gi, label);
    }
            
    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()
{


valert('0. starting validation...');

    setMainErrorMessage("");
    var bSuccess = true;
    if(validations)
    {

	valert('1.' + bSuccess);

        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()) 
            {
            
					valert('required error:' + questionId);
            
                setErrorMessage(questionId, validations[i].Label, validations[i].RequiredMessage, ErrMsg_Required);
                bSuccess = false;
                continue; 
            }

            if (!validations[i].HasValidType())    
            {
            
            valert('invalid type error:' + questionId);
            
                setErrorMessage(questionId, validations[i].Label, validations[i].TypeMessage, ErrMsg_ValidType);
                bSuccess = false;
                continue;
            }
            
            if (!validations[i].ExecuteExpression())
            {
            
             valert('invalid ExecuteExpression error:' + questionId);
            
                setErrorMessage(questionId, validations[i].Label, validations[i].ErrorMessage, "");
                bSuccess = false;
                continue;
            }
           
            if (!validations[i].HasValidMinLength())
            {
            
            
            valert('invalid HasValidMinLength error:' + questionId);
            
                if (validations[i].Type.toLowerCase() == "checkboxlist" ||
                    validations[i].Type.toLowerCase() == "multiselect") 
                    setErrorMessage(questionId, validations[i].Label, validations[i].MinimumLengthMsg, ErrMsg_ValidMinValueLength);
                else
                    setErrorMessage(questionId, validations[i].Label, validations[i].MinimumLengthMsg, ErrMsg_ValidMinLength);
                bSuccess = false;
                continue;
            }

            if (!validations[i].HasValidMaxLength())
            {
            
            
            valert('invalid HasValidMaxLength error:' + questionId);
            
                if (validations[i].Type.toLowerCase() == "checkboxlist" ||
                    validations[i].Type.toLowerCase() == "multiselect") 
                    setErrorMessage(questionId, validations[i].Label, validations[i].MaximumLengthMsg, ErrMsg_ValidMaxValueLength);
                else
                    setErrorMessage(questionId, validations[i].Label, validations[i].MaximumLengthMsg, ErrMsg_ValidMaxLength);
                bSuccess = false;
                continue;
            }
            
            
            var message = validations[i].ExecuteCustomFunction();
            if (message != "") 
            {
            
            valert('invalid ExecuteCustomFunction error:' + questionId);
            
                setErrorMessage(questionId, validations[i].Label, message, "");
                bSuccess = false;
                continue;
            }
        }
    }
    
    if (!bSuccess)
    {
        setMainErrorMessage(DefaultErrorMessage);
        window.location.href = "#top";
    }
    
    
    valert('55.' + bSuccess);
    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;


valert('type is... ' + this.Type.toLowerCase());

    switch(this.Type.toLowerCase())
    {
    
        case "alpha":
            return IsValidRegularExpression(this.Value, "^[A-Za-z ]+$");
        case "numeric":
            return IsNumeric(this.Value);
        case "alphanumeric":
            return IsValidRegularExpression(this.Value,"^[A-Za-z0-9 ]+$");
        case "phone":
            return IsPhone(this.Value);
        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 IsUrl(this.Value);
        case "radio", "checkbox", "checkboxlist, multiselect":
            return true;
        default: 
			//alert('default state reached! ' + this.Type.toLowerCase());
            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;
    }

}


function IsUrl(value)
{
    value = value.toLowerCase();
    if (value.indexOf("http://")<0 && 
        value.indexOf("https://")<0 && 
        value.indexOf("ftp://")<0)
        value = "http://" + value 
    
    return IsValidRegularExpression(value, "^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*$");
}

function IsNumeric(value)
{
    return IsValidRegularExpression(value,"^[0-9]+$");
}

function IsPhone(value)
{
    //strip out acceptable non-numeric characters
    var stripped = value.replace(/[\(\)\.\-\ ]/g, ''); 
    if (IsNumeric(stripped) && stripped.length == 10 )
       return true;
    return false;
}


//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) {
	var arr = [];
	for (var i = 1; i <= n; i++) {
		arr[i] = 31;
		if (i==4 || i==6 || i==9 || i==11) {
			arr[i] = 30;
		}
		if (i==2) {
			arr[i] = 29;
		}
   } 
   return arr;
}
//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;
//		}
//   } 
//   
//   valert('DaysArray: ' + this);
//   
//   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;
}


