//
// Copyright 2005 by Jeff Krause
//
//	dt_parseDate(text,min,max) 
//		return Array ( errorText, month {1..12}, date {1..31}, year {min .. max} );
//		in case of error rest of array is set to 0
//
//	dt_todayText(format)
//								// format is ignored for now
//		return string			// in format of "July 12, 2003"
//
//	dt_monthText(m [1..12], fShort )
//		return string			// in format of "September" or "Sep"
//
//	dt_dayText (d [1..7], fShort )
//		return string			// in format of "Sunday" or "Sun" for d = 1
//
//	dt_fLeapYear (y)
//		return boolean			// true or false
//

var dt_rgMonthNames = new Array("Invalid Month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
var dt_rgDayNames = new Array("Invalid Weekday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");


function dt_todayText(format) {
	var today = new Date();
	var iMonth = today.getMonth();
	var iDate = today.getDate();
	var iYear = today.getFullYear();
	return dt_monthText(iMonth+1) + " " + iDate + ", " + iYear;
	}

function dt_monthText(m, f) {
	var m;
	if ((m < 1) || (m > 12)) m = 0;
	if ((f) && (m > 0)) return dt_rgMonthNames[m].slice(0,2);
	else return dt_rgMonthNames[m];
	}

function dt_dayText(d, f) {
	var d;
	if ((d < 1) || (d > 7)) d = 0;
	if ((f) && (d > 0)) return dt_rgDayNames[d].slice(0,2);
	else return dt_rgDayNames[d];
	}

function dt_fLeapYear(y) {
	var y;
	if (y%4 != 0) { return false }		// not a fourth year
	if (y%400 == 0) { return true }		// every 400th year is a leap year
	if (y%100 == 0) { return false }	// every 100th year is not a leap year
	return true;
	}

function dt_parseDate(sbInputString,yMin,yMax,yBorder) {
	var today = new Date();
	var sbString = sbInputString;
	var fDebug = false;
	var sbError = "";
	var sbWarning = "";
	var rgDate = new Array;
	var rgTokens = new Array;
	var rgfAlphaArr = new Array;
	var nTokens;
	var iToken=0;
	var iString=0;
	var fFoundTok=false;
	var fLastAlpha=false;
	var fLastNumeric=false;
	var ch="";
	var yy=0;
	var mm=0;
	var dd=0;
	
	if (yBorder == null) yBorder = today.getFullYear() - 2000 + 10;
	rgDate[0]="";	// error
	rgDate[1]=0;	// month
	rgDate[2]=0;	// date
	rgDate[3]=0;	// year
	rgDate[4]=0;	// fAlpha error flag if single token
	rgDate[5]=0;	// token if its a single token
	rgDate[6]=0;	// fAddedYear if not specified
	rgDate[7]=0;	// fCorrectedYear to 19xx or 20xx if less than 100
	
	while (iString < sbString.length) {
		ch = sbString.charAt(iString++).toLowerCase();
		if ((ch >= "a") && (ch <= "z")) {
			if ((fFoundTok) && (fLastAlpha)) {
				rgTokens[iToken] += ch;
				}
			else if ((fFoundTok) && (fLastNumeric)) {
				iToken++;
				rgTokens[iToken] = ch;
				rgfAlphaArr[iToken] = true;
				fLastAlpha = true;
				fLastNumeric = false;
				}
			else if (!fFoundTok) {
				rgTokens[iToken] = ch;
				rgfAlphaArr[iToken] = true;
				fFoundTok = true;
				fLastAlpha = true;
				fLastNumeric = false;
				}
			}
		else if ((ch >= "0") && (ch <= "9")) {
			if ((fFoundTok) && (fLastNumeric)) {
				rgTokens[iToken] += ch;
				}
			else if ((fFoundTok) && (fLastAlpha)) {
				iToken++;
				rgTokens[iToken] = ch;
				rgfAlphaArr[iToken] = false;
				fLastAlpha = false;
				fLastNumeric = true;
				}
			else if (!fFoundTok) {
				rgTokens[iToken] = ch;
				rgfAlphaArr[iToken] = false;
				fFoundTok = true;
				fLastAlpha = false;
				fLastNumeric = true;
				}
			}
		else {
			if (fFoundTok) { iToken++ }
			fFoundTok = false;
			fLastAlpha = false;
			fLastNumeric = false;
			}
		}

	nTokens = rgTokens.length;

	sbError += nTokens;
	sbError += ":(";

	iToken = 0;
	while (iToken < nTokens) {
		if (iToken > 0) {
			sbError += ",";
			}
		sbError += rgTokens[iToken++];
		}
	sbError += ") ";

//
// must be at least two tokens for month, day.  Might not be a year, others ignored
//
	if (nTokens < 2) {						// might be a name, who knows.  flag if its an alpha and put token in array
		if (!fDebug) { sbError = "" }
		sbError += "Invalid date";
		rgDate[0]=sbError;
		if (nTokens > 0) {
			rgDate[4] = rgfAlphaArr[0];
			rgDate[5] = rgTokens[0];
			}
		return rgDate;
		}

	else if (nTokens == 2) {								// assume no year, add current year
		var today = new Date();
		rgTokens[2] = today.getFullYear();
		rgfAlphaArr[2] = false;
		nTokens++;
		rgDate[6] = true;
		}

	yy = parseInt(rgTokens[2],10);
	if (yy < 0) {}											// this error will get caught later, ignore
	else if ((yy < 100) && (rgTokens[2].length == 2))	 {		// try and get correct date for 2 digits
		if (yy > yBorder) yy += 1900;
		else yy += 2000;
		rgDate[7] = true;
		}

	sbError += " " + yy + " ";
//
// check year range
//
	if ((rgfAlphaArr[2]) || (yy < yMin) || (yy > yMax)) {
		if (!fDebug) { sbError = "" }
		sbError += 'Year must be between ' + yMin + ' and ' + yMax;
		rgDate[0]=sbError;
		return rgDate;
		}
//
// Only month can be alpha
//
	
	if (rgfAlphaArr[0] && rgfAlphaArr[1]) {
		if (!fDebug) { sbError = "" }
		sbError += 'Invalid month/day';
		rgDate[0]=sbError;
		return rgDate;
		}	
	else if (rgfAlphaArr[0]) {
		mm = dt_convertMonth(rgTokens[0]);
		dd = parseInt(rgTokens[1],10);
		sbError += "rgfAlphaArr[0]";
		}
	else if (rgfAlphaArr[1]) {
		mm = dt_convertMonth(rgTokens[1]);
		dd = parseInt(rgTokens[0],10);
		sbError += "rgfAlphaArr[1]" + rgTokens[1] + "," + mm + "," + rgTokens[0] + "," + dd + "; ";
		}
	else {
		mm = parseInt(rgTokens[0],10);
		dd = parseInt(rgTokens[1],10);
		sbError += "rgfAlphaArr[2]:" + rgTokens[0] + "," + mm + "," + rgTokens[1] + "," + dd + "; ";
		}
	sbError += mm;
//
// allow for reverse entry if dates make sense
//
	if ((mm > 12) && (dd < 13)) {
		var tmp
		tmp = mm;
		mm = dd;
		dd = tmp;
		sbError += "swap";
		}

	if ((dd == 0) || (mm == 0) || (mm > 12)) {
		if (!fDebug) { sbError = "" }
		sbError += 'Invalid month/day';
		rgDate[0]=sbError;
		return rgDate;
		}
//
// check validity of number of days in month (already know dd > 0)
//
	if (mm == 2) {															// Feb
		var fLeap = dt_fLeapYear(yy);
		sbError += " " + dt_fLeapYear(yy) + " ";
		if (fLeap && (dd > 29)) {
			sbWarning += "(" + dt_monthText(mm) + ' ' + yy + ' has only 29 days)';
			dd=29;
			}
		else if (!fLeap && (dd > 28)) {
			sbWarning += "(" + dt_monthText(mm) + ' ' + yy + ' has only 28 days)';
			dd=28;
			}
		}
	else if ((mm == 4 || mm == 6 || mm == 9 || mm == 11) && (dd >= 31)) {	// Apr, Jun, Sep, Nov
		sbWarning += "(" + dt_monthText(mm) + ' has only 30 days)';
		dd=30;
		}
	else if (dd > 31) {														// Jan, Mar, May, Jul, Aug, Oct, Dec
		sbWarning += "(" + dt_monthText(mm) + ' has only 31 days)';
		dd=31;
		}

	sbError += "[" + mm + '/' + dd + '/' + yy + "]";
	if (!fDebug) { sbError = "" }  // no errors
	if ( sbWarning != "" ) sbError += sbWarning;
	
	rgDate[0]=sbError;
	rgDate[1]=mm;
	rgDate[2]=dd;
	rgDate[3]=yy;
	return rgDate;
	}

function dt_convertMonth(mt) {
	var iMt = 0;
	var ch1="";
	var ch2="";
	var ch3="";
	if (mt.length > 0) { ch1 = mt.charAt(0) }
	if (mt.length > 1) { ch2 = mt.charAt(1) }
	if (mt.length > 2) { ch3 = mt.charAt(2) }
	
	if (ch1 == "f") { return 2 }			// February
	else if (ch1 == "s") { return 9 }		// September
	else if (ch1 == "o") { return 10 }		// October
	else if (ch1 == "n") { return 11 }		// November
	else if (ch1 == "d") { return 12 }		// December
	else if (ch1 == "j") {
		if (ch2 == "a") { return 1 }		// January
		else if (ch2 != "u") { return 0 }
		else if (ch3 == "n") { return 6 }	// June
		else if (ch3 == "l") { return 7 }	// July
		}
	else if (ch1 == "m") {
		if (ch2 != "a") { return 0 }
		else if (ch3 == "r") { return 3 }	// March
		else if (ch3 == "y") { return 5 }	// May
		}
	else if (ch1 == "a") {
		if (ch2 == "p") { return 4 }		// April
		else if (ch2 == "u") { return 8 }	// August
		}
	return 0;
	}

