///////////////////////////////////////////////////////////////////////////
// validate.js
// Functions for validating HTML form fields
// Michael Moyer
//
//
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
function autoVal (valForm) {
	var errMsg = new Array();
	var errNum = 0;
	var warnMsg = new Array();
	var warnNum = 0;
	var errElt;
	
	initValidate(errMsg);
	initWarnings(warnMsg);

	for (x = 0; x < valForm.elements.length; x++) {
	// FIRST LOOP - Check required fields
		if (valForm.elements[x].inputType == "select") {
			if (getSelected (valForm.elements[x]) == "-1") {
				alert ("You must complete all required fields");
				return false;
			}
		}
		if (valForm.elements[x].required == 1) {
			if (valForm.elements[x].inputType != "select") {
				if (isBlankElt (valForm.elements[x])) {
					alert ("You must complete all required fields");
					return false;
				}
			}
			else if (valForm.elements[x].inputType == "select") {
				if (getSelected (valForm.elements[x]) == "1001") {
					alert ("You must complete all required fields");
					return false;
				}
			}
		}
	}

	for (x = 0; x < valForm.elements.length; x++) {
	// SECOND LOOP - Check for valid data
		if (valForm.elements[x].inputType == "price") {
			if (valForm.elements[x].alt != "undefined") {
				if (valForm.elements[x].value != valForm.elements[x].alt && valForm.elements[x].value != "" && !isPrice(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid price");
					errNum++;
				}
			}
			else {
				if (valForm.elements[x].value != "" && !isPrice(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid price");
					errNum++;
				}
			}
		}
		if (valForm.elements[x].inputType == "int") {
			if (valForm.elements[x].alt != "undefined") {
				if (valForm.elements[x].value != valForm.elements[x].alt && valForm.elements[x].value != "" && !isInt(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid integer");
					errNum++;
				}
			}
			else {
				if (valForm.elements[x].value != "" && !isInt(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid integer");
					errNum++;
				}
			}
		}
		if (valForm.elements[x].inputType == "year") {
			if (valForm.elements[x].alt != "undefined") {
				if (valForm.elements[x].value != valForm.elements[x].alt && valForm.elements[x].value != "" && !isYear(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid year");
					errNum++;
				}
			}
			else {
				if (valForm.elements[x].value != "" && !isYear(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid year");
					errNum++;
				}
			}
		}
		if (valForm.elements[x].inputType == "email") {
			if (valForm.elements[x].alt != "undefined") {
				if (valForm.elements[x].value != valForm.elements[x].alt && valForm.elements[x].value != "" && !isEmail(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "You have entered an invalid e-mail address");
					errNum++;
				}
			}
			else {
				if (valForm.elements[x].value != "" && !isEmail(valForm.elements[x].value, errMsg)) {
					errElt = valForm.elements[x].name.substr(2);
					errElt = errElt.replace (/_/g," ");
					fillErrors(errMsg, "'"+ errElt +"' is not a valid e-mail address");
					errNum++;
				}
			}
		}
	}

	if (errNum) {
		printErr(errMsg);
		return false;
	}
/*
	for (x = 0; x < valForm.elements.length; x++) {
	// THIRD LOOP - Check for warnings
		if (valForm.elements[x].required == 2) {
			if (valForm.elements[x].inputType != "select") {
				if (isBlankElt (valForm.elements[x])) {
					fillErrors(warnMsg, valForm.elements[x].name);
					warnNum++;
				}
			else if (valForm.elements[x].inputType == "select") {
				if (getSelected (valForm.elements[x]) == "1001") {
					fillErrors(warnMsg, valForm.elements[x].name);
					warnNum++;
				}
			}
		}
	}

	if (warnNum) {
		return confirm(warnMsg);
	}
*/
	return true;
}

///////////////////////////////////////////////////////////////////////////
function initValidate (errMsg) {
// Takes an array, the first element of which will contain a list of error
// messages.
	errMsg[0] = "The following errors were encountered while processing your form:\n";
	errMsg[0] += "____________________________________________________\n\n";
	errMsg[1] = "";
}

///////////////////////////////////////////////////////////////////////////
function initWarnings (warnMsg) {
// Takes an array, the first element of which will contain a list of error
// messages.
	warnMsg[0] = "Are you sure you wish to leave the following fields blank?\n";
	warnMsg[0] += "____________________________________________________\n\n";
	warnMsg[1] = "";
}

///////////////////////////////////////////////////////////////////////////
function getSelected (selectElt) {
// Returns the selected value of a SELECT input
	for (i = 0; i < selectElt.options.length; i++) {
		if (selectElt.options[i].selected)
			return selectElt.options[i].value;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////
function isBlankElt (s) {
// Returns true if element s contains only blank spaces
	if (s.value == "") {
		return true;
	}
	else {
		for (var i=0; i<s.value.length; i++) {
			var c = s.value.charAt(i);
			if ((c!=' ') && (c!='\n') && (c!='\t')) {
				return false;
			}
		}
		return true;
	}
}

///////////////////////////////////////////////////////////////////////////
function makeDBDate (monthElt, yearElt) {
	var month = getSelected(monthElt);
	var year = getSelected(yearElt);
	return (month + "/1/" + year);
}

///////////////////////////////////////////////////////////////////////////
function containsQuotes (s) {
// Returns true if string s contains single or double quotes
	if (s.search(/['"]/) == -1)
		return false;

	return true;
}

///////////////////////////////////////////////////////////////////////////
function isInt (s) {
// Returns true if string s is an integer.
	if (s == "" || s.search(/[\d]+[\s]+[\d]+/) != -1)
		return false;
		
	s = s.replace (/[\s]*/g, "");

	if (s.search(/[\D]/) != -1)
		return false;
	return true;
}

///////////////////////////////////////////////////////////////////////////
function isEmail (s) {
// Returns true if string s is a valid e-mail address.
	if (s == "")
		return false;

	s = s.replace (/[\s]*/g, "");
	
	if (s.search(/^[\S]+@[\S]+[\.][\S]+$/) == -1)
		return false;
	return true;
}

///////////////////////////////////////////////////////////////////////////
function isPrice (s) {
// Returns true if string s is a valid price.
	if (s == "")
		return false;

	s = s.replace (/[\s]*/g, "");

	if (s.search(/^[$]?[\d]+[\.]?[\d]{0,2}$/) == -1)
		return false;
	return true;
}

///////////////////////////////////////////////////////////////////////////
function isYear(d, errMsg) {
	var errNum = 0;
	if (d == "")
		return false;

	if (d.search(/\d{2,4}/) != -1) {
		if (0 <= d && d <= 50)
			d = d + 2000;
		else if (51 <= d && d <= 99)
			d = d + 1900;
		else if (1800 <= d && d <= 2100)
			d = d;
		else
			errNum++;
	}
	else
		errNum++;

	return !errNum;
}

///////////////////////////////////////////////////////////////////////////
function getMonth (d) {
// Returns the month from a properly formatted date string.
	var splitDate = d.split("/");
	return parseInt(splitDate[0], 10);
}

///////////////////////////////////////////////////////////////////////////
function getDay (d) {
// Returns the day from a properly formatted date string.
	var splitDate = d.split("/");
	return parseInt(splitDate[1], 10);
}

///////////////////////////////////////////////////////////////////////////
function getYear (d) {
// Returns the 4-digit year from a properly formatted date string.
	var splitDate = d.split("/");
	var year = parseInt(splitDate[2], 10);
	if (0 <= year && year <= 50) {
		year = year + 2000;
	}
	else if (51 <= year && year <= 99) {
		year = year + 1900;
	}	
	return year;
}

///////////////////////////////////////////////////////////////////////////
function isValidDate (d, errMsg) {
// Returns true if element d contains a correctly formatted, valid date
// ("MM/DD/YY").  Otherwise returns false and errors are concatenated to
// errMsg[1].

	var date = new Date(d.value);

	alert(date.toString());

	if (date.toString() == "NaN")
		return false;

//	date.setYear(getYear(d.value));

	if (1900 > date.getFullYear() || date.getFullYear() > 2100)
		return false;

	d.value = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
	return true;
}

///////////////////////////////////////////////////////////////////////////
function isBefore (d1, d2, errMsg) {
// Returns 1 if date d1 precedes date d2.  Returns 0 otherwise, or if the 
// dates are illegal.
	if (isValidDate(d1, errMsg) && isValidDate(d2, errMsg)) {
		var date1 = new Date(d1.value);
		var date2 = new Date(d2.value);
		return (date1 < date2);
	}
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////
function isDateFuture (d, errMsg) {
	if (isValidDate(d, errMsg)) {
		var date1 = new Date(d.value);
		var date2 = new Date();
		return (date1 > date2);
	}
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////
function getDateFromTime (t) {
	var date = t.replace(/\s*\d*\s*:\s*\d*\s*[AP]M\s*/, "");
	date = date.replace (/[\s]*/g, "");
	return date;
}

///////////////////////////////////////////////////////////////////////////
function getTime (t) {
	var time = t.replace(/\s*\d*\s*\/\s*\d*\s*\/\d*\s*/, "");
	time = time.replace (/[\s]*/g, "");
	return time;
}

///////////////////////////////////////////////////////////////////////////
function getHour (t) {
	var splitTime = t.split(":");
	return parseInt(splitTime[0], 10);
}

///////////////////////////////////////////////////////////////////////////
function getMinute (t) {
	var splitTime = t.split(":");
	var min = splitTime[1].slice(0,2);
	return parseInt(min, 10);
}

///////////////////////////////////////////////////////////////////////////
function getAMPM (t) {
	var splitTime = t.split(":");
	var ampm = splitTime[1].slice(2,4);

	if (ampm == "AM" || ampm == "am" || ampm == "Am" || ampm == "aM")
		return "AM";
	else
		return "PM";
}

///////////////////////////////////////////////////////////////////////////
function isValidDateTime (d, errMsg) {
// Returns true if d contains a valid date-time string in the format
// MM/DD/YYYY HH:MM XM.

	var date;
	var time;
	var numErr = 0;

// Extract the date and time from string d.
	date = getDateFromTime(d);
	time = getTime(d);

// Make sure the date is correctly formatted and valid.
	if (!isValidDate(date, errMsg))
		numErr++;


// Make sure the time is correctly formatted.
	if (time.search(/\d{1,2}:\d{2,2}[AaPp][Mm]/) != -1) {

// Check that the time is valid;
		if (getHour(time) >= 1 && getHour(time) <= 12 && getMinute(time) >= 0 && getMinute(time) < 60) {
		}
		else {
//			fillErrors (errMsg, 5);
			numErr++;
		}
	}
	else {	
//		fillErrors (errMsg, 4);
		numErr++;
	}
	return !numErr;
}

///////////////////////////////////////////////////////////////////////////
function isBeforeTime (t1, t2, errMsg) {
// Returns 1 if time t1 precedes time t2.  Returns 0 otherwise, or if the 
// dates/times are illegal.
	if (isValidDateTime(t1, errMsg) && isValidDateTime(t2, errMsg)) {

		var date1 = getDateFromTime(t1);
		var date2 = getDateFromTime(t2);
		var time1 = getTime(t1);
		var time2 = getTime(t2);

		// Create two Date objects containing the date info.
		
		theHour1 = getHour(time1);
		theHour2 = getHour(time2);
		
		if (getAMPM(time1) == "AM") {
			if (theHour1 == 12)
				theHour1 = 0;
			var d1 = new Date(getYear(date1), getMonth(date1) - 1, getDay(date1), theHour1, getMinute(time1));
		}
		else
			var d1 = new Date(getYear(date1), getMonth(date1) - 1, getDay(date1), theHour1 + 12, getMinute(time1));
			
		if (getAMPM(time2) == "AM") {
			if (theHour2 == 12)
				theHour2 = 0;
			var d2 = new Date(getYear(date2), getMonth(date2) - 1, getDay(date2), theHour2, getMinute(time2));
		}
		else
			var d2 = new Date(getYear(date2), getMonth(date2) - 1, getDay(date2), theHour2 + 12, getMinute(time2));

		// Compare the date objects.
		if (d1 < d2)
			return 1;
		else {
//			fillErrors (errMsg, 6);
			return 0;
		}
	}
	else {
		return 0;
	}
}

///////////////////////////////////////////////////////////////////////////
function isDateAfterNow (d, errMsg) {
// Returns 1 if date d is after the current date
	if (isValidDate(d, errMsg)) {
		
		// Create two Date objects containing the date info.
		var date1 = new Date(getYear(d), getMonth(d) - 1, getDay(d));
		var date2 = new Date();

		// Compare the date objects.
		if (date1 > date2)
			return true;
		else {
//			fillErrors(errMsg, 7);
			return false;
		}
	}
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////
function isTimeAfterNow (t1, errMsg) {
// Returns true if time t1 precedes now.
	if (isValidDateTime(t1, errMsg)) {

		var date1 = getDateFromTime(t1);
		var time1 = getTime(t1);

		// Create two Date objects containing the date info.
		if (getAMPM(time1) == "AM")
			var d1 = new Date(getYear(date1), getMonth(date1) - 1, getDay(date1), getHour(time1), getMinute(time1));
		else
			var d1 = new Date(getYear(date1), getMonth(date1) - 1, getDay(date1), getHour(time1) + 12, getMinute(time1));

		var d2 = new Date();

		// Compare the date objects.
		if (d1 > d2)
			return true;
		else {
//			fillErrors (errMsg, 6);
			return false;
		}
	}
	else {
		return false;
	}
}

///////////////////////////////////////////////////////////////////////////
function fillErrors (errMsg, errorType) {
// Populates the errMsg array;
// 1 - Not all fields filled in
// 2 - Improperly formatted date
// 3 - Invalid date
// 4 - Improperly formatted time
// 5 - Invalid time
// 6 - End date precedes start date
// 7 - Date entered has already passed

	if (errorType == 1)
		errMsg[1] += "You have not completed all required fields\n";
	else if (errorType == 2)
		errMsg[1] += "All dates must be in the format MM/DD/YYYY\n";
	else if (errorType == 3)
		errMsg[1] += "You have entered an invalid date\n";
	else if (errorType == 4)
		errMsg[1] += "All times must be in the format MM/DD/YYYY HH:MM AM/PM\n";
	else if (errorType == 5)
		errMsg[1] += "You have entered an invalid time\n";
	else if (errorType == 6)
		errMsg[1] += "The end date you have entered precedes the start date\n";
	else if (errorType == 7)
		errMsg[1] += "The date you have entered has already passed\n";
	else
		errMsg[1] += errorType + "\n";
}

///////////////////////////////////////////////////////////////////////////
function printErr (errMsg) {
	alert (errMsg[0] + errMsg[1]);
}
