﻿/************************************************
* This file is used on:
* https://slc.dev/application_main_process.asp
* https://ccd.dev/credit-application.aspx
* https://ccd.dev/tax-application.aspx
* https://ritd.dev/tax-application.aspx
* https://ritd.dev/credit-application.aspx
* https://pcal.dev/payday_loan_application.aspx
* https://mypcal.dev/loan-application.aspx
* https://slc.dev/tax_debt_landing.asp
* https://slc.dev/credit_card_landing.asp
* http://t4a.dev/clinicians-corner/testccbusiness.aspx
* DotNetNuke/DesktopModules/payday_add_business/payday_add_business.ascx
************************************************/

/*
* This function is called on submission of the form, it checks if all the form went through the validation.
* @Parameters - 'whichForm': int of which form in the file should be validated, first form has 0 as value.
* @Return - Returns true if the form went through the validation, and false if it did not went through the validation.
*/
function submitForm(whichForm){

    document.ValidationFieldErrors = "";
    document.ValidationFieldValues = "";
    
    //Assigning the form which should be validated to 'form'
    var form = document.getElementsByTagName("form")[whichForm];

        //Validation check of the form
        if(validateFormDatabanq(form, true)){
        //Form went through vaildation, return true.
           
            return true;
        }else{
            //Form did not went through vaildation, return false, and show alert message.
            alert("Please, enter or correct the fields marked with a yellow background.");
	        return false;
	    }
	    
}

/****************************************************
* Rule set for validation and error messages.
* Rules for every different validation test. 
* Includes one label and one error message, if the 
* error messeges not going to be showed put "-".
* Currently the rules are called from the controls' 
* class. 
* 
* For example class="required zip", checks
* first if the field is rewuired and then if it's
* a valid zip code.
* 
* The fields are being validated on blur, currently
* by adding: onblur="javascript: validateFeild(this);"
* 
* TODO: Optically write a function that watches the
* form for on blurs. In that case the onblur tag does
* not have to be added on every field.
****************************************************/

var errMsg = {
	
	//Test that a field has a value.
	required:{
		msg: "-",
		test: function(obj,load) {
		    
		    return obj.value.length > 0;
		   		   
		}
	},
	
	//Test that a field is a valid zip.
	zip: {
		msg: "Enter a valid zip.",
		test: function(obj){
			var numericExpression = /^[0-9]+$/;
			
			if(obj.value.length == 0){
			    return true;
			}else if(obj.value.length !== 5){
				return false;
			}else if(!numericExpression.test(obj.value)){
				return false;
			}else{
				return true;
			}
		}
	},
	
	//Test that a field is valid phone number, and converts the phone number to the form of (123)-456-4567. Only for phone numbers in single textboxes. 
	phone: {
        msg: "Enter a valid phone number.",
        test: function(obj) {
            var m = /(\d{3}).*(\d{3}).*(\d{4})/.exec( obj.value );
			
            if ( m ) obj.value = "(" + m[1] + ") " + m[2] + "-" + m[3];
				
            return !obj.value || m;
        }
    },
	
	//Test that a field only contains numbers, incorrect naming of label. TODO: change the labe name 'phone3' to a more accurate name.
	phone3: {
		msg: "-",
		test: function(obj){
			var numericExpression = /^[0-9]+$/;
			if(!numericExpression.test(obj.value)){
				return false;
			}else{
				return true;
			}
		}
	},
	
	//Test that a field only contains letters.
	text: {
		msg: "Only letters are allowed.",
		test: function(obj){
			/*var numericExpression = /^[a-zA-Z]+$/;
			
			if(obj.value.length == 0){
			    return true;			
			}else if(!numericExpression.test(obj.value)){
				return false;
			}else{
				return true;
			}*/
			return true;
		}
	},
	
	//Test if field if is a valid bank routing number.
	bankRouting: {
		msg: "Enter a valid bank routing number.",
		test: function(obj){
		
		    //Test value: 123123123
		
		    //Code from http://www.brainjar.com/js/validation/default.asp
		    var s = obj.value;
			var i, n, t;

            // First, remove any non-numeric characters.

            t = "";
            if(obj.value.length == 0){
                return true;
            }else{
                for (i = 0; i < s.length; i++) {
                c = parseInt(s.charAt(i), 10);
                if (c >= 0 && c <= 9)
                    t = t + c;
                }

                // Check the length, it should be nine digits.

                if (t.length != 9)
                    return false;

                // Now run through each digit and calculate the total.
                n = 0;
                for (i = 0; i < t.length; i += 3) {
                    n += parseInt(t.charAt(i),     10) * 3
                    +  parseInt(t.charAt(i + 1), 10) * 7
                    +  parseInt(t.charAt(i + 2), 10);
                }

                // If the resulting sum is an even multiple of ten (but not zero),
                // the aba routing number is good.

                if (n != 0 && n % 10 == 0)
                    return true;
                else
                    return false;
    	        }
    	     }
	},
	
	//Test if field has less that a specific value, add for example label: minChar3 to show error message if the field only contains 3 characters.
	minChar: {
		msg: "-",
		test: function(obj){
			var minCharTest = obj.className.indexOf("minChar");
			var limit = obj.className.substr(minCharTest + 7,1);
			if(obj.value.length > limit){
			  return true;
			}else{
			  return false;
		    }
		}
	},
	
	//Non nuke sites
	//Test first pay date field on payday application
	first_payday_test: {
		msg: "-",
		test: function(obj){
		    return validatePayDate(1); 	    	
		}
	},
	
	//Test second pay date field on payday application
	second_payday_test: {
		msg: "-",
		test: function(obj){
		    return validatePayDate(2);		    			
		}
	},	
	
	//Test third pay date field on payday application
	third_payday_test: {
		msg: "-",
		test: function(obj){
		    return validatePayDate(3);		    				
		}
	},
	
	//Test fourth pay date field on payday application
	fourth_payday_test: {
		msg: "-",
		test: function(obj){
		    return validatePayDate(4);		    			
		}
	},	
	
	//Nuke sites
	//Test first pay date field on payday application
	first_payday_test_nuke: {
		msg: "-",
		test: function(obj){
		    return validatePayDateNuke(1); 	    	
		}
	},
	
	//Test second pay date field on payday application
	second_payday_test_nuke: {
		msg: "-",
		test: function(obj){
		    return validatePayDateNuke(2);		    			
		}
	},	
	
	//Test third pay date field on payday application
	third_payday_test_nuke: {
		msg: "-",
		test: function(obj){
		    return validatePayDateNuke(3);		    				
		}
	},
	
	//Test fourth pay date field on payday application
	fourth_payday_test_nuke: {
		msg: "-",
		test: function(obj){
		    return validatePayDateNuke(4);		    			
		}
	},	
	
	//Test url
	url: {
		msg: "Enter a valid website url.",
		test: function(obj){
		    var RegExp = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/; 
		    if(obj.value == ''){
				    return true;
			    }else if(!RegExp.test(obj.value)){
				    return false;
			    }else{
				    return true;
				}		    			
		}
	},	
	
	//Test that a field has a correct e-mail address.		
	email: {
		msg: "Enter a valid email address.",
		test: function(obj){
			var emailExpression = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
			    
			    if(obj.value == ''){
				    return true;
			    }else if(!emailExpression.test(obj.value)){
				    return false;
			    }else{
				    return true;
				}
		}
	}
};

/*******************************
* END RULE SET
*******************************/

/*
* Loop through each and every control in the form, and call validateField function to check validation
* @Return: true or false, if there are errors or no.
*/
function validateFormDatabanq(form, load){
    
    //Boolean variable set to false if there are any errors.
    var valid = true;
	
	//Go through every controll in the form.
	for(var i = 0; i < form.elements.length; i++){
	    
	    //If the control did not pass the validation, set 'valid' to false.
	    if(!validateField(form.elements[i], load)){
	        valid = false;
	    }
	}
  
  	if(valid){
	    return true;
	} else {

	    //Try to log the errors
	    try {
	        document.getElementById('imgError').src = '/common/form_error.aspx?error=Invalid&field=' + escape(document.ValidationFieldErrors) + '&fieldValues=' + escape(document.ValidationFieldValues);
	    } catch (err) {}
	
	    return false;
	}
}

/*
* Validating a specific field
*/
function validateField(elem, load){
	
	//List of all the errors.
	var errors = [];
	//List of errors that should be shown.
	var errorList = [];
	
	//Go through every rule in errMsg.	
	for(var name in errMsg){
	    
	    //Create a regular expression for every rule name.
	    var re = new RegExp("(^|\\s)" + name + "(\\s|$)");
		
		//If class name has value 'minChar' assign it to 'minCharTest'
	    var minCharTest = elem.className.indexOf("minChar");
		    
		    //Check ff the field has a 'minChar' label and erroring
		    if(minCharTest>=0 && !errMsg["minChar"].test(elem, load)){
	            
	            //Add error to errorlist
	            errors.push(errMsg["minChar"].msg);
	            
	        //Check if the class name belongs to the rule set and if it passes the calidation    
	        }else if(re.test(elem.className) && !errMsg[name].test(elem, load)){
	        	
	        	//Add error to errorlist
	            errors.push(errMsg[name].msg);
	            
	            //Check if error message should be showed or not.
	            if(errMsg[name].msg != "-"){
	                //Add error to the show errorlist
	                errorList.push(errMsg[name].msg);
	            }
	       	//Else if the feild passes the validation, hide all errors around the control      	   
		    }else if(re.test(elem.className) && errMsg[name].test(elem, load)){
			    hideErrors(elem);			
		    }
	}
	
	//Check if there are any errors
	if(errors.length){
	    
	    //Show error messages
		showErrors(elem, errors, errorList);
		
	}
	
	//Check if there are any errors
	if (errors.length == 0){
	    //alert("Control: " + elem + " True: " + elem.value);
	    return true;
	}else{
	    //alert("Control: " + elem + " False: " + elem.value);
	    return false;
	}
}

/*
* Hides error messages
*/
function hideErrors(elem){

	elem.style.backgroundColor = "white";
		
	var next = elem.nextSibling;
	
	try{
	if(next.id == 'error_star'){
	    next.style.display = "none";
	}
	
	var next2 = next.nextSibling;
	
	if(next2.id == 'error_star'){
	    next2.style.display = "none";
	}
	}catch(err){
	
	}
	
}

/*
* Shows error messages
*/
function showErrors(elem, errors, errorList){
   
    try{
 	elem.style.backgroundColor = "yellow";
    var next = elem.nextSibling;
   
    var star = document.createElement("span");
    
	star.setAttribute('id', 'error_star');
	
	star.setAttribute('class', 'databanq_validation_error_message');
	star.style.color = "red";
	var br = document.createElement("span");
	
	
	if(errorList.length != 0){
	    var errorMessage = errorList; 
        br = document.createElement("br"); 
   }
	
	var txt = errorList;
	var newT = document.createTextNode(txt);
    star.appendChild(newT);
    next.parentNode.insertBefore(star,next);
    star.parentNode.insertBefore(br,star);
    }catch(err){

    }
    
    try{
        document.ValidationFieldErrors += '|*|' + elem.id;
        document.ValidationFieldValues += '|*|' + document.getElementById(elem.id).value;
    } catch (err) {}
      
}

/****************************
* Payday - pay dates validation
*****************************/

/*
* For non nuke sites
* Validates the pay dates.
* @Parameters - 'which': idicates which form should be validated, 1,2,3 or 4.
* @Return - ture or false.
*/
function validatePayDate(which){
        
    if(which == 1){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = document.getElementById('NEXT_PAY_DATE_day');
        var monthElem = document.getElementById('NEXT_PAY_DATE_month');
        var yearElem = document.getElementById('NEXT_PAY_DATE_year');
        var errorMsgAfter = document.getElementById("first_pd_after");
        var errorMsgBefore = document.getElementById("first_pd_before");
    
    }else if(which == 2){
        
        //Get id's for dropdowns and errror messages divs
        var dayElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_day');
        var monthElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_month');
        var yearElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_year');
        var errorMsgAfter = document.getElementById("second_pd_after");
        var errorMsgBefore = document.getElementById("second_pd_before");
        
        
    }else if(which == 3){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = document.getElementById('NEXT_PAY_DATE_3_day');
        var monthElem = document.getElementById('NEXT_PAY_DATE_3_month');
        var yearElem = document.getElementById('NEXT_PAY_DATE_3_year');
        var errorMsgAfter = document.getElementById("third_pd_after");
        var errorMsgBefore = document.getElementById("third_pd_before");
    
    }else if(which == 4){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = document.getElementById('NEXT_PAY_DATE_4_day');
        var monthElem = document.getElementById('NEXT_PAY_DATE_4_month');
        var yearElem = document.getElementById('NEXT_PAY_DATE_4_year');
        var errorMsgAfter = document.getElementById("fourth_pd_after");
        var errorMsgBefore = document.getElementById("fourth_pd_before");
        
    
    }else{
    
        alert("JavaScript Error");
        return false;
        
    }
    
    return payDateTest(dayElem, monthElem, yearElem, errorMsgAfter, errorMsgBefore, which, true);

}

/*
* For nuke sites
* Validates the pay dates.
* @Parameters - 'which': idicates which form should be validated, 1,2,3 or 4.
* @Return - ture or false.
*/
function validatePayDateNuke(which){
        
    if(which == 1){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = getDayElem(1);
        var monthElem = getMonthElem(1);
        var yearElem = getYearElem(1);
        var errorMsgAfter = document.getElementById("first_pd_after");
        var errorMsgBefore = document.getElementById("first_pd_before");
        
    }else if(which == 2){
        
        //Get id's for dropdowns and errror messages divs
        var dayElem = getDayElem(2);
        var monthElem = getMonthElem(2);
        var yearElem = getYearElem(2);
        var errorMsgAfter = document.getElementById("second_pd_after");
        var errorMsgBefore = document.getElementById("second_pd_before");
        
    }else if(which == 3){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = getDayElem(3);
        var monthElem = getMonthElem(3);
        var yearElem = getYearElem(3);
        var errorMsgAfter = document.getElementById("third_pd_after");
        var errorMsgBefore = document.getElementById("third_pd_before");
    
    }else if(which == 4){
    
        //Get id's for dropdowns and errror messages divs
        var dayElem = getDayElem(4);
        var monthElem = getMonthElem(4);
        var yearElem = getYearElem(4);
        var errorMsgAfter = document.getElementById("fourth_pd_after");
        var errorMsgBefore = document.getElementById("fourth_pd_before");
    
    }else{
    
        alert("JavaScript Error");
        return false;
        
    }
   
    return payDateTest(dayElem, monthElem, yearElem, errorMsgAfter, errorMsgBefore, which, false);

}

/*
* Validates the called pay date, checks if the date is to early or to late. For first pay date the early limit is todays date.
* For rest of them the date must be later then the previous selected date. Right now the same dates are going through, should be one day later or depending
* on what the user selected in 'How often do you get paid'. 
* @Returns - ture or false.
*/
function payDateTest(dayElem, monthElem, yearElem, errorMsgAfter, errorMsgBefore, which, nonNuke){
    
    //Get the amount of days that should be added as top limit.
    var daysToAdd = getDaysToAdd(which);
    
    //Convert the string value of 'monthElem' to integer, an abstract one to get accurate month.   
    var monthValue = (parseInt(monthElem.value, 10))-1;
    
    //Create a new date object.
    var selectedDate = new Date();
    
    //Assigning 'selectedDate' with the selected date.
    selectedDate.setFullYear(yearElem.value,monthValue,dayElem.value);
    
    if(nonNuke){
        var previousSelectedDate = getPreviousSelectedDate(which);
    }else{
        var previousSelectedDate = getPreviousSelectedDateNuke(which);
    }
        
    
    //Check if the selected date is not before todays date (if it's the first pay date) or before the previous selected date if it's second, third or fourth pay date. 
    if(selectedDate < previousSelectedDate){
        
        //Show errors
        showPayDateErrors(dayElem, monthElem, yearElem, "yellow", errorMsgAfter, "block", errorMsgBefore, "none");
       
        return false;
    
    //Check if the selected date is before the upper limit. Which is 31 days after the previous pay dates upper limit or 31 days after todays date if it's for the first pay date.     
    }else if(selectedDate > addDaysFromToday(daysToAdd)){
        
        //Show errors
        showPayDateErrors(dayElem, monthElem, yearElem, "yellow", errorMsgAfter, "none", errorMsgBefore, "block");
        
        return false;
    
    //Else hide error messages for the pay date.        
    }else{
        
        //Hide error messages.
        showPayDateErrors(dayElem, monthElem, yearElem, "white", errorMsgAfter, "none", errorMsgBefore, "none");
        
        return true;
    }
    
}

/*
* Shows or hides error messages for pay dates, background color of the controls and shows or hides the error message under the control.
*/
function showPayDateErrors(dayElem, monthElem, yearElem, bgColor, errorMsgAfter, errorMsgAfterValue, errorMsgBefore, errorMsgBeforeValue){
        
        dayElem.style.backgroundColor = bgColor;
        monthElem.style.backgroundColor = bgColor;
        yearElem.style.backgroundColor = bgColor;
        errorMsgAfter.style.display = errorMsgAfterValue;
        errorMsgBefore.style.display = errorMsgBeforeValue;              
}

/*
* Adds a specific amount of days to todays date.
* @Parameters - 'days': Amount of days to add.
* @Return - Returns a date object with the added days.
*/
function addDaysFromToday(days){

    today=new Date();
    
    //Assign addDays to the amount of days in milli seconds.
    var addDays = days*24*60*60*1000;
    return new Date(today.getTime() + addDays);
}

/*
* Adds days to a date object.
* @Parameters - 'date': A date object to where days going to be added. 'days': abount of days to add.
*/
function addDaysToDate(date, days){

    //Assign addDays to the amount of days in milli seconds.
    var addDays = days*24*60*60*1000;
    return new Date(date.getTime() + addDays);

}

/*
* Gets the previous selected date, if the request is for the first pay date it returns todays date.
* @Parameters - 'which': int of which pay date 1,2,3 or 4.
* @Return - Returns the previous selected date, if the request is for the first pay date it returns todays date. If parameter is out of range it returns todays date.
*/
function getPreviousSelectedDate(which){
    
    if(which == 1){
    
        today = new Date();
        return today.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());
        
    }else if(which == 2){
        
        var dayElem = document.getElementById('NEXT_PAY_DATE_day');
        var monthElem = document.getElementById('NEXT_PAY_DATE_month');
        var yearElem = document.getElementById('NEXT_PAY_DATE_year');
        var monthValue = (parseInt(monthElem.value, 10))-1;
        
        previousPayDate = new Date();      
        
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
                
    }else if(which == 3){
    
        var dayElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_day');
        var monthElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_month');
        var yearElem = document.getElementById('NEXT_AFTER_NEXT_PAY_DATE_year');
        var monthValue = (parseInt(monthElem.value, 10))-1;
                
        previousPayDate = new Date();      
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
        
    }else if(which == 4){
        
        var dayElem = document.getElementById('NEXT_PAY_DATE_3_day');
        var monthElem = document.getElementById('NEXT_PAY_DATE_3_month');
        var yearElem = document.getElementById('NEXT_PAY_DATE_3_year');
        var monthValue = (parseInt(monthElem.value, 10))-1;
        
        previousPayDate = new Date();      
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
        
    }else{
    
        today = new Date();
        return today.getFullYear();
        
    }
}

function getPreviousSelectedDateNuke(which){
   
    if(which == 1){
    
        today = new Date();
        return today.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());
        
    }else if(which == 2){
        
        var dayElem = getDayElem(1);
        var monthElem = getMonthElem(1);
        var yearElem = getYearElem(1);
        var monthValue = (parseInt(monthElem.value, 10))-1;
        
        previousPayDate = new Date();      
        
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
                
    }else if(which == 3){
    
        var dayElem = getDayElem(2);
        var monthElem = getMonthElem(2);
        var yearElem = getYearElem(2);
        var monthValue = (parseInt(monthElem.value, 10))-1;
                
        previousPayDate = new Date();      
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
        
    }else if(which == 4){
        
        var dayElem = getDayElem(3);
        var monthElem = getMonthElem(3);
        var yearElem = getYearElem(3);
        var monthValue = (parseInt(monthElem.value, 10))-1;
        
        previousPayDate = new Date();      
        return previousPayDate.setFullYear(yearElem.value, monthValue, dayElem.value);
        
    }else{
    
        today = new Date();
        return today.getFullYear();
        
    }
}

/*
* To get the upper limit 31 days adds for every pay date
* @Parameters - 'which': int for which pay date, Allowd values 1,2,3 or 4.
* @Return - Returns days to add, if parameter is out of range it returns 0.
*/
function getDaysToAdd(which){

    if(which == 1){
        return 32;
    }else if(which == 2){
        return 63;
    }else if(which == 3){
        return 94;
    }else if(which == 4){
        return 125;
    }else{
        return 0;
    }
}

/*
* Gets todays day, month or year.
* @Parameters - 'type': String 'day', string 'month', string 'year'
* @Return - Returns todays date, month or year, if parameter is incorrect it returns null.
*/
function getTodays(type){
    
    today=new Date();
    
    if(type == 'day'){
        return today.getDate();
    }else if(type == 'month'){
        return today.getMonth()+1;
    }else if(type == 'year'){
        return today.getFullYear();
    }else{
        return null;
    }
}
