// Note: Date.setFullYear() requires JavaScript 1.2.
// This file containts date code for:
// 1) client-side validations, and
// 2) interaction with report package (Crystal at the moment)
//    such that the other files need not change if the report package changes
// When used for client-side validations, it requires validate.js.
// Constants, configurable values, and values that would change for 
// internationalization appear at the top.
// Parameters for date handling follow here.
// Dates must be in three "components" (e.g., year and month and day) but it's
// flexible as to the order; to change that, 
// specify it in the order and picture config items, and the function
// getDisplayDateFromDate() below:
// Date order: After date is parsed (split on delimiters), 
// the array elements will be, for format 06-31-1999: 0=06; 1=31; 2=1999,
// so specify which position represents each of year, month, and day.


// YEAR [getYear] Apply y2k Hack        
var now = new Date();
var year = now.getYear();
var syear = year - 2000;
if (year < 2000) year = year + 1900;//@-y2k hack
// abbreviated,shortened,condensed,truncated,reduced DAY NAMES == 'abbrevDayNames';
var abbrevDayNames = new Array();
abbrevDayNames[0] = "Su";
abbrevDayNames[1] = "Mo";
abbrevDayNames[2] = "Tu";
abbrevDayNames[3] = "We";
abbrevDayNames[4] = "Th";
abbrevDayNames[5] = "Fr";
abbrevDayNames[6] = "Sa";
// SHORT DAY NAMES == 'shortDayNames';
var shortDayNames = new Array();
shortDayNames[0] = "Sun";
shortDayNames[1] = "Mon";
shortDayNames[2] = "Tue";
shortDayNames[3] = "Mon";
shortDayNames[4] = "Thur";
shortDayNames[5] = "Fri";
shortDayNames[6] = "Sat";
// LONG DAY NAMES == 'longDayNames';
var longDayNames = new Array();
longDayNames[0] = "Sunday";
longDayNames[1] = "Monday";
longDayNames[2] = "Tuesday";
longDayNames[3] = "Wednesday";
longDayNames[4] = "Thursday";
longDayNames[5] = "Friday";
longDayNames[6] = "Saturday";
// SHORT MONTH NAMES == 'shortMonthNames';
var shortMonthNames = new Array();
shortMonthNames[0] = "Jan";
shortMonthNames[1] = "Feb";
shortMonthNames[2] = "Mar";
shortMonthNames[3] = "Apr";
shortMonthNames[4] = "May";
shortMonthNames[5] = "Jun";
shortMonthNames[6] = "Jul";
shortMonthNames[7] = "Aug";
shortMonthNames[8] = "Sep";
shortMonthNames[9] = "Oct";
shortMonthNames[10] = "Nov";
shortMonthNames[11] = "Dec";
// LONG MONTH NAMES == 'longMonthNames';
var longMonthNames = new Array();
longMonthNames[0] = "January";
longMonthNames[1] = "February";
longMonthNames[2] = "March";
longMonthNames[3] = "April";
longMonthNames[4] = "May";
longMonthNames[5] = "June";
longMonthNames[6] = "July";
longMonthNames[7] = "August";
longMonthNames[8] = "September";
longMonthNames[9] = "October";
longMonthNames[10] = "November";
longMonthNames[11] = "December";


var morningTime = "AM";
var eveningTime = "PM";
var yrPos = 2;
var moPos = 0;
var dyPos = 1;
// Date pictures: These represent legal dates.
// These pictures allow "/" or "-" delimiters, 
// require two- or four-digit years, allow one-digit months or days
var datePics = new Array();
datePics[0] = "9-9-9999";
datePics[1] = "9-99-9999";
datePics[2] = "99-99-9999";
datePics[3] = "99-9-9999";
datePics[4] = "9/9/9999";
datePics[5] = "9/99/9999";
datePics[6] = "99/99/9999";
datePics[7] = "99/9/9999";
datePics[8] = "9-9-99";
datePics[9] = "9-99-99";
datePics[10] = "99-99-99";
datePics[11] = "99-9-99";
datePics[12] = "9/9/99";
datePics[13] = "9/99/99";
datePics[14] = "99/99/99";
datePics[15] = "99/9/99";

var dateForMsg = "mm/dd/yy or mm/dd/yyyy";

var valMsgDateFormat = "Error in %s field:  Enter a valid date in the form " + dateForMsg;

// This function must change too if the date format changes:
function getDisplayDateFromDate(d) {
	return ((prefillZero(d.getMonth() + 1)) + "/" + prefillZero(d.getDate()) + "/" + d.getFullYear());
}


function getTwoDigitYrFromFour(fourDigitYear) {
	var rtn = fourDigitYear + "";
	return rtn.substring(2);
}


function toFourDigitYr(yr) {  // yr must be a two or four digit year at this point

	if (yr.toString().length == 4) {
		return yr;
	} else {
		// it's 2 digits
		// use a window of eighty years in the past and twenty in the future
		var currYr = getTwoDigitYrFromFour(getDateToday().getFullYear());
		if (currYr < 80) {
			currYr += 100;
		}
		if (yr < (currYr - 80)) {
			return "20" + yr;
		} else {
			return "19" + yr;
		}
	}
}


function isYear (s)
{
    if (!isNonnegativeInteger(s)) return false;

	var yr = s.substring(0,2);
	return ( ( (s.length == 4) && ( (yr == "19") || (yr == "20") ) ) || (s.length == 2) );
}

function isMonth (s)
{
    return isIntegerInRange (s, 1, 12);
}


function isDay (s)
{
    return isIntegerInRange (s, 1, 31);
}


function daysInFebruary (year)
{   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}


var daysInMonth = Array(12);
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;


function isDate (year, month, day)
{   // catch invalid years and invalid months and days.
    if (! (isYear(year) && isMonth(month) && isDay(day))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year);
    var intMonth = parseInt(stripLeadZero(month));
    var intDay = parseInt(stripLeadZero(day));

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false; 

    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
}


function parseDate(str) {  // assumes date is at least in the right format; need not be otherwise correct yet

	var delim;

	for (var i = 0; i < str.length; i++) {
		if (!isDigit(str.charAt(i))) {
			delim = str.charAt(i);
			break;
		}
	}

	var datePart = str.split(delim);
	if (datePart[0] == null) {
		datePart[0] = "";
	}
	if (datePart[1] == null) {
		datePart[1] = "";
	}
	if (datePart[2] == null) {
		datePart[2] = "";
	}
	return datePart;
}


function getDateCommon(d, ix) {

	if (typeof(d) == "string") {
		var datePart = parseDate(d);
		return datePart[ix];
	} else {
		return d[ix];
	}
}


function getDateYr(d) {

	return getDateCommon(d, yrPos);
}


function getDateMo(d) {

	return getDateCommon(d, moPos);
}


function getDateDy(d) {

	return getDateCommon(d, dyPos);
}


function valDate(str) {

	if (!valPicture(str, datePics)) {
		return false;
	} else {
		var datePart = parseDate(str);
		return (isDate(getDateYr(datePart), getDateMo(datePart), getDateDy(datePart)));
	}
}


function getDateToday() {
	return new Date();
}


function getDateYearAgoBeginMonth() {
	var d = getDateToday();
	d.setFullYear(d.getFullYear() - 1);
	d.setDate(1);
	return d;
}


function fmtRptArgDate(year,month,day) {
	if ((year == "") && (month == "") && (day == "")) {
		return "Date()";
	} else {
		return "Date(" + toFourDigitYr(year) + "," + month + "," + day + ")"
	}
}


function getRptArgDateFromDate(d) {
	return fmtRptArgDate(d.getFullYear(),(d.getMonth() + 1),d.getDate());
}

function getRptArgDateFromDisplayDate(displayDate) {

	if (!isEmpty(displayDate)) {
		if (!valDate(displayDate)) {  // the date should have already been edited; this is really not necessary
			alert("Illegal date: '" + displayDate + "'; using default...");
			return fmtRptArgDate("","","");
		} else {
			return (fmtRptArgDate(getDateYr(displayDate), getDateMo(displayDate), getDateDy(displayDate)));
		}
	} else {
		return fmtRptArgDate("","","");
	}
}

function prefillZero(num) {
	return (num < 10) ? "0" + num : num;
}
