//Validation function written by Adam Smith April 2009. When called the function loops through all elements on a named form. 
//The valuetype attribute is read on the form and depending on the value, different validation functions are called

var sMessage = '';
	function trim(str, chars) {
		return ltrim(rtrim(str, chars), chars);
	}
	 
	function ltrim(str, chars) {
		chars = chars || "\\s";
		return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
	}
	 
	function rtrim(str, chars) {
		chars = chars || "\\s";
		return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
	}
	function IsNumeric(sText)
	//Function to check if the named element is IsNumeric. Loop through each element and compare against the validChars field. If the fields are within this variable the number is valid. If not it isn't
	{
		var ValidChars = '0123456789.';
		var IsNumber=true;
		var Char;
		
		for (i = 0; i < sText.length && IsNumber == true; i++) 
		{ 
			Char = sText.charAt(i); 
			if (ValidChars.indexOf(Char) == -1) 
			{
				IsNumber = false;
			}
		}
		return IsNumber;
	}
	var dtCh= "/";
	var minYear=1900;
	var maxYear=2100;

	function isInteger(s){
		//Function to check if the named element is an integer. Check each element is between 0 and 9. If so then the value is valid, if not then it isnt.
		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 CTisDate(dtStr){
			//Function to check if the date passed in is valid
		var daysInMonth = DaysArray(12)
		var pos1=dtStr.indexOf(dtCh)
		var pos2=dtStr.indexOf(dtCh,pos1+1)
		var strDay=dtStr.substring(0,pos1)
		var strMonth=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){
			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
	}
	function validateNumber(value, field, iIsValid, strFriendlyName){
		//Function to validate a number. Run the IsNumeric function. If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
		if(value != ''){
			if(IsNumeric(value)){
				iIsValid += 0;
				hideError(field);
			}else{
				iIsValid += 1;
				sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';
				showError(field);
			}
		}else{
			/*iIsValid += 1;
			sMessage += '- ' + field + ' value is incorrect<br />';
			showError(field);*/
			iIsValid += 0;
			hideError(field);
		}
		return iIsValid;		
	}
		function validateBlankNumber(value, field, iIsValid, strFriendlyName){
		//Function to validate a number. Run the IsNumeric function. If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
		if(value != ''){
			if(IsNumeric(value)){
				iIsValid += 0;
				hideError(field);
			}else{
				iIsValid += 1;
				sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';
				showError(field);
			}
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' is blank</li>';
			showError(field);
		}
		return iIsValid;		
	}
	function validateBlankNumber_Zero(value, field, iIsValid, strFriendlyName){
		//Function to validate a number. Run the IsNumeric function. If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
		if(value != '' && value != 0){
			if(IsNumeric(value)){
				iIsValid += 0;
				hideError(field);
			}else{
				iIsValid += 1;
				sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';
				showError(field);
			}
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' is blank</li>';
			showError(field);
		}
		return iIsValid;		
	}
	function validateEmail(value, field, iIsValid, strFriendlyName){
		//Function to validate email addresses. Run a Regex validation against the value. If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
		var emailRegex = /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/;
		if(emailRegex.test(value)){
			iIsValid += 0;
			hideError(field);			
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';
			showError(field);
		}
		return iIsValid;	
	}
	function validateVatNo(value, field, iIsValid, strFriendlyName){
		//Function to validate a UK VAT Number. Run a Regex validation against the field.  If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
		var vatNoRegex = /^([GB])*(([1-9]\d{8})|([1-9]\d{11}))$/;
		if(vatNoRegex.test(value)){
			iIsValid += 0;
			hideError(field);			
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';		
			showError(field);			
		}
		return iIsValid;
	}
	//Function to validate a date. Uses the CTisDate function.  If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
	function validateDate(value, field, iIsValid, strFriendlyName){
		if(CTisDate(value)){
			iIsValid += 0;
			hideError(field);			
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';			
			showError(field);			
		}
		return iIsValid;
	}
	function validate_Split_Date(value, field, iIsValid, strFriendlyName,strField_MainPart){
		if(CTisDate(value)){
		    var iYear = document.getElementById(strField_MainPart + '_Y').value;
		    var iMonth = document.getElementById(strField_MainPart + '_M').value; 
		    var iDay = document.getElementById(strField_MainPart + '_D').value;
		    var dNow = new Date();
		    var dValAgainst = new Date(dNow.getFullYear(),dNow.getMonth(),dNow.getDate());
		    var dCheckDate = new Date(iYear, (iMonth - 1), iDay);
		    if (Date.parse(dCheckDate) >= Date.parse(dValAgainst)){
			    iIsValid += 0;
			    hideError(strField_MainPart + '_D');			
                hideError(strField_MainPart + '_M');
                hideError(strField_MainPart + '_Y');
            }else{
            	iIsValid += 1;
			    sMessage += '<li>' + strFriendlyName + ' must be in the future</li>';			
			    showError(strField_MainPart + '_D');
			    showError(strField_MainPart + '_M');			
                showError(strField_MainPart + '_Y');
            }			
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' is not a valid date</li>';			
			showError(strField_MainPart + '_D');
			showError(strField_MainPart + '_M');			
            showError(strField_MainPart + '_Y');
            			
		}
		return iIsValid;
	}
    function validate_Split_Date_Range(value, field, iIsValid, strFriendlyName, strFriendlyName2, strField_MainPart, strCheckAgainst){
		if(CTisDate(value)){
		    var iYear = document.getElementById(strField_MainPart + '_Y').value;
		    var iMonth = document.getElementById(strField_MainPart + '_M').value; 
		    var iDay = document.getElementById(strField_MainPart + '_D').value;
		    
		    var iYear_2 = document.getElementById(strCheckAgainst + '_Y').value;
		    var iMonth_2 = document.getElementById(strCheckAgainst + '_M').value; 
		    var iDay_2 = document.getElementById(strCheckAgainst + '_D').value;
		    
		    var dNow = new Date();
		    var dValAgainst = new Date(dNow.getFullYear(),dNow.getMonth(),dNow.getDate());
		    var dCheckDate = new Date(iYear, (iMonth - 1), iDay);
		    var dCheckAgainst = new Date(iYear_2, (iMonth_2 - 1), iDay_2);
		    if (Date.parse(dCheckDate) >= Date.parse(dValAgainst)){
			    if (Date.parse(dCheckAgainst) <= Date.parse(dCheckDate)){
			        iIsValid += 1;
			        sMessage += '<li>' + strFriendlyName + ' must be before ' + strFriendlyName2 + '</li>';			
			        showError(strField_MainPart + '_D');
			        showError(strField_MainPart + '_M');			
                    showError(strField_MainPart + '_Y');
			        showError(strCheckAgainst + '_D');
			        showError(strCheckAgainst + '_M');			
                    showError(strCheckAgainst + '_Y');                    
			    } else {
			        iIsValid += 0;
			        hideError(strField_MainPart + '_D');
			        hideError(strField_MainPart + '_M');			
                    hideError(strField_MainPart + '_Y');
                    hideError(strCheckAgainst + '_D');			
                    hideError(strCheckAgainst + '_M');
                    hideError(strCheckAgainst + '_Y');
                }
            }else{
            	iIsValid += 1;
			    sMessage += '<li>' + strFriendlyName + ' must be in the future</li>';			
			    showError(strField_MainPart + '_D');
			    showError(strField_MainPart + '_M');			
                showError(strField_MainPart + '_Y');
            }			
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' is not a valid date</li>';			
			showError(strField_MainPart + '_D');
			showError(strField_MainPart + '_M');			
            showError(strField_MainPart + '_Y');
            			
		}
		return iIsValid;
	}	
	function validateBlankDate(value, field, iIsValid, strFriendlyName){
			if(value != ''){
				if(CTisDate(value)){
					iIsValid += 0;
					hideError(field);			
				}else{
					iIsValid += 1;
					sMessage += '<li>' + strFriendlyName + ' value is incorrect</li>';			
					showError(field);			
				}
			}else{
				iIsValid += 0;
				hideError(field);	
			}
			return iIsValid;
	}	
	//Function to validate a blank field.  If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
	function validateBlank(value, field, iIsValid, strFriendlyName){
		if(value != ''){
			iIsValid += 0;
			hideError(field);
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' cannot be blank</li>';
			showError(field);
		}
		return iIsValid;
	}
	//Function to validate a blank dropdown field. Check if the value is -.  If valid iIsValid is true return 0 and hide the error field, if not iIsValid is false, the field is highlighted as in error and a validation message is set
	function validateBlank_DropDown(value, field, iIsValid, strFriendlyName){
		if (value != '0'){
			iIsValid += 0;
			hideError(field);
		}else{
			iIsValid += 1;
			sMessage += '<li>' + strFriendlyName + ' has not been selected</li>';
			showError(field);
		}
		return iIsValid;
	}
	function validateRejectestimate(value, field, iIsValid, strFriendlyName){
	    
	    if (document.getElementById(field).checked == true && (document.getElementById('Estimate_Notes_Client').value == null || document.getElementById('Estimate_Notes_Client').value == '')){
	        iIsValid += 1;
	        sMessage += '<li>You must enter client notes when rejecting an estimate</li>';
            showError(field);
	    }else{
	        iIsValid += 0;
	        hideError(field);	        
	    }
	    return iIsValid;
	}
	function validateCreateTicket(value, field, iIsValid, strFriendlyName){
    	if(document.getElementById('chk_CreateTicket').checked == true || document.getElementById('chk_SendToClient').checked == true){
	        if(document.getElementById('chk_CreateTicket').checked == true && document.getElementById('chk_SendToClient').checked == true){    
	            iIsValid += 0;
	            hideError(field);	 
	        }else{
	            iIsValid += 1;
	            if(sMessage.indexOf('<li>You must have both create ticket and send to client selected</li>') == -1){
	                sMessage += '<li>You must have both create ticket and send to client selected</li>';
	            }
                
                showError(field);
	        }
	    } else {
	        iIsValid += 0;
	        hideError(field);	
	    }
	    return iIsValid;
    }
	function showError(field){
		//Show error function. Highlight the selected field in Red, and draw a red border around it.
		var el = document.getElementById(field)
		el.style.backgroundColor = '#FFDFE1';
		el.style.border = '2px solid #FF0000';
	}
	function hideError(field){
        //alert(field);
		//Hide error function. Set the background of the field to 0 and hide the border.
		var el = document.getElementById(field)
		el.style.backgroundColor = '#FFFFFF';
		el.style.border = '1px solid #bbbbbb';
	}
	function validateForm(form){
			//ValidateForm function.
	var iIsValid = 0;
	var strName = '';
	var strValue = '';
	var strType = '';
	var strFriendlyName = '';
	var strFriendlyName2 = '';
	var strCheckAgainst = '';
	var elem = document.getElementById(form).elements;
	for(var i = 0; i < elem.length; i++)
		//Loop through each element on the entered form
	{
		
		strType = elem[i].getAttribute('valuetype');
			//Get the value type (Read the valuetype attribute set on the form)
		strName = elem[i].name;
			//Get the name of the field
		strValue = trim(elem[i].value, " ");
			//Get the value of the field
		strFieldType = elem[i].type;
			//Get the field type
		strFriendlyName = elem[i].getAttribute('friendly_name');
		    //Get the friendly name for the field
		strFriendlyName2 = elem[i].getAttribute('friendly_name_part2');
		    //Get the second part of the friendly name
		strCheckAgainst = elem[i].getAttribute('check_against');
		    //Get the check against value
		if(strName != 'submit' && strFieldType != 'hidden' && strFieldType != 'button'){
			//alert('Element' + elem[i] + ' name: ' + elem[i].name + ' Field type: ' + elem[i].type + ' Friendly name: ' + strFriendlyName);
			//Run the below code assuming the name of the element isnt submit, and the type of the element isnt hidden.
			strType = elem[i].attributes.valuetype.value;
			    if(strType == 'number'){
					//Type is number, set iIsValid to the value returned from the validateNumber function.
					iIsValid = validateNumber(strValue, strName, iIsValid, strFriendlyName);
				}else if(strType == 'blank_number'){
					//Type is number, set iIsValid to the value returned from the validateNumber function.
					iIsValid = validateBlankNumber(strValue, strName, iIsValid, strFriendlyName);
				}else if(strType == 'blank_number_zero'){
				    //Type is number and cannot be zero
				    iIsValid = validateBlankNumber_Zero(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'email'){	
					//Type is email. set iIsValid to the value returned from the validateEmail function.
					iIsValid = validateEmail(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'vatno'){
					//Type is vatno. Set iIsValid to the value returned from the validateVatNo function.
					iIsValid = validateVatNo(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'date'){
					//Type is date. Set iIsValid to the value returned from the validateDate function.
					iIsValid = validateDate(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'blank'){
					//Type is blank. Set iIsValid to the value returned from the validateBlank function.
					iIsValid = validateBlank(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'blank_select'){
					//Type is blank_select. Set iIsvalid to the value returned from the validateBlank_DropDown function.
					iIsValid = validateBlank_DropDown(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'blank_Date'){
						//Type is blank_Date. Set iIsvalid to the value returned from the validateBlankDate function.
					iIsValid = validateBlankDate(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'reject_estimate'){
				    //Type is reject estiamte
				    iIsValid = validateRejectestimate(strValue, strName, iIsValid, strFriendlyName);				
				}else if (strType =='create_ticket'){
				    iIsValid = validateCreateTicket(strValue, strName, iIsValid, strFriendlyName);
				}else if (strType == 'blank_Date_Time'){
						//Type is blank_Date_Time. Set iIsvalid to the value returned from the validateBlankDate function.
						//Function is used to validate a date which will also have a time (Split on space)
					var arrValName = '';
					var sValName = '';
					arrValName = strValue.split(' ' );
					sValName = arrValName[0];
					iIsValid = validateBlankDate(sValName, strName, iIsValid, strFriendlyName);
				}else if (strType == 'Date_Time'){
					//Type is Date_Time. Set iIsvalid to the value returned from the validateBlankDate function.
					var arrValName = '';
					var sValName = '';
					arrValName = strValue.split(' ' );
					sValName = arrValName[0];
					iIsValid = validateDate(sValName, strName, iIsValid, strFriendlyName);
				}else if (strType == 'validate_date_Dropdown'){
			        var strField_MainPart = elem[i].getAttribute('ID_MainPart');
			        var oDay_Field = document.getElementById(strField_MainPart + '_D');
			        var oMonth_Field = document.getElementById(strField_MainPart + '_M');
			        var oYear_Field = document.getElementById(strField_MainPart + '_Y');
			        var iDay = oDay_Field.value;
			        var iMonth = oMonth_Field.value;
			        var iYear = oYear_Field.value;
			        var sDate = iDay + '/' + iMonth + '/' + iYear
			        
			        if(sDate == '0/0/0'){
			       	    iIsValid += 1;
			            sMessage += '<li>' + strFriendlyName + ' cannot be blank</li>';
			            showError(strField_MainPart + '_D'); 
			            showError(strField_MainPart + '_M'); 
			            showError(strField_MainPart + '_Y'); 
			        }else{
    			        iIsValid = validate_Split_Date(sDate, strName, iIsValid, strFriendlyName, strField_MainPart);  
                    }
			    }else if (strType == 'validate_date_Dropdown_range'){
			        var strField_MainPart = elem[i].getAttribute('ID_MainPart');
		            var oDay_Field = document.getElementById(strField_MainPart + '_D');
		            var oMonth_Field = document.getElementById(strField_MainPart + '_M');
		            var oYear_Field = document.getElementById(strField_MainPart + '_Y');
		            var iDay = oDay_Field.value;
		            var iMonth = oMonth_Field.value;
		            var iYear = oYear_Field.value;
		            var sDate = iDay + '/' + iMonth + '/' + iYear
		            if(sDate == '0/0/0'){
		       	        iIsValid += 1;
		                sMessage += '<li>' +  strFriendlyName + ' cannot be blank</li>';
		                showError(strField_MainPart + '_D'); 
		                showError(strField_MainPart + '_M'); 
		                showError(strField_MainPart + '_Y'); 
		            }else{
			            iIsValid = validate_Split_Date_Range(sDate, strName, iIsValid, strFriendlyName, strFriendlyName2, strField_MainPart, strCheckAgainst);  
                    }
			    }
			}
			strName = '';
			strValue = '';
			strType = '';
	} 
	if (iIsValid != 0){
		//There are errors on the form. Set the Val_Summary div to visible, and display the error message, along with sMessage which is declared by the validation functions.
		document.getElementById('Val_SummaryHolder').style.display = 'block';
		document.getElementById('Val_Summary').style.display = 'block';
		document.getElementById('Val_Summary').innerHTML = '';
		document.getElementById('Val_Summary').innerHTML = document.getElementById('Val_Summary').innerHTML +'This page has the following errors:<br /><ul>'+ sMessage + '</ul>';
		window.location.hash="Error";
		sMessage = '';
		return false;
		
}else{
		//There are no errors, return true
		return true;
	}
}
