var valArr = new Array();

function AddFld(sFormType, sFieldName, sErrMsg)
{
	var row = new Object();
	row["formtype"] = sFormType;		// sFormType = {F = find; M = maint}
	row["fieldname"] = sFieldName;
	row["errmsg"] = sErrMsg;
	row["Rules"] =  new Array();

	valArr[valArr.length] = row;
	delete row;
}

function AddRule(sRuleType, sRuleValue)
{
	var oRule = new Object();

	oRule["ruletype"] = sRuleType;
	oRule["rulevalue"] = sRuleValue;
	valArr[valArr.length-1].Rules[valArr[valArr.length-1].Rules.length] = oRule;
	delete oRule;
}

function hderr(sName)
{
	sName+= '_err';
	var d = document;
	if ( d.getElementById )
	{
		if ( d.getElementById(sName) )
			d.getElementById(sName).style.visibility = 'hidden';
	}
	else
		if ( d.layers )
			if ( d.layers[objName] )
				document.layers[objName].visibility = 'hide';
}

function swerr(sName)
{
	var d = document;
	sName+= '_err';
	if (d.getElementById)
		d.getElementById(sName).style.visibility = 'visible';
	else
		if (d.layers && d.layers[objName])
			d.layers[sName].visibility = 'show';
}


function HideAllErrors( frm )
{
	for ( i=0; i < frm.elements.length; i++ )
		hderr(frm.elements[i].name);
}

function iFieldArrayPos(sField)
{
	var iIndex = -1;

	for (i=0; i < valArr.length; i++)
		if (valArr[i].fieldname == sField)
		{
			iIndex = i;
			break;			
		}
	return iIndex;
}

function RuleValidation(sFormType, f)
{
	var dummy;
	var sact;
	var bCont = false;
	var bRet = true;
	var bRetCustomValidation = true;
	var iIndex = -1;

	var r;
	var re;

	HideAllErrors( f );

	var oEls = f.elements;		//elements
	for (var i=0; i < oEls.length; i++)
	{
		var oFld = oEls[i];

		if (oFld.name.substr(0,1) != "_")
		{
			iIndex = iFieldArrayPos(oFld.name);
			if (iIndex > -1)		//validations exist for field
			{
				// get ref to field object
				var oFld2;
				switch (oFld.type) 
				{
					case "text" :
					
					case "password" :
					case "textarea" :
							oFld.value = trim(oFld.value);
							oFld2 = oFld;
							break;

					case "select-one" :
							if (oFld.selectedIndex.toString() != "-1")
								oFld2 = oFld.options[ oFld.selectedIndex ];
							else
								oFld2 = null;
							break;

					case "select-multiple" :
							if (oFld.selectedIndex.toString() != "-1")
								oFld2 = oFld.options[ oFld.selectedIndex ];
							else
								oFld2 = null;
							break;


					case "hidden" :
						continue;
					
					default :
							alert( oFld.type + ' has not been implemented in frmval.js, please implement it.' );
							return;
				}	//switch


				for (var j=0; j<valArr[iIndex].Rules.length && valArr[iIndex].formtype == sFormType; j++)
				{
					switch (valArr[iIndex].Rules[j].ruletype)
					{
						case "man":
							if ( (oFld2.value == "") || ( oFld2==null ) )
							{
								swerr( oFld.name );
								bRet = false;
							}
							break;

						case "email":
							if (oFld2.value && oFld2.value != '') 
							{
								//Change by G.S to allow emails with 4 chars in 2nd extension (20/09/2004)
								re = new RegExp( "^[a-z0-9][a-z_0-9\\.-]*@[a-z_0-9\\.-]+\\.[a-z]{2,4}$", "ig" );
								r = oFld2.value.match(re);

								if ( r==null )
								{
									swerr(oFld.name);
									bRet = false;
								}
							}
							break;		

						case "num":
							if (oFld2.value && oFld2.value != '')
							{
								if ( isNumber(oFld2.value ) == false )
								{
									swerr(oFld.name);
									bRet = false;
								}
							}
							break;		

						case "minlen":
							if ( oFld2.value && oFld2.value != '' )
								if ( oFld2.value.length < valArr[iIndex].Rules[j].rulevalue )
								{
									swerr(oFld2.name);
									bRet = false;
								}
							break;


						case "minval":
							if ( oFld2.value && oFld2.value != '' )
								if (isNaN(oFld2.value))
								{
									swerr(oFld2.name);
									bRet = false;
								}
								else
								{
									if ( parseFloat( oFld2.value ) < valArr[iIndex].Rules[j].rulevalue )
									{
										swerr(oFld2.name);
										bret = false;
									}
								}
								
							break;

						case "maxval":
							if ( oFld2.value && oFld2.value != '' )
								if (isNaN(oFld2.value))
								{
									swerr(oFld2.name);
									bRet = false;
								}
								else
								{
									if ( parseFloat( oFld2.value ) > valArr[iIndex].Rules[j].rulevalue )
									{
										swerr(oFld2.name);
										bret = false;
									}
								}
								
							break;


						case "creditcard":
							if ( oFld2.value && oFld2.value != '' )
								if (isCreditCard(oFld2.value) == false)
								{
									swerr(oFld2.name);
									bRet = false;
								}
							break;


						case "twcard":
							if (oFld2.value && oFld2.value != '')
							{
								var oCard = new clsCard(oFld2.value);
								if (oCard.isTWCard == false)
								{
									swerr(oFld2.name);
									bRet=false;
								}
							}
							break;


						case "rsaid":
							if ( oFld2.value && oFld2.value != '' )
							{
								if ( isValidRSAIDNumber(oFld2.value) == false)
								{
									swerr( oFld2.name );
									bRet = false;
								}
							}
							break;



						case "reg":
							re = new RegExp( valArr[oFld.name].Rules[j].rulevalue, "ig" );
							r = oFld2.value.match(re);

							if ( r==null )
							{
							  	swerr(oFld.name);
							  	bRet = false;
							}
							break;																										

						case "date":
							if ( oFld2.value && oFld2.value != '' )
							{
								re = new RegExp( "^([0]?[1-9]|[1-2][0-9]|3[0-1])\/([0]?[1-9]|1[0-2])\/([1-2][0-9][0-9][0-9])$", "ig" );
								r = oFld2.value.match(re);

								if ( r==null )
								{
									swerr(oFld.name);
									bRet = false;
								}
								else
									if ( !isValidDate(oFld2.value) )
									{
										swerr(oFld.name);
										bRet = false;
									}
							}
							break;	

						default :
							alert( 'Invalid validation rule name, please check rule : ' + valArr[fld].rule[j].rt );

					}	//switch
				}	//for
			}	//if
		}	//if
	}	//for


//	if ( bRet )
//		return true;
//	else
//		return false;
//

	return bRet;

}

function isValidDate( sDate )
{
	// sDate = d/m/y format

	var days = [31,28,31,30,31,30,31,31,30,31,30,31];
	var d, m, y = new Number();
	var la_DMY = new Array();
	var bRet = true;

	if ( trim( sDate ) != '' )
	{
		var re = new RegExp( "^([0]?[1-9]|[1-2][0-9]|3[0-1])\/([0]?[1-9]|1[0-2])\/([1-2][0-9][0-9][0-9])$", "ig" );
		var r = sDate.match(re);

		if ( r==null )
			bRet = false;
		else
		{
			//matched to dd/mm/yyyy format
			la_DMY = sDate.split("/");

			d = la_DMY[0];
			m = la_DMY[1];
			y = la_DMY[2];
			//RR added for 2-digit years
			if (y < 100 && y >= 0)
			{
				if (y < 30) //RR could cause problems e.g. if born 1929- or credit card expires 2030+
					y += 2000;
				else 
					y += 1900;
			}

			if ((m < 1) || (m > 12))
				bRet = false;

			if ((y % 4) == 0)
				days[1] = 29;
			else
				days[1] = 28;

			if ((y % 100) == 0) 
			{
				if ((y % 400) == 0)
					days[1] = 29;
				else
					days[1] = 28;
			}

			if (d > days[m - 1])
				bRet = false;
				
			if (y<1900 || y>2100)
				bRet = false;
		}
	}
	else
		bRet = false;

	return bRet;
}


function trim(str) {
	return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
}

function bRadioChecked( oControl )
{
	var bRet=false;

	if ( oControl.length )
	{
		for ( i=0; i < oControl.length ; i++ )
			if ( oControl[i].checked == true)
				bRet = true;
	}
	else
		bRet = false;
	return bRet;
}

function isCreditCard(st) {
	// Encoding only works on cards with less than 19 digits
	// does a Luhn Mod-10

	if (st.length > 19)
		return (false);

	sum = 0; mul = 1; l = st.length;
	for (i = 0; i < l; i++) {
		digit = st.substring(l-i-1,l-i);
		tproduct = parseInt(digit ,10)*mul;
		if (tproduct >= 10)
			sum += (tproduct % 10) + 1;
		else
			sum += tproduct;

		if (mul == 1)
			mul++;
		else
			mul--;
	}

	if ((sum % 10) == 0)
		return (true);
	else
		return (false);
}

function isNumber( sNumber )
{
	var re = new RegExp( "^([0-9]{1,})(([.]?[0-9]{1,})?)$", "ig" );
	//var r = oFld2.value.match(re);
	var r = sNumber.match(re);

	if ( r==null )
		return false;
	else
		return true;
}


function clsCard(sCardNo)
{
	this.CardNo = sCardNo
	this.isStaffPrefix = ( sCardNo.substring(0,6).match('[12]01002') ? true : false );
	this.isStaffCard = ((sCardNo.substring(0,6).match('[12]01002') && sCardNo.length==14) ? true : false );
	this.isCashPrefix = ((sCardNo.substring(0.6).match('10110[24]') || sCardNo.substring(0.6).match('20[12]104')) ? true : false );
	this.isCashCard = (((sCardNo.substring(0.6).match('10110[24]') || sCardNo.substring(0.6).match('20[12]104')) && sCardNo.length==14) ? true : false ); //RR 02/07/04 mod from len 15 and only 101104 
	this.isTWCard = isTWCard(sCardNo);
}

function isTWCard( sCardNo )
{
	var bRet = false;

	sCardNo = trim(sCardNo);
	var sPrefix = sCardNo.substring(0,6);
	var iLength = sCardNo.length;

	//sa
	if (iLength==14)
	{
		//General TW card
		if (sPrefix.match('10100[1356]') || sPrefix.match('20[12]00[1235]') || sPrefix == '301004') bRet = true;

		//staff 
		if (sPrefix.match('[12]01002')) bRet = true;
		
		//cash
		if (sPrefix.match('10110[24]') || sPrefix.match('20[12]104')) bRet = true; //RR mod from len==15 02/07/04
		
		//new additions to account no validation
		if (sPrefix.match('10115[12]') || sPrefix.match('10125[15]')) bRet = true;
		
		if (sPrefix.match('10115[12]') || sPrefix.match('10125[15]')) bRet = true;
		
		if (sPrefix.match('20[12]20[12]')) bRet = true;

		if (sPrefix.match('1012[06][1]')) bRet = true;

		if (sPrefix.match('10101[1356]')) bRet = true;

		if (sPrefix.match('10121[13]')) bRet = true;
	}	
	return bRet;
}

function lb_AddItem ( lo_SelectName, sID, sText )
{
	var loOption = new Option(sText, sID);
	lo_SelectName.options[lo_SelectName.length] = loOption;
}

function lb_RemoveItem( lo_SelectName, sID )
{
	for (var i=0; i< lo_SelectName.length;) {
		if (lo_SelectName.options[i].value == sID)
		{
			lo_SelectName.remove(i);
		}
		else {
			i++;
		};
	};
};





function ValidTelephoneDetails(poAreaCode, poTelNo, pbRequired)
{
	//this function returns a boolean value
	// see function bAtLeastOneValidTelephoneNumber below for easy way of validating 3 phone numbers
	// pbRequired : pass in True is values are required for both columns

	poAreaCode.value = trim(poAreaCode.value);
	poTelNo.value = trim(poTelNo.value);

	var lbRet = true;
	var lbValidPhone = ( poAreaCode.value == '' ) && ( poTelNo.value == '' );		//blank check

	if ( (lbValidPhone == false) || ( pbRequired == true ) )		//if field filled in or required, validate filled in fields
	{
		//check if all fields contain values, else make missing fields mandatory
		lbValidPhone = ( poAreaCode.value != '' )  && ( poTelNo.value != '' );

		//check if all fields contain values, else make missing fields mandatory
		if (lbValidPhone == false)		//make missing fields mandatory
		{
			swerr(poAreaCode.name);
			swerr(poTelNo.name);
			lbRet = false;
		}
	}
	return lbRet;
}



function bAtLeastOneValidTelephoneNumber( poHomeTelCode, poHomeTelNo, poWorkTelCode, poWorkTelNo, poCellCode, poCellNo)
{
	var lbRet = true;


	

	//one contact number
	poHomeTelCode.value = trim(poHomeTelCode.value);
	poHomeTelNo.value = trim(poHomeTelNo.value);

	poWorkTelCode.value = trim(poWorkTelCode.value);
	poWorkTelNo.value = trim(poWorkTelNo.value);

	poCellCode.value = trim(poCellCode.value);
	poCellNo.value = trim(poCellNo.value);

	//check for blanks
	var bHome = ( poHomeTelCode.value == '' ) && ( poHomeTelNo.value == '' );
	var bWork = ( poWorkTelCode.value == '' ) && ( poWorkTelNo.value == '' );
	var bCell = ( poCellCode.value == '' ) && ( poCellNo.value == '' );

	if ( ( bHome == true ) && ( bWork == true ) && ( bCell == true ) )
	{
		//all fields were blank

		swerr(poHomeTelCode.name);
		swerr(poHomeTelNo.name);

		swerr(poWorkTelCode.name);
		swerr(poWorkTelNo.name);

		swerr(poCellCode.name);
		swerr(poCellNo.name);

		lbRet = false;
	}
	else
	{
		// at least one (or more) fields were filled in for a telphone number grouping

		lbRet &= ValidTelephoneDetails(poHomeTelCode, poHomeTelNo, false);
		lbRet &= ValidTelephoneDetails(poWorkTelCode, poWorkTelNo, false);
		lbRet &= ValidTelephoneDetails(poCellCode, poCellNo, false);
	}	//if

	return lbRet;
}



function isValidRSAIDNumber(psIDNumber)
{
	if (psIDNumber.length != 13)
	{
		//alert('ID number must be 13 characters long')
		return false;
	}

	var liIDNumber = parseInt(psIDNumber, 10);
	if (isNaN(liIDNumber))
		return false;
  
	var liSumOfDigits = 0
	for(i=1; i<=12; ++i)
	{
		switch (i)
		{
			case 1:
			case 3:
			case 5:
			case 7:
			case 9:
			case 11:
					liSumOfDigits += parseInt(psIDNumber.substr(i - 1, 1), 10);
					break;

			default:
				switch (parseInt(psIDNumber.substr(i - 1, 1), 10))
				{
					case 1: liSumOfDigits += 2; break;
					case 2: liSumOfDigits += 4; break;
					case 3: liSumOfDigits += 6; break;
					case 4: liSumOfDigits += 8; break;
					case 5: liSumOfDigits += 1; break;
					case 6: liSumOfDigits += 3; break;
					case 7: liSumOfDigits += 5; break;
					case 8: liSumOfDigits += 7; break;
					case 9: liSumOfDigits += 9; break;
				}
		}
	}
  
	var liCheckDigit = (liSumOfDigits%10) == 0 ? 0 : 10 - (liSumOfDigits%10);
	if (parseInt(psIDNumber.substr(12, 1), 10) == liCheckDigit)
		return true;
	else
		return false;
}




function setListBoxItem(poListBox, sValue)
{
	if (poListBox)
	{
		for (var i=0; i < poListBox.length; i++)
		{
			if (poListBox.options[i].value == sValue)
				poListBox.selectedIndex = i;
		}
	}
	else
		alert("The listbox does not exist");
}