/* **********************************************************************
 * 
 * File:	validation.js
 * Date:	August 9, 2001
 * Author:	Rodney M. Chun
 * Desc:	External client-side JavaScript that validates user input.
 *		Requires browser with JS 1.1 or higher. However, constructs
 *		from JS version 1.2 not used.
 *		
 *		The following functions are performed by this code:
 *		1) Initialization of date input.
 *		2) Validation of user date input (e.g. disallow Feb 31.)
 * 		3) Validation of user text input by screening out 'bad' 
 *		characters such as meta characters.  If such violations
 * 		are found, script informs user and asks for modification
 *		in the input.
 *
 ***********************************************************************/


/* Function Name: 	initDate
 * -----------------------------
 * Function that sets the default dates in the date combo-boxes.  The default start
 * date is the current date.  The default end date is 6 days later.  This
 * function is form specific since it sets specific form.element[i] values.
 * Hence, if the form changes -- in particular the order or number of the combo-box
 * items -- this function will need to be modified accordingly.
 */
function initDate(form)
{
	var now = new Date();
	var endDate = new Date();
	var dayoffset = 6;
	var day, month, year, eday, emonth, eyear;

	//  To set start date to any arbitrary date, uncomment next 4 lines, 
	//  and set date to whatever you like.
	// 1. var semesterDate = new Date(2001, 00, 01);	// set to beginning of term (YYYY,MM,DD).
	// 2. month = semesterDate.getMonth();		// recall JS months are zero-based.
	// 3. day = semesterDate.getDate();
	// 4. year = semesterDate.getFullYear();

	month = now.getMonth();
	day = now.getDate();
	year = now.getFullYear();

	// Set default end-date.  Use the millisecond format to handle potential problem
	// where end-date falls in month/year other than that of the start date.
	endDate.setTime(now.getTime() + (dayoffset * 24*60*60*1000));
	emonth = endDate.getMonth();
	eday = endDate.getDate();
	eyear = endDate.getFullYear();

	form.startmonth[month].selected = true;			// set form's start-fields.
	form.startday[day - 1].selected = true;			// convert to zero-base.
	form.startyear[year - 2001].selected = true;		// convert to zero-base.

	form.endmonth[emonth].selected = true;			// set form's end-fields.
	form.endday[eday - 1].selected = true;
	form.endyear[eyear - 2001].selected = true;
}

/* Function Name: 	getDaysInMonth
 * -----------------------------
 * Function that returns the maximum number of days in the named-month which
 * -- of course -- depends on the year too.  Note that months are numbered 
 * from a zero-base so January == 0 in Javascript.  Better to use 'switch'
 * statement to determine days in each month, but this would require browsers
 * supporting JS 1.2, or higher.
 */
function getDaysInMonth(year, month)
{
	var month30 = new Array(3,5,8,10);			// months with 30 days.
	var month31 = new Array(0,2,4,6,7,9,11);	// months with 31 days.
	var i;

	if (month == 1) {							// special case of February
		if (((year%4 == 0) && (year%100 != 0)) || (year%400 == 0)) return (29);
		else return (28);
	}

	for (i=0; i<month30.length; i++) {
		if (month == month30[i]) return (30);
	}	

	for (i=0; i<month31.length; i++) {
		if (month == month31[i]) return (31);
	}	
}


/* Function Name: 	checkDate
 * -----------------------------
 * Function that checks for errors in the two date fields on form.  The following
 * steps occur here:
 * 1) check that each indicated date is a 'valid' date (i.e. no February 31).
 * 2) if they are valid, convert each date to a date object using makeDate.
 * 3) compare start to end to guarantee order is start < end.
 * 4) return an error string with any details of problems discovered along the way.
 */
function checkDate(form)
{
	var errors = "";
	var tabStr = "     ";						// 5 spaces to simulate tab.
	var maxDays;								// maximum number of days in given month.
	var start = new Date();
	var end = new Date();

	maxDays = getDaysInMonth(form.startyear[form.startyear.selectedIndex].value,
							form.startmonth[form.startmonth.selectedIndex].value - 1);
	if (form.startday[form.startday.selectedIndex].value > maxDays) {
		errors += tabStr + "Start date is not valid.  Please re-enter start date.\n\n";
	}

	maxDays = getDaysInMonth(form.endyear[form.endyear.selectedIndex].value,
							form.endmonth[form.endmonth.selectedIndex].value - 1);
	if (form.endday[form.endday.selectedIndex].value > maxDays) {
		errors += tabStr + "End date is not valid.  Please re-enter end date.\n\n";
	}

	if (errors.length == 0) {			// dates did not exceed end of month.
		start = makeDate(form.startmonth[form.startmonth.selectedIndex].value - 1, 
							form.startday[form.startday.selectedIndex].value, 
							form.startyear[form.startyear.selectedIndex].value);
		end = makeDate(form.endmonth[form.endmonth.selectedIndex].value - 1, 
							form.endday[form.endday.selectedIndex].value, 
							form.endyear[form.endyear.selectedIndex].value);

		if (start.getTime() > end.getTime()) {
			errors += tabStr + "Start must specify a date *before* the end date.\n\n";
		}
	}
	return(errors);
}


/* Function Name: 	makeDate
 * Usage:			startDate = makeDate(MM, DD, YYYY);
 * -----------------------------
 * Function that takes date strings and returns a date object.  There are 3 arguments,
 * mstr, dstr, ystr which are strings for the month, day, and year respectively.  Here
 * a value of MM = 1 corresponds to January.
 */
function makeDate(month, day, year)
{
	var now = new Date();

	now.setFullYear(year);		// must set year first to correctly set leap-years.
	now.setMonth(month);		// note: months in JS are zero-based.
	now.setDate(day);
	return (now);
}


/* Function Name: 	checkStr
 * -----------------------------
 * Reusable function that checks for illegal characters in the text input.
 * The two arguments are 1) the string to check and 2) the string that defines the
 * illegal characters.  If the function detects an illegal character in the input
 * string, it returns an appropriate message.  If no illegal characters found, then
 * an empty string is returned.
 */
function checkStr(str, badCharStr)
{
	var tabStr = "     ";
	var currErrStr = "";
	var i;

	for (i=0; i<badCharStr.length; i++) {
		if (str.indexOf(badCharStr.charAt(i)) != -1) {
			currErrStr += tabStr + "Illegal character, " + badCharStr.charAt(i) + " .\n";
		} 
	}
	return currErrStr;
}


/* Function Name: 	checkText
 * -----------------------------
 * Function that checks the form's text fields for proper input (if any).  We
 * exclude any meta and path characters in the search string(s) for security reasons.
 * The two fields checked are the name strings and keyword strings.  Function 
 * returns an error string with problems (if any) that were detected.
 */
function checkText(form)
{
	var tabStr = "     ";
	var NL = "\n";
	var errFirst = "";
	var errLast = "";
	var errKey = "";
	var errors = "";
	var badChars = "\\:;<>?/{}[]|!@#$%^&()_+=~`";	// illegal characters.
						// allow ".-,'* and blanks, plus alphanumeric.
	if (form.lastname.value != "") {
		form.lastname.value = trim(form.lastname.value);
		errLast = checkStr(form.lastname.value, badChars);
		if (errLast.length > 0) {
			errors += tabStr + "Error(s) in last name" + NL + errLast + NL ;
		}
	}

	/***  First name input element removed from searchform -- do not check any more.
	if (form.firstname.value != "") {
		form.firstname.value = trim(form.firstname.value);
		errFirst = checkStr(form.firstname.value, badChars);
		if (errFirst.length > 0) {
			errors += tabStr + "Error(s) in first name" + NL + errFirst + NL ;
		}
	}
	*********/

	if (form.keytitle.value != "") {
		form.keytitle.value = trim(form.keytitle.value);
		errKey = checkStr(form.keytitle.value, badChars);
		if (errKey.length > 0) {
			errors += tabStr + "Error(s) in title keyword(s)" + NL + errKey + NL ;
		}
	}
	if (form.keyabstract.value != "") {
		form.keyabstract.value = trim(form.keyabstract.value);
		errKey = checkStr(form.keyabstract.value, badChars);
		if (errKey.length > 0) {
			errors += tabStr + "Error(s) in abstract keyword(s)" + NL + errKey + NL;
		}
	}
	return (errors);
}

/* Function Name: 	checkForm
 * -----------------------------
 * Function that does some housecleaning before sending form off to
 * the response page, 1SearchResponse.asp.  In particular, function
 * checks for user input in fields.  If there is none, then simply sets
 * default values.
 */
function checkForm(form)
{
	var OKForm = true;
	var errStr = "";

	// error check for illegal dates and unordered dates.
	errStr += checkDate(form);

	// error check text fields in form. Filter out all meta & system path characters.
	errStr += checkText(form);

	if (errStr.length > 0) {
		alert("Input errors detected.  Please correct and resubmit form.\n\n" + errStr);
		return false;
	} else {
		return OKForm;				// User input passed all tests, allow form to be submitted.
	}
}

