//Copyright pi-squared 2007

//Declare globals
var myDivArray = new Array();
//------------------------------------------------------------------------------
// Description	: Clears the target element's values
// Parameters	: objIn
// Returns		: nothing
//------------------------------------------------------------------------------
function clrChild(objIn){
	var myType=chkType(objIn);
	switch (myType)
	{
	case 'select-one':
	case 'select-multiple':
		clrList(objIn);
		break;
	case 'radio':
	case 'checkbox':
		clrArray(objIn);
		break;
	case 'text': 
	case 'textarea': 
	case 'password': 
	case 'file': 
		clrText(objIn);
	    break;
	default:
		break;
	}
}

//------------------------------------------------------------------------------
// Description	: Checkbox and radio button array clearer
// Parameters	: parent object
// Returns		: nothing
//------------------------------------------------------------------------------
function clrArray(objIn){
	if(objIn.length>1){
	    //for an array of check boxes or radio buttons
		for(var a=0; a<objIn.length; a++){
			objIn[a].checked=false;
		}
	}
	else{
	    //for a single check box or radio button
		objIn.checked=false;
	}
}

//------------------------------------------------------------------------------
// Description	: Drop down & multiple clearer
// Parameters	: parent object
// Returns		: nothing
//------------------------------------------------------------------------------
function clrList(objIn){
	objIn.selectedIndex='';
}

//------------------------------------------------------------------------------
// Description	: Text input clearer
// Parameters	: parent object
// Returns		: nothing
//------------------------------------------------------------------------------
function clrText(objIn){
	objIn.value='';
}

//------------------------------------------------------------------------------
// Description	: Run assignCheckArrays if myCheckArray.length>0
// 				  Create array of block elements that will contain required form elements if triggered by checkReqEvents. 
// 				  Optionally hides targeted form elements onLoad, based on form element, plus target value
// Parameters	: hide
// Returns		: nothing
//------------------------------------------------------------------------------
function frmLoad(display){
	//Search for ","
	var re=/,/gi;
	var newStr;
	for (var i=0; i<myCheckArray.length; i++){
		newStr=myCheckArray[i].split(re);
		newStr[1]+='_'+newStr[2];
		//only if there is a hidden div
		if (document.getElementById(newStr[1])){
			myDivArray.push(document.getElementById(newStr[1]));
			if(display=='hide'){
				myDivArray[i].style.display='none';
			}
		}
	}
	if(myCheckArray.length>0){
		assignCheckArrays();
	}
}
//------------------------------------------------------------------------------
// Description	: Hider/un-hider of HTML elements containing targeted form elements
// Parameters	: parentObj,show
// Returns		: nothing
//------------------------------------------------------------------------------
function OtherBox(parentObj,trigger,show){
	var myObj=getObj(parentObj);
	newStr=myObj.name+'_'+trigger;	
	if (document.getElementById(newStr)){
	    myObj=document.getElementById(newStr);
		//only if there is a hidden element
		if(show==true){
			if (myObj.nodeName=="TR"){//got to treat TR's differently
				if (navigator.appVersion.indexOf("MSIE")!=-1){//for IE..could expand to test for container element type...
					myObj.style.display='block';
				}
				else{//for other browsers, so we can show/hide TR's as a block level element normally...
					myObj.style.display='table-row';
				}
			}
			else{
				myObj.style.display='block';
			}
		}
		else{
			myObj.style.display='none';
		}
	}
	else{
		return;
	}
}

//------------------------------------------------------------------------------
// Description	: Event handler for dynamically setting form elements to required 
// status, set in onLoad event handler for body tag
// Parameters	: myCheckArray (global)
// Returns		: Nothing
//------------------------------------------------------------------------------
function assignCheckArrays()
{
	var re=/,/gi;
	var myTempArray=myCheckArray;
	var combCheckArray=new Array();
	for (var i=0; i<myTempArray.length; i++){//for multiple required assignments on different targets of same form element array
		outerTest=myTempArray[i].split(re);
		combCheckArray.push(outerTest);
		for (var j=i+1; j<myTempArray.length; j++){
			innerTest=myTempArray[j].split(re);
			if (outerTest[0]==innerTest[0] && outerTest[1]==innerTest[1]){
				myTempArray.splice(j,1);
				j--;
				combCheckArray[i][2]+='&'+innerTest[2];
				combCheckArray[i][3]+='&'+innerTest[3];
			}
		}
	}
	for (var i=0; i<combCheckArray.length; i++){
		checkReqEvents(combCheckArray[i]);
	}
}

//------------------------------------------------------------------------------
// Description	: Event handler for dynamically setting form elements to required status
// Parameters	: uses combCheckArray 
// Returns		: Nothing
//------------------------------------------------------------------------------
function checkReqEvents(combCheckArray){
	//might need to be adapted for diff. browsers...
	frmIn=eval ('document.forms.'+combCheckArray[0]);
	objIn=eval ('frmIn.'+combCheckArray[1]);
	var myType=chkType(objIn);
	if((objIn.length>1 && myType=='radio')||(objIn.length>1&&myType=='checkbox')){
	    //if a form element array
		for (var y=0; y<objIn.length; y++){	
			objIn[y].onclick=function () {setChildReq(combCheckArray,myType)/*;chkElementSelected(this) - can add additional functions after setChildReq with reference to the specific array element that was clicked*/}
		}
	}
	else	{
		if(myType=='radio' || myType=='checkbox'){
		    //for single radio or check box
			objIn.onclick=function () {setChildReq(combCheckArray,myType)/*;chkElementSelected(this) - can add additional functions after setChildReq with reference to the specific array element that was clicked*/}
		}
		else{//all other form objects
			objIn.onchange=function () {setChildReq(combCheckArray,myType)/*;chkElementSelected(this) - can add additional functions after setChildReq with reference to the specific array element that was clicked*/}
		}
	}
}

//------------------------------------------------------------------------------
// Description	: Sets the additional form elements to be required/un-required
// Parameters	: combCheckArray, myType
// Returns		: nothing
//------------------------------------------------------------------------------
function setChildReq(combCheckArray,myType)
{
	var re=/&/gi;
	var frmIn,objIn,trigger,toChk;	
	frmIn=eval ('document.forms.'+combCheckArray[0]);
	objIn=eval ('frmIn.'+combCheckArray[1]);
	trigger=combCheckArray[2].split(re);
	toChk=combCheckArray[3].split(re);
	var query, newstr;
	var status=false;
	var lastReqArray='';
	for (var i=0; i<trigger.length; i++){
		switch (myType){
		case 'select-one':
		case 'select-multiple':
			status=chkList(objIn,trigger[i]);
			break;
		case 'radio':
		case 'checkbox':
			status=chkArray(objIn,trigger[i]);
			break;
		case 'text': 
		case 'textarea': 
		case 'password': 
		case 'file': 
			status=checkText(objIn,trigger[i]);
			break;
		default:
			break;
		}
		lastReqArray=classAssign(frmIn,objIn,trigger[i],toChk[i],status,lastReqArray);
	}
}

//------------------------------------------------------------------------------
// Description	: visible style setter and 'req' class assigner/de-assigner for 
//                target form elements.
// Parameters	: parent form, target, status, lastReqArray
// Returns		: lastReqArray
//------------------------------------------------------------------------------
function classAssign(frmIn,objIn,trigger,toChk,status,lastReqArray){
	var myStr='';
	//Search for "-".
	var re=/-/gi;
	var toChkArray=toChk.split(re);
	//compare each element in lastReqArray to toChkArray, and remove any duplicated elements
	if(lastReqArray!=''){
		for (var c=0; c<lastReqArray.length; c++){
			for (var j=0; j<toChkArray.length; j++){
				if (toChkArray[j]==lastReqArray[c]){
					toChkArray.splice(j,1);
					j--;
				}
			}
		}
	}
	var done=false;
	if(toChkArray[0]!='null'){
		for (var i=0; i<toChkArray.length; i++){
				var myQuery=eval('frmIn.'+ toChkArray[i]);
				myType=chkType(myQuery);
				if ((myType=='checkbox' && myQuery.length>1) || (myType=='radio' && myQuery.length>1)){
					query=myQuery[0];	
				}
				else{
					query=myQuery;
				}
				if (status==true){/*assign "req" class*/
					myStr='req ' + query.className;
					query.className=myStr;
					OtherBox(objIn,trigger,true);
				}
				else{
					if (done==false){//hack to only do it once...
						traverseNodes(objIn,frmIn,toChkArray,trigger);
						done=true;
					}
					OtherBox(objIn,trigger,false);
				}
			}	
		}
	else{
		OtherBox(objIn,trigger,status);	
	}
	//set lasReqArray to toChkArray after the first successful 'req' class assignment
	if (status==true && toChkArray[0]!='null' && lastReqArray==''){
		lastReqArray=toChkArray;
	}
	return lastReqArray;
}

//------------------------------------------------------------------------------
// Description	: function to clear contents of all form elments within parent element
//                that was made visible by a parent form element selection specified in myCheckArray, 
//                also clears "req" class assignments from myCheckArray & finds children elements
// Parameters	: objIn,frmIn,toChkArray,trigger
// Returns		: nothing
//------------------------------------------------------------------------------

function traverseNodes(objIn,frmIn,toChkArray,trigger){
	//get local reference of body object
	var myBody=document.getElementsByTagName('body').item(0);
	
	//string variable to test for
	var re=/ /gi;
	
	//determine id of parent element
	objIn=getObj(objIn);
	var targetStr=objIn.name+'_'+trigger;
	
	//if triggered within a hidden container then
	if(document.getElementById(targetStr)){

		//initialise form array index variables
		var index;
		var endIndex;
		var startIndex;
		var endOfDom=1000;
		var myObj;
		
		var myChldArray=new Array();
		
		//get array of which containers to be also hidden are inside parent container
		for (var i=0; i<myDivArray.length; i++){
		myObj=myDivArray[i];
			for (var j=0; j<endOfDom; j++){
				if(myObj.parentNode.id){
					if(myObj.parentNode.id==targetStr){
						myChldArray.push(myDivArray[i]);
						break;
					}
					else{
						myObj=myObj.parentNode;
						if (myObj==myBody){
							break;
						}
					}
				}else{
					myObj=myObj.parentNode;
					if (myObj==myBody){
						break;
					}
				}
			}
		}

		//determine form element index of last element in toChkArray
		index=detFormIndex(frmIn,toChkArray,toChkArray.length-1);
		endIndex=index;
		myObj=frmIn[index];
		//find end element in form array within parent element
		for (var i=0; i<endOfDom; i++){
			if(myObj.parentNode.id){
				if(myObj.parentNode.id==targetStr){
					endIndex=index;
					index++;
					if(myObj=frmIn[index]){
						myObj=frmIn[index];
					}
					else{
						break;
					}
				}
				else{
					myObj=myObj.parentNode;
					if(myObj==myBody){
						break;
					}
				}
			}else{
				myObj=myObj.parentNode;
				if (myObj==myBody){
					break;
				}
			}
		}
		
		//determine form element index of first element in toChkArray
		index=detFormIndex(frmIn,toChkArray,0);
		startIndex=index;
		myObj=frmIn[index];
		//find start element in form array within parent element;
		endOfDom=0;
		for (var i=1000; i>endOfDom; i--){
			if(myObj.parentNode.id){
				if(myObj.parentNode.id==targetStr){
					startIndex=index;
					index--;
					if(myObj=frmIn[index]){
						myObj=frmIn[index];
					}
					else{
						break;
					}
				}
				else{
					myObj=myObj.parentNode;
					if (myObj==myBody){
						break;
					}
				}
			}else{
				myObj=myObj.parentNode;
				if (myObj==myBody){
					break;
				}
			}
		}



		//clear all form elements inside parent element and unset any req class assignments
		for (var i=startIndex; i<endIndex+1; i++){
			clrChild(frmIn[i]);
			myStr=frmIn[i].className.split(re);
			if(myStr[0]=='req'){
				myStr.shift();
				var tmpStr='';
				for (var s=0; s<myStr.length; s++){
					tmpStr+=myStr[s]+' ';
				}
			frmIn[i].className=tmpStr;
			}
		}
	}
	//clear req assignments of form elements in toChkArray
	for (var i=0; i<toChkArray.length; i++){
		objIn=eval ('frmIn.'+toChkArray[i]);
		objIn=getObj(objIn);
		myStr=objIn.className.split(re);
		if(myStr[0]=='req'){
			myStr.shift();
			var tmpStr='';
			for (var s=0; s<myStr.length; s++){
				tmpStr+=myStr[s]+' ';
			}
			objIn.className=tmpStr;
		}
	}
	//hides myChldArray elements
	for (var i=0; i<myChldArray.length; i++){
		myChldArray[i].style.display='none';
	}
}

//------------------------------------------------------------------------------
// Description	: Returns index in parent form array of object
// Parameters	: parent form, object
// Returns		: index
//------------------------------------------------------------------------------

function detFormIndex(frmIn,toChkArray,index){
	myObj=eval ('frmIn.'+toChkArray[index]);
	myObj=getObj(myObj);
	var index=0;
	for (var i=0; i<frmIn.length; i++){
		if(frmIn[i]==myObj){
			index=i;	
		}
	}
	return index;
}
	
//------------------------------------------------------------------------------
// Description	: Form validator function, gives the user an error list, and puts focus on 1st incorrect field
// Parameters	: parent object
// Returns		: nothing
//------------------------------------------------------------------------------
function fnValidateForm(frmIn){
	//for if only a single form to be checked
	if(frmIn.name){
		frmIn=new Array(frmIn);
	}
	var errorStack=new Array();
	
	//looks for blank gap in class assignments for form elements
	var re=/ /gi;
	var check='';
	var test, query, myStr;
	for (var m=0; m<frmIn.length; m++){
		for (var i=0; i<frmIn[m].length; i++){	
			//makes sure sibling radio & check box elements don't all get processed, only collection
			if (frmIn[m][i].name != check){
				myStr=frmIn[m][i].className.split(re);
				if(myStr[0]=='req'){//checks to see if a form element is required
					
					//ensures that array of radio or check box elements get checked, not individual element of array
					query=eval('frmIn[m].'+frmIn[m][i].name);
					
					//checks to see whether a required form element has been selected/filled in or correctly formatted
					test=assignChk(query,myStr);
					if (test != true){
						errorStack.push(test);	
					}
				}
				else{
					if (myStr[0]=='validate'){//checks to see if form element is not required, but needs format validation
						query=eval('frmIn[m].'+frmIn[m][i].name);
						if (query.value!=''){//if it's not filled in, no need to validate
							test=assignFormatValidator(query,myStr);
							if (test != true){
								errorStack.push(test);	
							}
						}
					}
				}
			}
			check=frmIn[m].elements[i].name;
		}
	}
	//check for matches
	for (var m=0; m<frmIn.length; m++){
		errorStack=chkMatches(errorStack,frmIn[m]);
	}
	//check for minimum filled in
	for (m=0; m<frmIn.length; m++){
		errorStack=chkMinReq(errorStack,frmIn[m]);
	}

    //Search for ","
	re=/,/gi;
	//var errorMessageArray=errorMessages.split(re);
	
	var errorMessageArray=errorMessages;
	
	//Error Message Displayed on page.
	var bldErrorMessage='Please complete or attend to the following details:\n-------------------------------------------------\n\n';
	for (var i=0; i<errorStack.length; i++){
		bldErrorMessage += prcssErrorArray(errorMessageArray,errorStack[i])+'\n\n';
	}
	if (bldErrorMessage != 'Please complete or attend to the following details:\n-------------------------------------------------\n\n'){
		alert(bldErrorMessage);
		return false;
	}
	else{
	  return true;
	}
}

//------------------------------------------------------------------------------
// Description	: determines whether the form element in the error stack has a description in errorMessages
// Parameters	: errorMessageArray, element
// Returns		: element name/
//------------------------------------------------------------------------------
function prcssErrorArray(errorMessageArray,myError){
	//Search for "-".
	var re1=/,/gi;
	var re2=/-/gi;
	var test=false;
	var errorMsg='';
	
	if (!myError.type){
        //if an array with a message at the end. ie. incorrectly formatted input, or non matching inputs
		for (var k=0; k<myError.length-1; k++){
			for (var x=0; x<errorMessageArray.length; x++){
				var tempArray1=errorMessageArray[x].split(re1);
				var tempArray2=tempArray1[1].split(re2);
				if (myError[k].name==tempArray2[0] && myError[k].form.name==tempArray1[0]){
					errorMsg+='\''+tempArray2[1]+'\'';
					if(k != myError.length-2){
						errorMsg+=' & ';
					}
					test=true;
					break;
				}	
			}
			if(test==false){
				errorMsg+='\''+myError[k].title+'\'';
				if(k != myError.length-2){
					errorMsg+=' & ';
				}
			}
		}
		errorMsg+=' '+myError[myError.length-1];
		return errorMsg;
	}
	else{
		
		 //just a normal form element in the array
		for (var x=0; x<errorMessageArray.length; x++){
			var tempArray1=errorMessageArray[x].split(re1);
			var tempArray2=tempArray1[1].split(re2);
			if (myError.name==tempArray2[0] && myError.form.name==tempArray1[0]){
				return '\''+tempArray2[1]+'\' needs to be completed.';
			}	
		}
		return '\''+myError.title+'\' needs to be completed.';
	}
}

//------------------------------------------------------------------------------
// Description	: determines whether the form element is a single element or array
// Parameters	: parent object
// Returns		: myType
//------------------------------------------------------------------------------

function chkType(objIn){
	if (!objIn.type){//for radio button and check box arrays 
		return objIn[0].type;
	}
	else{
		return objIn.type;
	}
}

//------------------------------------------------------------------------------
// Description	: determines whether the form element is a single element or array
// Parameters	: parent object
// Returns		: myType
//------------------------------------------------------------------------------

function getObj(objIn){
	if (!objIn.type){//for radio button and check box arrays 
		return objIn[0];
	}
	else{
		return objIn;
	}
}

//------------------------------------------------------------------------------
// Description	: Determines input type, assigns correct check function
// Parameters	: parent object, class string array
// Returns		: parent object, false
//------------------------------------------------------------------------------

function assignChk(objIn,myStr){
	var myType=chkType(objIn);
	switch (myType){
    	case 'select-one': 
		case 'select-multiple': 
			return chkList(objIn);
		case 'radio': 
		case 'checkbox': 
			return chkArray(objIn); 
		case 'text': 
		case 'textarea': 
		case 'password': 
		case 'file': 
			return checkText(objIn,myStr); 
    	default: 
			return 'unknown';
	}
}

//------------------------------------------------------------------------------
// Description	: Checkbox and radio button array checker
// Parameters	: parent object
// Returns		: parent object, checked
//------------------------------------------------------------------------------
function chkArray(objIn,target){
	var checked=false;
	var toReturn;
	if(objIn.length>1){
	    //for an array of check boxes or radio buttons
		for(var a=0; a<objIn.length; a++)		{
			if (objIn[a].checked){
				if(!target){
					if(objIn[a].value != ''){//make sure selected option has a value, ie. not 'please select'
						checked=true;
					}
				}
				else{
					if(objIn[a].value==target){//tests if radio or check button selected matches the target
						checked=true;
					}
				}
			}
		}
		toReturn=objIn[0];//id tag is set on 1st element of radio or check array

	}
	else{//for a single check box or radio button
		if (objIn.checked){
			if(!target){
				if(objIn.value != ''){//make sure selected option has a value, ie. not 'please select'
					checked=true;
				}
			}
			else{
				if(objIn.value==target){//tests if radio or check button selected matches the target
					checked=true;
				}
			}
		}
		toReturn=objIn;
	}
	if (checked==false){
		if (target){
			return checked;
		}
		else{
			return toReturn;
		}
	}
	else{
		return checked;
	}
}

//------------------------------------------------------------------------------
// Description	: Drop down & multiple select checker
// Parameters	: parent object, target
// Returns		: parent object, checked
//------------------------------------------------------------------------------

function chkList(objIn,target){
	var checked=false;
	for(var a=0; a<objIn.length; a++){
		if (objIn[a].selected){
			if(!target){//checks to see if target has beeen selected
				if (objIn[a].value != ''){//make sure selected option has a value, ie. not 'please select' or something like that...'
					checked=true;
				}
			}
			else{
				if (objIn[a].value==target){//checks to see if the target value was selected
					checked=true;
				}
			}
		}
	}
	if (checked==false){
		if (target){
			return checked;
		}
		else{
			return objIn;
		}
	}
	else{
		return checked;
	}
}

//------------------------------------------------------------------------------
// Description	: Text input checker
// Parameters	: parent object
// Returns		: parent object, false
//------------------------------------------------------------------------------

function checkText(objIn,myStr,target){
	if(!target){
		if (objIn.value==''){
			return objIn;
		}
		else{
			return assignFormatValidator(objIn,myStr);
		}
	}
	else{
		if (objIn.value != ''){
			return true;
		}
		else{
			return false;
		}
	}
}

//------------------------------------------------------------------------------
// Description	: Assigns correct text field format validator
// Parameters	: objIn
// Returns		: parent object, false
//------------------------------------------------------------------------------

function assignFormatValidator(objIn,myStr){
	switch (myStr[1]){
	    //to grow list with date, telephone etc. functions...
		case 'email': 
			return verifyEmail(objIn);
		case 'ccnumber': 
			return verifyCcNumber(objIn);
		case 'integer': 
			return verifyInteger(objIn);
		case 'float': 
			return verifyFloat(objIn);
		case 'number': 
			return verifyNumber(objIn);
		default: 
			return true;
	}
}

//------------------------------------------------------------------------------
// Description	: Email validator
// Parameters	: FormFieldName
// Returns		: parent object, false
//------------------------------------------------------------------------------
function verifyEmail(FormFieldName)
{
	var emailReg="^[\\w-_\.]*[\\w-_\.]\@[\\w]\.+[\\w]+[A-Za-z0-9]$"; // credit: madcow@olg.com (slightly adapted)
	var emailExp=new RegExp(emailReg);
	if (emailExp.test(FormFieldName.value)){
		return true;
	}
	else{
		return [FormFieldName,'needs to be formatted correctly.'];
	}
}

//------------------------------------------------------------------------------
// Description	: CCnumber validator
// Parameters	: FormFieldName
// Returns		: parent object, false
//------------------------------------------------------------------------------

function verifyCcNumber(FormFieldName)

{
	var ccReg=/^\d{15,}$/; //must be at least 6 numbers only
	var ccExp=new RegExp(ccReg);
	if (ccExp.test(FormFieldName.value)){
		return true;
	}
	else{
		return [FormFieldName,'needs to contain at least 15 numbers, and no spaces.'];
	}
}

//------------------------------------------------------------------------------
// Description	: integer validator
// Parameters	: FormFieldName
// Returns		: parent object, false
//------------------------------------------------------------------------------

function verifyInteger(FormFieldName)
{
	var integerReg=/^\d{1,}$/; //looks for at least 1 integer number
	var integerExp=new RegExp(integerReg);
	if (integerExp.test(FormFieldName.value)){
		return true;
	}
	else{
		return [FormFieldName,'needs to contain only whole numbers, with no spaces'];
	}
}

//------------------------------------------------------------------------------
// Description	: float validator
// Parameters	: FormFieldName
// Returns		: parent object, false
//------------------------------------------------------------------------------

function verifyFloat(FormFieldName)

{ 
	var floatReg=/^\d+\.\d+$/;
	var floatExp=new RegExp(floatReg);
	if (floatExp.test(FormFieldName.value)){
		return true;
	}
	else{
		return [FormFieldName,'needs to contain only numbers, with one \'.\' contained within the numbers'];
	}
}

//------------------------------------------------------------------------------
// Description	: number validator, either float or integer
// Parameters	: FormFieldName
// Returns		: parent object, false
//------------------------------------------------------------------------------

function verifyNumber(FormFieldName)

{ 
	var floatReg=/^\d{0,}\.?\d+$/;
	var floatExp=new RegExp(floatReg);
	if (floatExp.test(FormFieldName.value)){
		return true;
	}
	else{
		return [FormFieldName,'needs to contain only numbers, with ONE \'.\' optionally contained WITHIN the numbers'];
	}
}

//------------------------------------------------------------------------------
// Description	: determines whether elements in confirmArray are correctly matched
// Parameters	: errorStack, parent form
// Returns		: errorStack
//------------------------------------------------------------------------------
function chkMatches(errorStack,frmIn){
	var re, myStr;
	for (var i=0; i<confirmArray.length; i++)	{
		var mtchArray=new Array();
		re=/,/gi;
		myStr=confirmArray[i].split(re);
		if (myStr[0]==frmIn.name){
			re=/-/gi;
			myStr=myStr[1].split(re);
			for (var k=0; k<myStr.length; k++){
				mtchArray.push(eval('frmIn.'+myStr[k]));
			}
			for (var j=0; j<myStr.length-1; j++){
				query1=mtchArray[j];
				query2=mtchArray[j+1];
				if (query1.value != query2.value){
					mtchArray.push('need to match each other.');
					errorStack.push(mtchArray);
				}
			}
		}
	}
	return errorStack;
}

//------------------------------------------------------------------------------
// Description	: determines whether at least one elements in minReqArray are correctly matched
// Parameters	: errorStack, parent form
// Returns		: errorStack
//------------------------------------------------------------------------------
function chkMinReq(errorStack,frmIn){
	var re, myStr;
	var completed=false;
	for (var i=0; i<minReqArray.length; i++)	{
		var mtchArray=new Array();
		re=/,/gi;
		myStr=minReqArray[i].split(re);
		if (myStr[0]==frmIn.name){
			re=/-/gi;
			myStr=myStr[1].split(re);
			for (var k=0; k<myStr.length; k++){
				query=eval('frmIn.'+myStr[k]);
				test=assignChk(query,'');
				if (test==true){
					completed=true;
					break;
				}
				myObj=getObj(eval('frmIn.'+myStr[k]));
				mtchArray.push(myObj);
			}
			if(completed==false){
				mtchArray.push(': at least one of these needs to be selected or filled in.');
				errorStack.push(mtchArray);
			}
		}
	}
	return errorStack;
}