/*INSTRUCTIONS FOR FORM CONSTRUCTION

1.	<form> tag has to have both name and id attributes 

2.	Submit Button: 
	<input
		type="button" 
		value="SUBMIT" 
		class="inputbutton" 
		onclick="javascript: validateForm(formName);"
	>


3.	Each form element (field) that requires validation needs to have CUSTOM (that do not exist in DOM) attributes.
 These attributes are 
static and hold variable/value pairs that are used but JS script. New attributes (the ones that are not listed below) need to have new 
corresponding functions and variables in the script.

	Currently used attributes:
		a.	"required" ::  values: "yes" | "no". Lack of the attribute is treated as "no".
		EXAMPLE: required="yes"
		b.	"syntaxtype" :: values: 
		i.	"email" :: eMail;
		ii.	"zipcodeus" :: US convention;
		iii.	"phoneus" :: for the US phone;
		iiii. unique : Checking value from form against value stored in database for uniqueness. 
		               If this form field is prepopulated from DB atrribute unique must come in pair with attribute storeddValue.
	    v.    storedValue : the value that is stored in database. Comes in pair with unique. (for not prepopulated form not required)
	EXAMPLE: syntaxtype="email"

	The values are prefixes to the existing functions. EXAMPLE: email attribute is a prefix to emailValidate() function.
	(Foreign postal codes and phones are not validated at present.)

	c.	"maxlength" :: values: any integer :: optional, redundant to the existing browser DOM attribute;
		EXAMPLE: maxlength="64";
	d.	"minlength" ::  values: any integer;
		EXAMPLE: minlength ="5";
	e.	"allowedchars" :: values: var name that holds a string with the allowed characters that can be used in the field. The variable needs to be declared and assigned value to in the head of the script. The value of this attribute is CASE SENSITIVE and must match exactly JS variable name (JS enforcement).
		EXAMPLE: 
		In JS head:
		var phoneAllowed = '0123456789-';
		Input attribute:
		Allowedchars=" phoneAllowed"
	f.	"buttongroup" :: value: the same name as the checkbuttons are given to. Grouping is accomplished by name.
	g.	"mincheck" :: value: integer. Describes how many buttons in a group must be checked minimum.
	h.	"maxcheck" :: value: integer. Describes how many buttons in a group must be checked maximum.

EXAMPLES OF FORM ELEMENTS CONSTRUCTIONS:

<input 
	type="text" 
	name="phone2" 
	id="phone2" 
	value="" 
	size="20" 
	class="inputtext"
	required="no"
	label="Phone 2"
	syntaxtype="phoneus"
	maxlength="12"
>

<input 
	type="text" 
	name="address1" 
	id="address1" 
	value="" 
	size="60" 
	class="inputtext"
	required="no"
	allowedchars="addressAllowed"
	label="Address 1"
	maxlength="32"
>

CODE CHANGES

*/



//set global variables
//allowed characters vars
//first position contains string of allowed characters, second -- error message
var alpnumericalAllowed = new Array(2); 
	alpnumericalAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz';  
	alpnumericalAllowed[1] = 'allowed characters are NUMBERS and LETTERS only.';
var alpnumericalspaceAllowed = new Array(2); 
	alpnumericalspaceAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz ';  
	alpnumericalspaceAllowed[1] = 'allowed characters are NUMBERS, LETTERS, and SPACES only.';
var alphanumericspaceotherchar = new Array(2); 
	alphanumericspaceotherchar[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz,-_.& \'';  
	alphanumericspaceotherchar[1] = 'allowed characters are NUMBERS, LETTERS, and SPACES only.';
var nameAllowed = new Array(2); 
	nameAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz.,-& ';  
	nameAllowed[1] = 'allowed characters are NUMBERS, LETTERS, and SPACES only.';
var mailSubject = new Array(2); 
	mailSubject[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz-:;"@$&()! ';  
	mailSubject[1] = 'allowed characters are NUMBERS, LETTERS, and SPACES only.';
var companyAllowed = new Array(2); 
	companyAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz,-.& '; 
	companyAllowed[1] = 'allowed characters are NUMBERS abd LETTERS only.';
var addressAllowed = new Array(2); 
	addressAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz-.,& ';  
	addressAllowed[1] = 'allowed characters are NUMBERS, LETTERS, and "-" only.';
var alphabethAllowed = new Array(2); 
	alphabethAllowed[0] = 'ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz -';
	alphabethAllowed[1] = 'allowed characters are LETTERS and SPACES only.';
var zipusAllowed = new Array(2); 
	zipusAllowed[0] = '0123456789-'; 
	zipusAllowed[1] = 'allowed characters are NUMBERS and DASH only.';
var emailAllowed = new Array(2);
	emailAllowed[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz.@_-';
	emailAllowed[1] = 'allowed characters are LETTERS, NUMBERS, "@", ".", "_" and "-" only.';
var phoneusAllowed = new Array(2);
	phoneusAllowed[0] = '0123456789-';
	phoneusAllowed[1] = 'allowed characters are NUMBERS and DASH only.';
var floatAllowed = new Array(2);
	floatAllowed[0] = '\.0123456789';
	floatAllowed[1] = 'allowed characters are NUMBERS and PERIOD only.';
var numbersAllowed = new Array(2);
	numbersAllowed[0] = '0123456789';
	numbersAllowed[1] = 'allowed characters are NUMBERS only.';
var noquotesnospace = new Array(2);
	noquotesnospace[0] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz,-_.&:;?/><][{}+=)(*^%$#@!~`';
	noquotesnospace[1] = 'Quotes, double quotes, pipe and space are not allowed.';
	
//vars that hold objects parameters
var currentElement;
var currentElementId;
var currentElementObject;
var currentElementValue;
var currentElementAttributes;
var currentForm;
var currentLabel;
var cityField;
var stateField;
var elementsArray = new Array();
var buttonGroupObjects = new Array();

var errorvalue = true;
var formApprove = true;
var HTTPrequestsent = false;  //true if we send HTTPrequest before submitting form
//the follwoing is used to turn submission ON/OFF
//reason: validation may be called befor other functions are called
//in which case submit() is called from those functions (or not, id AJAX is used)
// to turn submission OFF -- set do submitSwitch = false; in your function;

var submitSwitch = true;
//Variable us is true if selected country is US. Used for automatic zipcode populated when us=true (file regVerify.js function getZip)
var us = true;
//detect browser
var browserName=navigator.appName;

//errors
var errorArray = new Array(2);
	//holds objects
	errorArray[0] = new Array();
	//holds errors
	errorArray[1] = new Array();

//this is to make sure that syntax validation functions exist -- in case someone uses a function that does not exist
//the values are prefixes that are used in corresponding syntax validation functions
var syntaxFunctions = new Array('email','phoneus','zipcodeus','matchto','selectall','float','date','zipcodecanada');

//array of form elements CUSTOM attributes for validations
var validationAttributes = new Array('required','allowedchars','syntaxtype','buttongroup','minlength','selectall','matchto','positive');

//allowed file extensions for upload
var valFiles = new Array('mpeg','mpeg4','mpeg3','wmv');
//used to load zipcode

function zipcodeLoader(zip,field,formID,city,state,flag){

	field.style.borderColor = '';
	field.style.color = '';
	currentForm = formID;
	cityField = city;
	stateField = state;
	//alert(formID);
	if(zip.toString().length == 5){
	
		currentElementValue = zip;
		err = zipcodeusValidate();
		
		if(trim(err) == ''){
		//alert();
			setSrc = "/javascripts/ziploader.cfm?zipCode5=" + zip;
			document.getElementById('zipFrame').src = setSrc;
			
		}
		
		else{
			field.style.borderColor = 'red';
			field.style.color = 'red';
			alert('Only Digits Can Be Used In Zip Code Field!');
		}

	}
	
	else{
		currentForm.elements[cityField.id].value = '';
		selOptions = currentForm.elements[stateField.id].options;
		for(i=0; i< selOptions.length; i++){
		if(i == 0){
		selOptions[i].selected = true;
		}
		else{
		selOptions[i].selected = false;
		}
		}
		//alert();
	}

}

function populateZipcode(stateName,queCity,queState){
	//populate fields
	selOptions = currentForm.elements[stateField.id].options;
	if(stateName != false){
		currentForm.elements[cityField.id].value = queCity;
		
		
		//alert(selOptions.length);
		//figure if state value is numerical or abbreviation
		//done because some forms use integers as option values, some -- state abbreviations
		selectState = 0;
		dType = parseInt(selOptions[selOptions.length/2].value).toString();
		//alert(dType == 'NaN');
		if(dType != "NaN"){
			//alert('number');
			selectState = queState;
		}
		
		else{
			//alert('string');
			selectState = stateName;
		}
		
		//select the state
		
		for(i=0; i< selOptions.length; i++){
			if(selOptions[i].value == selectState){
				selOptions[i].selected = true;
			}
			else{
				selOptions[i].selected = false;
			}
		}
		
		
		//alert(stateName + ' ' + queCity + ' ' + queState);
	}
	
	else{
		currentForm.elements[cityField.id].value = '';
		for(i=0; i< selOptions.length; i++){
			if(i == 0){
				selOptions[i].selected = true;
			}
			else{
				selOptions[i].selected = false;
			}
		}
		
	}
	
}


//restore defaul styles of the fields
function restoreStyles(){
	for(i=0;i<currentForm.length;i++){
		
		currentForm[i].style.borderColor = '';
		currentForm[i].style.color = '';
	}
}

//restore defaul styles of the fields
function restoreThisStyle(el){
		el.style.borderColor = '';
		el.style.color = '';

}
//highlights fields if there are errors in a particular field
function highlightFields(){
	currentElement.style.borderColor = 'red';
	currentElement.style.color = 'red';
}

//compose error

function composeError(txt){

	arLen = errorArray[0].length;
	if(currentElementObject.id == 'stationList'){
		currentElementObject = document.getElementById('callband');
	
	}
	errorArray[0][arLen] = currentElementObject;
	errorArray[1][arLen] = '"'+currentLabel + '" ' +txt;
}

//float validation
function floatValidate(){
	mString = trim(currentElementValue);
	if(isNaN(mString) || mString.length == 0){
		var errCheck = "is not a float.";
		errorvalue = false;
	 	composeError(errCheck);
	}
}

//Email validation
        function emailValidate(){
		
		mString = trim(currentElementValue);
		if(mString != ''){
            var errCheck = '';
            var at= '@';
            var dot= '.';
            var lat= mString.indexOf(at);
            var lstr= mString.length;
            var ldot= mString.indexOf(dot);
            var disallowedChars = '~`!#$%^&*()=+ ;?|\\/><,:;{}[]"';
			errorvalue = true;
            if (mString.indexOf(at)==-1){
			   errCheck = errCheck + '- "@" is missing. ';
			   errorvalue = false;
            }
            if (mString.indexOf(at)==0 || mString.indexOf(at)==lstr-1){
				if (errorvalue)
               {	errCheck = errCheck + '- Character "@" cannot be the first or the last character. ';
			   		errorvalue = false;
				}			   
            }
			
			if (mString.indexOf(dot)==-1){
               if (errorvalue)
               {	 errCheck = errCheck + '- "." is missing. ';
				   errorvalue = false;
				}		
            }
			
			
            if (mString.indexOf(dot)==0 || mString.indexOf(dot)== lstr-1){
				if (errorvalue)
               {	errCheck = errCheck + '- "." cannot be the first or the last character. ';
			 		errorvalue = false;
				}		
			   	
            }
            
            if (mString.indexOf(at,(lat+1))!=-1){
                if (errorvalue)
               {	errCheck = errCheck + '-  Only one "@" is allowed. ';
			 	  	errorvalue = false;
				}
            }
			
            if (mString.substring(lat-1,lat)==dot || mString.substring(lat+1,lat+2)==dot){
           	 if (errorvalue)
               {	errCheck = errCheck + '- "@" and "." cannot be adjacent to each other. ';
			   		errorvalue = false;
				}
            }
			
            if (mString.indexOf(" ")!=-1){
				 if (errorvalue)
               {	errCheck = errCheck + '- Spaces are not allowed.  ';
			   		errorvalue = false;
				}
            }
            
             //check if .. are encountered
             for(i=0; i < mString.length; i++){
                 if(mString.charAt(i) == '.' && mString.charAt(i + 1) == '.'){
				 	if (errorvalue)
	               {	errCheck = errCheck + '-  Cannot have two "." as adjacent characters. ';
						 errorvalue = false;
					}
                 }
             }
             
             //check for disallowed characters
			 disChar = '';
             for(i=0;i<mString.length;i++){
                 if(disallowedChars.indexOf(mString.charAt(i)) > -1){
	                 disChar = disChar + '"' + mString.charAt(i) + '" ';
                 }
             }
			 if(disChar != ''){
			 	if (errorvalue)
	               {	errCheck = errCheck + '- Characters' + disChar + 'are not allowed. ';
				   		errorvalue = false;
					}
				 }
			//if there two email fields
			emField = document.getElementById('email');
			emconField = document.getElementById('confirmEmail');
			currentElementObject
		//currentElementId
			
			if(emField && emconField && currentElementId == 'confirmEmail'){
				if(trim(emField.value) != trim(emconField.value)){
					if (errorvalue)
	               {	errCheck = errCheck + '- Email and Confirm Email fields are different. ';
				   		errorvalue = false;
					}
				
				}
			
			
			}
			if(trim(errCheck) != ''){
				composeError(errCheck);
			}

            }
			
        }
		
		
		function selectallValidate()
		{
		 
		   var matchelement=currentElementObject.attributes['selectall'].value;
		   if (matchelement.toLowerCase()=='yes')
		    {
			  for(var i=0;i<currentElementObject.options.length;i++)
			  currentElementObject.options[i].selected=true;
			
			}
		
		}
		
		
		
		//Matches field value to name in the matchto attribute
		
		 function matchtoValidate()
		 {
		
		 
		    var errCheck = '';
		  var matchelement=document.getElementById(currentElementObject.attributes['matchto'].value);
		
		  if (currentElementObject.value!=matchelement.value)
		  errCheck =errCheck +'does not match  '+'"'+ matchelement.attributes['label'].value+'"'; 
		  
		  if(trim(errCheck) != '')
		   {
			composeError(errCheck);
		   }
		
		
		}
		
			//Positive number validation
		
		 function positiveValidate()
		 {
		
		 
		  var errCheck = '';
	
		  if (currentElementValue <= 0)
		  errCheck =errCheck +'must be greater than 0.'; 
		  
		  if(trim(errCheck) != '')
		   {
			composeError(errCheck);
		   }
		
		
		}
		
		
		//US phone validation
        function phoneusValidate(){
		pString = trim(currentElementValue);
		if(pString != ''){
	        var errCheck = '';
	        var phoneNumberAllowed = '0123456789-';
			charFlag = false;
	            for (i = 0; i < pString.length; i++){   
	                if (phoneNumberAllowed.indexOf(pString.charAt(i)) == -1){
	                    charFlag = true;
	                }
	            }
				
				if(charFlag){
					errCheck = errCheck + '- Numbers and Dashes are only allowed. ';
				}
	            
	            //check for the length
	            if(pString.length != 12){
	                errCheck = errCheck + '- Should be in XXX-XXX-XXXX format. ';
	            }
	            //check for dash position
	            else{
	                dCounter = new Array();
	                for(i=0; i < pString.length; i++){
	                    if(pString.charAt(i) == '-'){
	                    dCounter[dCounter.length] = i;
	                    }
	                }
	                
	                if(dCounter.length != 2){
	                    errCheck = errCheck + '- Is not in XXX-XXX-XXXX format. ';
	                }
	                else{
	                    if(dCounter[0] != 3 || dCounter[1] != 7){
	                        errCheck = errCheck + '- Dashes are in wrong positions. Should be in XXX-XXX-XXXX format. ';
	                    }
	                }
	            }
				if(trim(errCheck) != ''){
				composeError(errCheck);
				}
            }
        }
		//Marina: Canada ZipCode validation
		function zipcodecanadaValidate(){
		 zString = trim(currentElementValue);
		 var zipNumberAllowed = '0123456789';
		 var zipLetterAllowed = 'ABCDEFGHIJKLMNOPQRSTUVWQXYZabcdefghijklmnopqrstuvwxyz';
		 var errCheck = '';
			 if (zString.length !=7){
			 	 errCheck = errCheck + '- Is not valid. Must have format: letter number letter space number letter number';
				 composeError(errCheck);
				
			}
			else{
			     if (zipLetterAllowed.indexOf(zString.charAt(0)) == -1 || zipNumberAllowed.indexOf(zString.charAt(1)) == -1 || zipLetterAllowed.indexOf(zString.charAt(2)) == -1 || zString.charAt(3)!=' ' || zipNumberAllowed.indexOf(zString.charAt(4))==-1 || zipLetterAllowed.indexOf(zString.charAt(5)) == -1 || zipNumberAllowed.indexOf(zString.charAt(6))==-1){
				 	errCheck = errCheck + '- Is not valid. Must have format: letter number space number letter number';
					composeError(errCheck);
				 }
			}
			
		}
		//US Zip Code validation
        function zipcodeusValidate(){
		//alert(currentElementValue);
        zString = trim(currentElementValue);
		if(zString != ''){
        var errCheck = '';
        var zipNumberAllowed = '0123456789-';
		charFlag = false;
        for (i = 0; i < zString.length; i++){   
                if (zipNumberAllowed.indexOf(zString.charAt(i)) == -1){
					charFlag = true;
                }
            }
			
		if(charFlag){
		
			errCheck = errCheck + '- Is not valid. ';
		}
        //check for length
        if(zString.length < 5
            || (zString.length > 5 && zString.length < 10)
            || zString.length > 10){
            errCheck = errCheck + '- Must be either 5 (XXXXX) or 10 (XXXXX-XXXX) characters long. ';
            
        }
        
        //check for "-" position
        deshPos = zString.indexOf('-');
		
		//if no dash an too long
		if(zString.length == 10 && deshPos == -1){
			errCheck = errCheck + '- Please insert DASH between main Zip Code and +4. Must be either 5 (XXXXX) or 10 (XXXXX-XXXX) characters long.';
		
		}
		//only one dash is allowed
		secondDash = zString.split("-");
		if(secondDash.length > 2){
			errCheck = errCheck + '- Only one DASH is allowed. Must be either 5 (XXXXX) or 10 (XXXXX-XXXX) characters long.';
		
		}
        //if dash is the last
        if(deshPos == 5 && zString.length == 6){
            //cut the dash off
            currentElementObject.value = zString.slice(0,5);
        }
        
        if(deshPos != -1 && deshPos != 5){
		//alert('dash');
            //cut the dash off
            errCheck = errCheck + '- Position of Dashes are wrong. ';
        }
		if(trim(errCheck) != ''){
			composeError(errCheck);
			}
        }
		return errCheck;
        }
//date validation
/*function dateValidate(){
				
				
	mString = trim(currentElementValue);

	var monMax = new Array();
	monMax[0] = [0,31,29,31,30,31,30,31,31,30,31,30,31];
	monMax[1] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	monMax[2] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	monMax[3] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	var errCheck = '';
	var valIn = mString;
	
	valIn = valIn.replace(/[^0-9,\/,-/]/g,"");
	valIn = valIn.replace(/[-/]/g,"/");
	valIn = valIn.replace(/\/\//g,"/");
	charFlag = false;
	
	var valSplit = valIn.split('/');
	
	
	if(valSplit.length != 3){
		errCheck = errCheck + '- Syntax is wrong! The correct syntax is mm/dd/yyyy or m/d/yyyy. ';
		errorvalue = false;
	}
	
	else
	{
		var mon = parseInt(valSplit[0]);
		var day = parseInt(valSplit[1]);
		var year = parseInt(valSplit[2]);
		
		if(mon > 12 || mon < 1)
		{
			errCheck = errCheck + '- Month is out of range. ';
			errorvalue = false;
		}
		else
		{
			if(day < 32){
				if(day > monMax[year%4][mon] || day < 1)
				{
					errCheck = errCheck + '- Day is out of range. ';
					errorvalue = false;
				}
			}
			else
			{
				errCheck = errCheck + '- Day is out of range. ';
				errorvalue = false;
			}
			
			if(year<2007){
				errCheck = errCheck + '- Year must be 4 numers long and no earlier than 2007. ';
				errorvalue = false;
			}
		}
		
		
	
	
	}
	
	
	if(trim(errCheck) != ''){
		composeError(errCheck);
	}

}




function autoDate(el)
{
var e = window.event;
if(e.keyCode != 37){
	var monMax = new Array();
	monMax[0] = [0,31,29,31,30,31,30,31,31,30,31,30,31];
	monMax[1] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	monMax[2] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	monMax[3] = [0,31,28,31,30,31,30,31,31,30,31,30,31];
	
	
	var valIn = el.value;
	
	valIn = valIn.replace(/[^0-9,\/,-/]/g,"");
	valIn = valIn.replace(/[-/]/g,"/");
	valIn = valIn.replace(/\/\//g,"/");
	
	//el.value = valIn;
	
	var valSplit = valIn.split('/');
	if(valSplit.length > 3){
		while(valSplit.length>3){
			valSplit.pop();
		}
	}
	

	


	//alert(valSplit);
	switch(valSplit.length){
		case 1:
			
			while(valSplit[0].length > 3){
				valSplit[0] = valSplit[0].replace(/.$/,"");
			}
			
			if(valSplit[0].length == 3){
				var lastChar = valSplit[0].charAt(2);
				valSplit[0] = valSplit[0].replace(/.$/,"");
				valSplit[1] = lastChar;
			}
			
			if(parseInt(valSplit[0]) > 12){
				valSplit[0] = 12;
			}
			
		break;
		
		case 2:
			while(valSplit[1].length > 3){
				valSplit[1] = valSplit[1].replace(/.$/,"");
			}
			if(valSplit[1].length == 3){
				var lastChar = valSplit[1].charAt(2);
				valSplit[1] = valSplit[1].replace(/.$/,"");
				valSplit[2] = lastChar;
			}
			
			if(parseInt(valSplit[1]) > monMax[0][parseInt(valSplit[0])]){
				valSplit[1] = monMax[0][parseInt(valSplit[0])];
			}
			
		break;
		
		case 3:
		//alert(valSplit[0].length);
			while(valSplit[2].length > 4){
				valSplit[2] = valSplit[2].replace(/.$/,"");
			}
		break;
	}
	
}
el.value = valSplit.join('/');
}
*/

//character validation
function charsValidate(valString){
	charFlag = '';
	for (i = 0; i < currentElementValue.length; i++){
		if (valString[0].indexOf(currentElementValue.charAt(i)) == -1){
			//if this character was not flagged
			if(charFlag.indexOf(currentElementValue.charAt(i)) == -1){
				charFlag = charFlag + '"' + currentElementValue.charAt(i) + '" ';
			}
		}
	}
	if(trim(charFlag) != ''){
		errMsg = ' - The following characters are not allowed: ' + charFlag;
		composeError(errMsg);
	}

}

function buttonGroupVlidation(group){
	mincheckReq = 0;
	maxcheckReq = 10000;
	
	//loop through array and figure which on belongs to this group
	for(g=0; g < buttonGroupObjects.length; g++){
		if(buttonGroupObjects[g][0] == group){
			//loop through attributes
			attrToCheck = currentElementObject.attributes;
			for(atr = 0; atr < attrToCheck.length; atr++){
				if(attrToCheck[atr].name.toLowerCase() == 'mincheck'){
					mincheckReq = trim(attrToCheck[atr].value);
				}
				
				if(attrToCheck[atr].name.toLowerCase() == 'maxcheck'){
					maxcheckReq = trim(attrToCheck[atr].value);
				}
			}
			
			//loop through the buttons
			checkedCount = 0;
			for(but = 1; but < buttonGroupObjects[g].length; but++){
				function hightlightButtons(){
				for(bc = 1; bc < buttonGroupObjects[g].length; bc++){
					buttonGroupObjects[g][bc].style.borderColor = 'red';
					//buttonGroupObjects[g][bc].style.color = 'red';
				}
			}
				if(buttonGroupObjects[g][but].checked){
					checkedCount = checkedCount +1;
				}
			}
			
			//compare to requirements
			if(checkedCount > maxcheckReq){
				errMsg = '- You are allowed to check not more than ' + maxcheckReq + ' buttons';
				composeError(errMsg);
				hightlightButtons()
			}
			
			if(checkedCount < mincheckReq){
				errMsg = '- You must check at least ' + mincheckReq + ' buttons';
				composeError(errMsg);
				hightlightButtons()
			}

		}
	}
	
				
//buttonGroupVlidation END
}
//final validation function

function finalValidation(){

	//clear errors
	//holds objects
	errorArray[0].length = 0;
	//holds errors
	errorArray[1].length = 0;
	
	for(elCount = 0; elCount < elementsArray.length; elCount++){
		currentElementObject = elementsArray[elCount][0];
		currentElementId = currentElementObject.id
		currentElementAttributes = currentElementObject.attributes;
		currentElementValue = elementsArray[elCount][1];
		currentLabel = elementsArray[elCount][2];
		//loop through attributes
		//deal with passwords
			
		for(atCount=0; atCount < currentElementAttributes.length; atCount++){
			currentAttribute = currentElementAttributes[atCount];
			attName = currentAttribute.name.toLowerCase();
			attValue = trim(currentAttribute.value);
			
			if(attName == 'matchto'){
			objString = attName + 'Validate()';
			val = eval(objString);
			}
			
			if(attName == 'selectall'){
			objString = attName + 'Validate()';
			val = eval(objString);
			}
			
			if(attName == 'positive' && attValue=="true"){
			objString = attName + 'Validate()';
			val = eval(objString);
			}
			
			
			//required validation
			
			if(attName == 'required' && attValue == 'yes'){
				
				if(currentElementValue == '' || (currentElementValue == 0 && currentElementObject.type!='text')){
					composeError('is required.');
				}
				
				if(currentElementObject.type=='radio'){
				var radio_choice = false;
				
				    for (counter = 0; counter < currentElementObject.form[currentElementObject.name].length; counter++)
					{
					// If a radio button has been selected it will return true
					// (If not it will return false)
					if (currentElementObject.form[currentElementObject.name][counter].checked)
					radio_choice = true; 
					
					}
					//if(radio button checked)
					if(radio_choice == false){
						composeError('is required.');
					}
				}
				
				
			}
			
			//syntax validation
			if(attName == 'syntaxtype'){
			
				objString = attValue + 'Validate()';

				val = eval(objString);
				
			}
			
			//allowed chars validation
			if(attName == 'allowedchars'){
				val = eval(attValue);
				charsValidate(val);
			}
			
			if(attName == 'minlength'){
				 if(currentElementValue.length > 0 && currentElementValue.length < attValue){
				 	composeError('- Must Have minimum' + attValue + ' characters.');
				 }
			}
			
			
			
			//checkboxes groups validation
			if(attName == 'buttongroup'){
				buttonGroupVlidation(attValue);
			}
		}
	}
	if(errorArray[0].length > 0){
		formApprove = false;
		errorMsg = 'Please correct the following errors and submit:\n\n';
		for(i=0; i < errorArray[0].length; i++){
			indNum = i+1;
			errorMsg = errorMsg + '   ' + indNum + ') ' + errorArray[1][i] + '\n\n';
			currentElement = errorArray[0][i]; 
			currentElementId = currentElement.id;
			//alert(currentElementId);
			highlightFields();
		
		}
		errorMsg = errorMsg + 'Please fix the errors and submit again';
		//if button was disabled on click and there is error message enable the button
		//turnoff - property of button. Equal true if we wabt to disable it 

			for(i=0;i<currentForm.elements.length;i++){
				if(currentForm.elements[i].type == 'button' && currentForm.elements[i].turnoff=='true'){
					currentForm.elements[i].disabled=false;
				}
			}

		alert(errorMsg);
		if(!(!(currentForm.sb))){currentForm.sb.disabled=false;}
		
	}
	
	else{
		if(submitSwitch){
			currentForm.submit();
		}
		
		else{
			formApprove = true;
			//alert(currentForm);
			globalAjaxRequest (requestType, queryString, requestTemplate, respFunc);
			//alert(currentStep);
			//alert("formApprove " + formApprove);
		}
		
	}
	//alert("formApprove " + formApprove);

//end of finalValidation();
}

function validateForm(formToValidate){
//alert();
	currentForm = formToValidate;
	restoreStyles();
	elementsArray.length = 0;
	var errorDebArray = new Array();
	formElements = formToValidate.elements;
	//used to hold check button group requirements
	buttonGroupArray = new Array;
	//examine elements and capture the fields that need to be validated so that we can refer to them as objects-- not by id or name
	for(i=0;i < formElements.length;i++){
	//trim them all
	
		if (formElements[i.value] != null){
		
			trimmed = trim(formElements[i].value);
			formElements[i].value = trimmed;
		}
	
	var elementAttributes = formElements[i].attributes;
	attFlag = 0;
	labelValue = '';
	//alert(elementAttributes);
	//go through all the attributes and define is attributes are for validation purpose
		for(e = 0; e < elementAttributes.length; e++){
		attName = elementAttributes[e].name.toLowerCase();
		//figure if the name is in validationAttributes array (set in the beginning)
			//catch label
			if(attName == 'label'){
				labelValue = elementAttributes[e].value;
			}
			
			for(n=0; n < validationAttributes.length; n++){
			//if the name matches -- add to the elementsArray
				if(attName == trim(validationAttributes[n])){
				attFlag = 1;
				}
			}
			if(buttonGroupObjects.length == 0){
			if(attName == 'buttongroup'){
				//loop through elements again and collect members of this group
				grName = elementAttributes[e].value;
				arrLength = buttonGroupObjects.length
				buttonGroupObjects[arrLength] = new Array();
				buttonGroupObjects[arrLength][0] = grName;
				attFlag = 1;
				
				for(grCount = 0; grCount < formElements.length; grCount++){
					if(formElements[grCount].type == 'checkbox' && formElements[grCount].name == grName){
						newLength = buttonGroupObjects[arrLength].length;
						buttonGroupObjects[arrLength][newLength] = formElements[grCount];
					}
				}
			}
			}
		}
		//if validation attributes are found, add the element to the array of validated objects
		if(attFlag == 1){
			arLength = elementsArray.length;
			elementsArray[arLength] = new Array();
			//hold the object
			elementsArray[arLength][0] = formElements[i];
			//hold the value
			elementsArray[arLength][1] = trim(formElements[i].value);
			//store label
			elementsArray[arLength][2] = labelValue;
			//alert(formElements[i].value);
		}
	}
		
	//enforce conventions and display debudding info

	for(elCount = 0; elCount < elementsArray.length; elCount++){
	elementName = elementsArray[elCount][0].id
	thisAttributes = elementsArray[elCount][0].attributes;
	labelFlag = true;
		//loop through attributes
		for(atCount=0; atCount < thisAttributes.length; atCount++){
			currentAttribute = thisAttributes[atCount];
			attName = currentAttribute.name.toLowerCase();
			attValue = trim(currentAttribute.value);
			//capture if there is label attribute
			if(attName == 'label' && attValue != ''){
				labelFlag = false;
			}
			//find the attribute in the list of validation attributes
			for(n=0; n < validationAttributes.length; n++){
				if(attName == trim(validationAttributes[n])){
					//check is required syntax is correct
					if(attName == 'required' && attValue.toLowerCase() != 'yes' && attValue.toLowerCase() != 'no'){
						errorDebArray[errorDebArray.length] = '"' + elementName + '" attribute "' + attName + '" value is "' + attValue + '": it must be "yes" or "no".\n';
					}
					
					//check if syntaxtype is correct
					if(attName == 'syntaxtype'){
						
						synCheck = eval('typeof(' + attValue + 'Validate)');
						if( synCheck == 'undefined'){
							syntList = '';
							sep = ', ';
							for(sCount = 0; sCount < syntaxFunctions.length; sCount++ ){
								if(sCount + 1 == syntaxFunctions.length){
									sep = '';
								}
								syntList = syntList + syntaxFunctions[sCount] + 'Validate' + sep;
							}
							errorDebArray[errorDebArray.length] = '"' + elementName+ '": ' + '"' + attValue + 'Validate " Syntax Validation Function Does NOT Exist.\nCurrently Available Syntax Functions Are: ' + syntList + '.\nPlease Either Use Existing Functions PREFIXES or Make a New One.';	
						}
					}
					
					
					//check allowedchars
					if(attName == 'allowedchars'){
						
						charCheck = eval('typeof(' + attValue + ')');
						if( charCheck == 'undefined'){
							errorDebArray[errorDebArray.length] = '"' + elementName + '": "' + attValue + '" Characters Allowed Array Does Not Exist.\nPlease Either Use Existing Arrays or Make a New One.\n';
						
						}
						
					
					}
				}
			}
		}
		
		if(labelFlag){
			errorDebArray[errorDebArray.length] = '"' + elementName + '": Does Not Have "label" Attribute or the Attribute is Empty.\nPlease Insert the "label" Attribute to make validation errors more comprehensive.\n'
		}
		//end of debug loop
	}
	
	
	if(errorDebArray.length != 0){
		debugMessage = '';
		debugMessage = 'There are problems with form design!\n\n';
		for(i=0; i < errorDebArray.length; i++){
			preInd = i + 1 + ') ';
			debugMessage = debugMessage + preInd + errorDebArray[i] + '\n';
		}
		while(errorDebArray.length > 0){
		
			errorDebArray.pop();
		}
		alert(debugMessage);
		
	}
	
	else{
	
		for(var i=0;i < formElements.length;i++){
		//trim them all
		if (formElements[i].value != null){
			trimmed = trim(formElements[i].value);
			formElements[i].value = trimmed;
		}
		var elementAttributes = formElements[i].attributes;
		//go through all the attributes and find attrubute 'unique'
			for(var e = 0; e < elementAttributes.length; e++){
			attName = elementAttributes[e].name.toLowerCase();
                // Marina: Checking value from form against value stored in database for uniqueness. 
				if(attName == 'unique' && elementAttributes[e].value=='yes'){
				// if there is not attribure 'storedValue' set it to empty string.
				// storedValue is the value that is stored in database.
				// Important: for edit form we have to have stored value. For add new - not.
					if(!formElements[i].storedValue)
					{
					formElements[i].storedValue = '';
					
					}
              		if (formElements[i].storedValue != formElements[i].value){
										
						var uniqueItem = formElements[i].name;
						HTTPrequestsent = true;
						globalAjaxRequest('GET', 'uniqueItem='+formElements[i].name+'&uniqueValue='+formElements[i].value.replace(/%/g,"%25").replace(/&/g,"%26"), '/admin/ajax_uniqueCheck.cfm', 'checkUniqueAndValidate');
					}
	
					
				}
			}
		}
	
	    if(HTTPrequestsent == false){
			finalValidation();
		}
	
	
	}


	//return false;
//end validateForm function
}

function globalAjaxRequestWithValidation(method, f, template, func){
  	submitSwitch = false;
  	requestType = method;
  	queryString = f; 
  	requestTemplate = template; 
  	respFunc = func;
  
 	validateForm(f);

}

//Marina: This function checks name for unique and validate form
function checkUniqueAndValidate(){
			var responses= xmlHttp.responseText.split("|");
			//document.getElementById('test').innerHTML = xmlHttp.responseText;
	        var alreadyExists = responses[1];
			var uniqueItem = responses[2];
			var uniqueValue = responses[3]; 
			if (alreadyExists != 0)
			{
				alert("The "+uniqueItem+" '"+uniqueValue+"'"+" is already in our system. Please select different "+uniqueItem+".");
				document.getElementById(uniqueItem).value = '';
				for(i=0;i<currentForm.elements.length;i++){
					if(currentForm.elements[i].type == 'button' && currentForm.elements[i].turnoff=='true'){
						currentForm.elements[i].disabled=false;
					}
				}
			}
			else{
				finalValidation();
			}
			HTTPrequestsent = false;
}
//Marina: If countryID equal 231(US) make stateID not required
//If countryID equal 39 (Canada) change zipcode format to 'letter number space number letter number'
 function checkStateReq(countryid){
 	
	document.getElementById('zipcode').value='';
	 if (countryid != 231){
	 	document.getElementById('stateID').required='no';
		document.getElementById('stateID').selectedIndex=0;
		document.getElementById('stateID').disabled=true;
		
		us = false;
		if(countryid==39){
		    us = false;
			document.getElementById('zipcode').syntaxtype='zipcodecanada';
			document.getElementById('zipcode').allowedchars='alpnumericalspaceAllowed';
			document.getElementById('zipcode').onkeyup='';
		}
	 }
	 else{
	 	document.getElementById('stateID').required='yes';
		document.getElementById('stateID').disabled=false;
		us = true;
	 }
 }