// create globally accessible data structure
vo=new Object();
vo.dateCreated=new Date();
vo.fields=new Array();
vo.formId='';
vo.messages=new Array();
vo.errors=new Array();
vo.state=0;

function getDefaultRegExp(dataType){
	// holds default regular expressions
	var re;
	switch(dataType){
		case 'text': re=new RegExp('','i'); break;
		case 'date': re=new RegExp('[0-3][0-9]\/[0-1][0-9]\/[1-2][0-9][0-9][0-9]','i'); break;
		case 'time': re=new RegExp('[0-2][0-9]:[0-5][0-9]:[0-5][0-9]','i'); break;
		case 'datetime': re=new RegExp('[1-2][0-9][0-9][0-9]\/[0-1][0-9]\/[0-3][0-9]space[0-2][0-9]:[0-5][0-9]:[0-5][0-9]','i'); break;
		case 'email': re=new RegExp('','i'); break;
		case 'telephone': re=new RegExp('','i'); break;
		case 'fax': re=new RegExp('','i'); break;
		case 'file': re=new RegExp('','i'); break;
		case 'folder': re=new RegExp('','i'); break;
		case 'uri': re=new RegExp('','i'); break;
		case 'xml': re=new RegExp('','i'); break;
		case 'integer': re=new RegExp('\d+','i'); break;
		case 'decimal': re=new RegExp('-?[0-9]+\.[0-9][0-9]','i'); break;
		default: re=''; break;
		}
	return re;
	}

function setFormValidation(formId){
	var formRef;
	var formExists=false;
	// check that the formId is not blank
	if(formId.length != 0){
		// if we have non blank formId - check if it exists
		formRef=document.getElementById(formId);
		if(formRef){formExists=true;}
		}
	if(formExists){vo.formId=formId;vo.state=1;}
	else{vo.formId='';vo.state=0;}
	vo.messages[vo.messages.length]='formId set to "' + formId + '"';
	}
	
function setFieldValidation(elementId,dataType,minLen,maxLen,minVal,maxVal,regExp){
	// adds FieldValidationObject (fvo) to vo.fields array
	var fvo=new Object();
	var fvTxt='';
	var elementInForm=false;
	var elemRef;
	// make sure the element exists
	elementInForm=isElementInForm(elementId);
	if(elementInForm){
		// got element
		fvo.elementId=elementId;
		fvo.dataType=dataType;
		fvo.minLen=minLen;
		fvo.maxLen=maxLen;
		fvo.minVal=minVal;
		fvo.maxVal=maxVal;
		fvo.regExp=regExp;
		// get validation text
		fvo.fvTxt=getValidationText(fvo);
		vo.fields[vo.fields.length]=fvo;
		// append validation text to element title attibute
		elemRef=document.getElementById(fvo.elementId)
		elemRef.title=elemRef.title + ' : ' + fvo.fvTxt;
		vo.messages[vo.messages.length]='Created validation object for "' + elementId + '"';
		}
	else{
		// element does not exist - add error message
		vo.errors[vo.errors.length]='Unable to find element "' + elementId + '"';
		}
	}
	

function validateForm(){
	var ok2submit=true;
	var debugProcess=false;
	var f=0;
	var fieldCount=vo.fields.length;
	var vf=new Object();
	var vfo;
	var elemRef;
	var formRef=document.getElementById(vo.formId);
	var elemVal;
	var constr='';
	var vMsg='';
	if(debugProcess){
		// initailise debugging
		vf.errors=new Array();
		vf.messages=new Array();
		vf.messages[vf.messages.length]='Debugging initailised';
		}
	if(fieldCount == 0){
		if(debugProcess){vf.messages[vf.messages.length]='No fields to validate - success assumed';}
		ok2submit=true;
		}
	else{
		// fields found - loop through testing
		if(debugProcess){vf.messages[vf.messages.length]='Starting validation of ' + fieldCount + ' fields';}
		for(f=0;f < vo.fields.length;f++){
			vfo=vo.fields[f];
			// get a handle on the element we're validating
			elemRef=formRef[vfo.elementId];
			// add code here to make sure radio, checkbox, textarea and select values are correctly extracted
			elemVal=elemRef.value;
			// test with appropriate validation function
			fValid=false
			switch(vfo.dataType){
				case 'integer': fValid=vfn_integer(vfo,elemVal); break;
				case 'decimal': fValid=vfn_decimal(vfo,elemVal); break;
				case 'date': fValid=vfn_date(vfo,elemVal); break;
				case 'email': fValid=vfn_email(vfo,elemVal); break;
				// time
				// datetime
				// file
				// folder
				// uri
				// xml
				// email
				// telephone
				// fax
				
				// default same as text	
				default: fValid=vfn_text(vfo,elemVal);break;
				}
				
			if(fValid){
				// field is ok
				vMsg=' VALID';
				elemRef.style.backgroundColor='#CCFFCC';
				}
			else{
				// field is not ok
				vMsg=' INVALID';
				ok2submit=false;
				//elemRef.focus();
				//elemRef.select();
				elemRef.style.backgroundColor='#FFCCCC';
				document.getElementById('validation_results').innerHTML=document.getElementById('validation_results').innerHTML + "<br />" + vfo.fvTxt;
				// if(!debugProcess){return false;}
				}
			if(debugProcess){
				constr='(' + vfo.dataType + ',' + vfo.minLen + ',' + vfo.maxLen + ',' + vfo.minVal + ',' + vfo.maxVal + ',' + vfo.regExp + ')';
				vf.messages[vf.messages.length]='Validating "' + vfo.elementId + '" value="' + elemVal + '" validationStr="' + constr + '"' + vMsg;
				}
			}
		
		}
	if(debugProcess){
		vf.messages[vf.messages.length]='Final returned result ="' + ok2submit + '"';
		vf.messages[vf.messages.length]='End validation';
		dumpTxt=debugVF(vf);
		alert(dumpTxt);
		}
	// if(ok2submit){alert('Form validated successfully.');}
	return ok2submit;
	}

function clearDivs()
{
	document.getElementById('validation_results').innerHTML="";
}

	
function getValidationText(fvo){
	var fvTxt='';
	var fType='';
	switch(fvo.dataType){
		case 'text': fvTxt='Please enter some text'; if(fvo.regExp.length !=0){fvTxt=fvTxt + ' matching "' + fvo.regExp + '".';}else{fvTxt=fvTxt + '.';} break;		
		case 'integer': fvTxt='Please enter an integer.'; break;
		case 'decimal': fvTxt='Please enter a 2 decimal place number (for example 65.45).'; break;
		case 'email': fvTxt='Please enter a valid e-mail address.'; break;
		case 'telephone': fvTxt='Please enter a telephone number.'; break;
		case 'fax': fvTxt='Please enter a fax number.'; break;
		case 'date': fvTxt='Please enter a date as "dd/mm/yyyy".'; break;
		case 'time': fvTxt='Please enter a time as "HH:mm:ss".'; break;
		case 'datetime': fvTxt='Please enter a date and time as "yyyy-mm-dd HH:mm:ss".'; break;
		case 'file': fvTxt='Please enter a file path.'; break;
		case 'folder': fvTxt='Please enter folder path.'; break;
		case 'uri': fvTxt='Please enter a URL.'; break;
		case 'xml': fvTxt='Please enter an xml document.'; break;
		default: fvTxt='Please enter some text.'; break;
		}
	if(fvo.minLen !=0 && fvo.maxLen !=0){fvTxt=fvTxt + ' It must be between ' + fvo.minLen + ' and ' + fvo.maxLen + ' characters long.' ;}
	else{
		if(fvo.minLen !=0){fvTxt=fvTxt + ' It must be at least ' + fvo.minLen + ' character(s) long.';}
		if(fvo.maxLen !=0){fvTxt=fvTxt + ' It must be at most ' + fvo.maxLen + ' character(s) long.';}
		}
	if(fvo.minVal.length !=0 && fvo.maxVal.length !=0){
		fvTxt=fvTxt + ' The value must be between "' + fvo.minVal + '" and "' + fvo.maxVal + '"';
		}
	else{
		if(fvo.minVal.length !=0){fvTxt=fvTxt + ' The value must be greater than or equal to "' + fvo.minVal + '"';}
		if(fvo.maxVal.length !=0){fvTxt=fvTxt + ' The value must be less than or equal to "' + fvo.maxVal + '"';}
		}
	if(fvo.regExp.length !=0){fvTxt=fvTxt + ' The value must match the pattern "' + fvo.regExp + '"';}
	if(fvo.minLen !=0){fvTxt=fvTxt + ' [Required]';}
	else{fvTxt=fvTxt + ' [Optional]';}
	return fvTxt;
	}
	
function isElementInForm(elementId){
	var elementInForm=false;
	var elemRef;
	var formRef;
	// if form has been successfully added to vo
	if(vo.state=1){
		formRef=document.getElementById(vo.formId);
		elemRef=formRef[elementId];
		if(elemRef){elementInForm=true;}
		}
	return elementInForm;
	}
	

// DEBUGGING FUNCTIONS ONLY BELOW HERE ############################################################################

function debugVO(){
	var dumpTxt='DEBUGGING ValidationObject\n';
	var i=0;
	dumpTxt+='\nvo.formId=' + vo.formId;
	dumpTxt+='\nvo.dateCreated=' + vo.dateCreated;
	dumpTxt+='\nvo.state=' + vo.state;
	dumpTxt+='\n\nERRORS';
	switch(vo.errors.length){
		case 0: dumpTxt+='\n0 errors'; break;
		case 1: dumpTxt+='\n1 error'; dumpTxt+='\n --- ' + vo.errors[0]; break;
		default: dumpTxt+='\n' + vo.errors.length + ' errors'; for(i=0;i < vo.errors.length;i++){dumpTxt+='\n --- ' + vo.errors[i];}
		}
	dumpTxt+='\n\nMESSAGES';
	switch(vo.messages.length){
		case 0: dumpTxt+='\n0 messages'; break;
		case 1: dumpTxt+='\n1 message'; dumpTxt+='\n --- ' + vo.messages[0]; break;
		default: dumpTxt+='\n' + vo.messages.length + ' messages'; for(i=0;i < vo.messages.length;i++){dumpTxt+='\n --- ' + vo.messages[i];}
		}
	dumpTxt+='\n\nFIELDS';
	switch(vo.fields.length){
		case 0: dumpTxt+='\n0 fields'; break;
		case 1: dumpTxt+='\n1 field'; dumpTxt+='\n' + vo.fields[0].elementId + ' : ' + vo.fields[0].fvTxt; break;
		default: dumpTxt+='\n' + vo.fields.length + ' fields'; for(i=0;i < vo.fields.length;i++){dumpTxt+='\n' + vo.fields[i].elementId + ' : ' + vo.fields[i].fvTxt;} break;
		}
	alert(dumpTxt);
	}	
	
	
function debugVF(vf){
	var dumpTxt='DEBUGGING Form Validation PROCESS\n';
	var i=0;
	dumpTxt+='\n\nMESSAGES';
	switch(vf.messages.length){
		case 0: dumpTxt+='\n0 messages'; break;
		case 1: dumpTxt+='\n1 message'; dumpTxt+='\n --- ' + vf.messages[0]; break;
		default: dumpTxt+='\n' + vf.messages.length + ' messages'; for(i=0;i < vf.messages.length;i++){dumpTxt+='\n --- ' + vf.messages[i];}}
	dumpTxt+='\n\nERRORS';
	switch(vf.errors.length){
		case 0: dumpTxt+='\n0 errors'; break;
		case 1: dumpTxt+='\n1 error'; dumpTxt+='\n --- ' + vf.errors[0]; break;
		default: dumpTxt+='\n' + vf.errors.length + ' errors'; for(i=0;i < vf.errors.length;i++){dumpTxt+='\n --- ' + vf.errors[i];}}
	return dumpTxt;
	}
	
