/*------------------------------------------------------------------------
	Name: 		field()
	Purpose: 	field object constructor
	Return:		collection object
Modifications:
	Date:		Name:	Description:
	7/24/00		ZNO		Creation
------------------------------------------------------------------------*/
function field(desc,type,req) {
	this.desc = desc;
	this.type = type;
	this.req = req;
}

/*------------------------------------------------------------------------
	Name: 		isValid()
	Purpose: 	master validation function
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
------------------------------------------------------------------------*/
function isValid(v_sForm, r_oFields) {
	var oForm = eval("document." + v_sForm);
	var oErrors = new Array
	var lCount = 0;
	
	for (var i in r_oFields) {
		// pass every field to the appropriate validation function
		var oField = eval("oForm." + i);
		if (r_oFields[i].req || oField.value.length > 0) {
			// only check fields that have a value or are required
			if (!(eval("is" + r_oFields[i].type + "(oField)"))) {
				oErrors[lCount] = r_oFields[i].desc;
				lCount++;
			}
		}
	}
	if (lCount > 0) {
		// must be some errors
		var sMessage = "Please enter a valid\n";
		for (i = 0; i < lCount; i++) {
			sMessage += "- " + oErrors[i] + "\n";
		}
		alert(sMessage);
		return false;
	} else {
		return true;
	}
}

/*------------------------------------------------------------------------
	Name: 		isSelect()
	Purpose: 	make sure they made some selection
				this assumes that layout options, like lines, are <= 0
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
	8/6/02		ZNO		Check field type
	9/16/2003	ZNO		Make 0 a valid option
------------------------------------------------------------------------*/
function isSelect(r_oField) {
	if (r_oField.type == "select-one") {
		var re = /[a-zA-Z:]/;	// \D gives bad result
		var val = r_oField.options[r_oField.selectedIndex].value;
		// true if option value >= 0 or non-numeric
		return (val >= 0 || re.test(val)) ? true : false;
	}
	return false;				// maybe default true if not select?
}

/*------------------------------------------------------------------------
	Name: 		isRadio()
	Purpose: 	make sure one radio button was checked
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
------------------------------------------------------------------------*/
function isRadio(r_oField) {
	for (var i = 0; i < r_oField.length; i++) {
		// cycle through each item in the radio collection
		if (r_oField[i].checked) { return true; }
	}
	// if we made it here then no radio is checked
	return false;
}

/*------------------------------------------------------------------------
	Name: 		isBirthDate()
	Purpose: 	allow only future expiration dates
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	10/5/00		ZNO		Creation
	8/6/02		ZNO		Use GetDate()
------------------------------------------------------------------------*/
function isCCExpire(r_oField) {
	var oDate = GetDate(r_oField);
	if (oDate) {
		var oThisDate = new Date();
		if (oDate >= oThisDate) { return true; }
	}
	return false;
}

/*------------------------------------------------------------------------
	Name: 		isBirthDate()
	Purpose: 	validate birthdate
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	8/23/00		ZNO		Creation
	8/6/02		ZNO		Use GetDate()
------------------------------------------------------------------------*/
function isBirthDate(r_oField) {
	var oDate = GetDate(r_oField);
	if (oDate) {
		var oThisDate = new Date();
		var lThisYear = cleanYear(oThisDate.getYear());
		var lMaxAge = 120;		// not many people older than that
		// can't have birthday in future or more than MaxAge
		if (oDate < oThisDate && lYear > (lThisYear - lMaxAge)) { return true; }
	}
	return false;
}

/*------------------------------------------------------------------------
	Name: 		isDate()
	Purpose: 	make sure that a date has been entered
				allows dashes or slashes, m/d/yy or mm/dd/yyyy
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
	8/6/02		ZNO		Use GetDate()
------------------------------------------------------------------------*/
function isDate(r_oField) {
	var oDate = GetDate(r_oField)
	if (oDate) { return true; }
	return false;
}

/*------------------------------------------------------------------------
	Name: 		cleanYear()
	Purpose: 	make years four digits; assume century break on xx10
	Return:		int
Modifications:
	Date:		Name:	Description:
	8/22/00		ZNO		Creation
------------------------------------------------------------------------*/
function cleanYear(v_sYear) {
	if (v_sYear.length == 2) { v_sYear = (v_sYear > 10 ? "19" : "20") + v_sYear; }
	return v_sYear;
}

/*------------------------------------------------------------------------
	Name: 		GetDate()
	Purpose: 	return valid date object
	Return:		object/boolean
Modifications:
	Date:		Name:	Description:
	8/6/02		ZNO		Creation
------------------------------------------------------------------------*/
function GetDate(r_oField) {
	var re = /^((\d{1,2})[\/-\\](\d{1,2})[\/-\\](\d{2,4}))$/;
	var YEAR = 4; var MONTH = 2; var DAY = 3;
	if (re.test(r_oField.value)) {
		// format is right--now check each date value
		var arMatch = re.exec(r_oField.value);
		var lMonth = arMatch[MONTH];
		var lDay = arMatch[DAY];
		var lYear = cleanYear(arMatch[YEAR]);
		
		if (lMonth <= 12 && lMonth >= 1 && lDay <= 31 && lDay >= 1 && lYear <= 2010 && lYear >= 1850) {
			// -1 on month seems necessary for js date glitch
			return new Date(lYear, arMatch[MONTH] - 1, arMatch[DAY]);
		}
	} 
	// invalid date format
	return false;
}

/*------------------------------------------------------------------------
	Name: 		isMoney()
	Purpose: 	validate monetary fields
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	9/14/01		ZNO		Creation
	1/20/2004	ZNO		Took out fractional penny check
------------------------------------------------------------------------*/
function isMoney(r_oField) {
	var lMoney = r_oField.value;
	if (parseFloat(lMoney) != lMoney * 1) {
		return false;	// non-numeric values in field
	}
	return true;
}

/*------------------------------------------------------------------------
	Name: 		isCCN()
	Purpose: 	do Mod10 check on CCN
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	10/12/00	ZNO		Creation
------------------------------------------------------------------------*/
function isCCN(r_oField) {
	var sCCN = toNumeric(r_oField.value)
	
	// temp validation to check out with test CCN
	var re = /^41{14,15}$/;
	if (re.test(sCCN)) { return true; }
	// end temp stuff ---------------------------
	
	var re = /^\d{15,16}$/;
	// fail if wrong length
	if (!(re.test(sCCN))) {	return false; }

	var lLength = sCCN.length;
  	var bEven = lLength & 1;
	var lCheckSum = 0;

	for (var i = 0; i < lLength; i++) {
		var thisNum = parseInt(sCCN.charAt(i));
		if (!((i & 1) ^ bEven)) {
			thisNum *= 2;
			if (thisNum > 9) { thisNum -= 9; }
		}
		lCheckSum += thisNum;
	}
	// fail if non-zero Mod10
	if (lCheckSum % 10 != 0) { return false; }
	return true;
}

/*------------------------------------------------------------------------
	Name: 		isStoreNo()
	Purpose: 	validate store # against list in hidden frame
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	11/13/00	ZNO		Creation
------------------------------------------------------------------------*/
function isStoreNo(r_oField) {
	var oForm = window.parent.data.frmData;
	var sStoreList = oForm.storelist.value;
	return sStoreList.search(","+r_oField.value+",") != -1 ? true : false; 
}

/*------------------------------------------------------------------------
	Name: 		toNumeric()
	Purpose: 	converts a field to all numbers
	Return:		number
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
	7/12/02		ZNO		updated to regexp
------------------------------------------------------------------------*/
function toNumeric(v_sField) { return v_sField.replace(/\D/g, ""); }

/*------------------------------------------------------------------------
	Purpose: 	basic regular expression pattern checks
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
	5/23/01		ZNO		Organization ID check
	6/24/02		ZNO		CVV check
------------------------------------------------------------------------*/
function TestField(r_oField, r_oRE) {	return r_oRE.test(r_oField.value); }
function isPassword(r_oField) {			return TestField(r_oField, /^.{4,10}$/); }
function isOrganization(r_oField) {		return TestField(r_oField, /^(\d+)$/); }
function isCVV(r_oField) {				return TestField(r_oField, /\d{3,4}/); }
function isUsername(r_oField) {			return TestField(r_oField, /^[a-zA-Z0-9_\-'\.]{4,10}$/); }
function isPrescNo(r_oField) { 			return TestField(r_oField, /^(\d{4,})$/); }
function isPharmNo(r_oField) { 			return TestField(r_oField, /^(\d+)$/); }
function isEmail(r_oField) { 			return TestField(r_oField, /^([\w\._\-]+@[\w\-]+\.[\w\-]+\.*[\w\-]*.*[\w\-]*)$/); }
function isZip(r_oField) {				return TestField(r_oField, /^(\d{5})$/); }
function isZip4(r_oField) {				return TestField(r_oField, /^(\d{4})$/); }
function isNumeric(r_oField) {			return TestField(r_oField, /^(\d+)$/); }
function isURL(r_oField) {				return TestField(r_oField, /\.\w{2,3}\/?/); }

/*------------------------------------------------------------------------
	Purpose: 	customized checks
	Return:		boolean
Modifications:
	Date:		Name:	Description:
	7/27/00		ZNO		Creation
	8/25/00		ZNO		SSN check
	7/24/01		ZNO		Range check
	8/29/02		ZNO		Preferred Savings Card check and postal code wrapper functions
------------------------------------------------------------------------*/
function isInRange(r_oField) { return (r_oField.value >= m_lRangeLow && r_oField.value <= m_lRangeHigh); }
function isPSC(r_oField) { var sPSC = toNumeric(r_oField.value); return (sPSC.length == 11); }
function isPhone(r_oField) { var sPhone = toNumeric(r_oField.value); return (sPhone.length == 10); }
function isSSN(r_oField) { var sSSN = toNumeric(r_oField.value); return (sSSN.length == 9); }
function isString(r_oField) { return (r_oField.value != ""); }
function isPostal(r_oField) { return isZip(r_oField); }
function isPostal4(r_oField) { return isZip4(r_oField); }