//---------------------------------------------------------------------
// WAF - Web/Windows Application Framework
// Copyright © 2005 The Enticy Group LLC.
//
// File:	datepicker.js
//
// Description:	Javascript class and functions to support a popup date picker window
//
// Revisions :
//		2003-07-07	Conrad	added call to onchange() on clicking a date
//		2003-08-11	Conrad	start at date of field's current value, not today
//		2003-08-12	Conrad	removed yearly calendar, use styles, remove format
//		2003-10-02	Conrad	substantial improvements
//		2005-07-08	Conrad	changed nav_* images to .pngs
//		2005-10-25	Conrad	strip time from date for Safari's Javascript engine
//---------------------------------------------------------------------

function show_calendar(returnFieldId, winCal, monthToShow, yearToShow) {

	// This is the "outside link" to this code.

	// This creates a new global calendar and displays it
	cal = new Calendar(returnFieldId, winCal, monthToShow, yearToShow);

}

function Calendar(returnFieldId, winCal, monthToShow, yearToShow) {

	// Constructor -- also displays the window

	// Get the current date
	var dNow = new Date();
	this.gNowDay = dNow.getDate();
	this.gNowMonth = dNow.getMonth();
	this.gNowYear = dNow.getFullYear();

	// Get the field's current value as a starting date, or use today as a default
	var dStartDate;
	if (returnFieldId != null)
		dStartDate = this.stringToDate(document.getElementById(returnFieldId).value);
	if (dStartDate == null)
		dStartDate = dNow;
	this.gStartDay = dStartDate.getDate();
	this.gStartMonth = dStartDate.getMonth();
	this.gStartYear = dStartDate.getFullYear();

	// If we haven't chosen a month to display, use the starting date's month
	if (monthToShow == null) {
		monthToShow = new String(dStartDate.getMonth());
		yearToShow = new String(dStartDate.getFullYear().toString());
	}

	// If winCal is null, a new window is created
	if (winCal == null)
		this.gWinCal = this.newWindow();
	else
		this.gWinCal = winCal;

	this.gMonthName = this.monthName(monthToShow);
	this.gMonth = new Number(monthToShow);
	this.gYear = yearToShow;
	this.gReturnItem = returnFieldId;

	this.show();
}

Calendar.prototype.newWindow = function() {
	// Create a new default Calendar window
	winCal = window.open("", "Calendar", "width=250,height=200,status=no,resizable=no,top=200,left=200");
	winCal.focus();
	winCal.opener = self;
	return winCal;
}

Calendar.prototype.monthName = function(month) {
	monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	return monthNames[month];
}

Calendar.prototype.daysInMonth = function(month, year) {

	daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	var nDays = daysInMonth[month];
	if (month == 1) // February
		if ( ((year % 400) == 0) || ((year % 4) == 0 && (year % 100) != 0) )
			nDays += 1;
	return nDays;
}

Calendar.prototype.getMonthlyCalendarCode = function() {

	return (
		'<table class="calMonthTable">' +
		this.cal_header() +
		this.cal_data() +
		'</table>'
	);
}

Calendar.prototype.buildCallText = function(month, year) {
	return (
		"window.opener.show_calendar(" + 
		"'" + this.gReturnItem + "', self, " + month + ", " + year +
		");"
	);
}

Calendar.prototype.buildLinkText = function(month, year, isPrevious, isMonthly) {
	var sLink = 
		'<a class="calNavLink" href="javascript:' + 
		this.buildCallText('\'' + month + '\'', '\'' + year + '\'') + '">';

	if (isPrevious)
		sDirectionText = "previous";
	else
		sDirectionText = "next";

	if (isMonthly)
		sIntervalText = "month";
	else
		sIntervalText = "year";

	sLink += '<img class="calNavImage" title="' + sDirectionText + ' ' + sIntervalText + '" src="WAF/images/nav_' + sDirectionText + '.png"/>';
	sLink += '</a>';

	return sLink;
}

Calendar.prototype.show = function() {
	
	// CCC: I commented this out, because it causes a Javascript error.
	// I'd get rid of it, but I don't know why it was here to begin with.
	//this.gWinCal.document.open();

	this.wwrite('<html><head>');
	this.wwrite('<title>Calendar</title>');
	this.wwrite('<style type="text/css">');
	this.wwrite('<!--');

	this.wwrite('.calBody {}');

	this.wwrite('.calInputTable {width: 100%; border: solid 1px; margin-bottom: 10px; }');
	this.wwrite('.calInputRow {vertical-align: middle; }');
	this.wwrite('.calInputCell {text-align: center; white-space: nowrap;}');
	this.wwrite('.calNavLink {}');
	this.wwrite('.calNavImage {vertical-align: middle; border: none; }');
	this.wwrite('.calMonthChoice {vertical-align: middle; }');
	this.wwrite('.calYearChoice {vertical-align: middle; }');

	this.wwrite('.calMonthTable {width: 100%; border: solid 1px; }');
	this.wwrite('.calHeaderRow {font-weight: bold; font-size: 9pt; font-family: Verdana, Arial, helvetica; }');
	this.wwrite('.calHeaderCell {text-align: center; }');
	this.wwrite('.calWeekRow {font-size: 9pt; font-family: Verdana, Arial, helvetica; }');
	this.wwrite('.calWeekdayCell {cursor: pointer; width: 14%; text-align: right; background-color: white; }');
	this.wwrite('.calWeekendCell {cursor: pointer; width: 14%; text-align: right; background-color: lightgrey; }');
	this.wwrite('.calCurrentCell {width: 14%; text-align: right; background-color: lightblue; }');
	this.wwrite('.calTodayCell {width: 14%; text-align: right; border: solid 1px red; }');
	this.wwrite('.calEmptyCell {width: 14%; text-align: right; }');

	this.wwrite('-->');
	this.wwrite('</style>');
	this.wwrite('<link rel="stylesheet" type="text/css" href="css/calendar.css"/>');

	this.wwrite('<script type="text/javascript">');
	this.wwrite('<!--');
	this.wwrite('function returnValue(sValue) {');
	this.wwrite('  self.opener.document.getElementById("' + this.gReturnItem + '").value = sValue;');
	this.wwrite('  if (self.opener.document.getElementById("' + this.gReturnItem + '").onchange)');
	this.wwrite('    self.opener.document.getElementById("' + this.gReturnItem + '").onchange();');
	this.wwrite('  window.close();');
	this.wwrite('}');

	var vMonth = 1 + this.gMonth;
	vMonth = (vMonth.toString().length < 2) ? '0' + vMonth : vMonth;
	var vY4 = new String(this.gYear);

	this.wwrite('function returnDay(nDay) {');
	this.wwrite('  var vDD = (nDay.toString().length < 2) ? "0" + nDay : nDay;');
	this.wwrite('  returnValue("' + vMonth + '/" + vDD + "/' + vY4 + '")');
	this.wwrite('}');
	this.wwrite('//-->');
	this.wwrite('</script>');
	
	this.wwrite('</head>');
	this.wwrite('<body class="calBody">');

	// Calculate previous month
	var prevMM = (this.gMonth + 11) % 12;
	var prevYYYY = this.gYear;
	if (this.gMonth == 0) prevYYYY--;

	// Calculate next month
	var nextMM = (this.gMonth + 1) % 12;
	var nextYYYY = this.gYear;
	if (this.gMonth == 11) nextYYYY++;

	this.wwrite('<table class="calInputTable">');
	this.wwrite('<tr class="calInputRow">');
	this.wwrite('<td class="calInputCell">');

	// Make a previous month link
	this.wwrite(this.buildLinkText(prevMM, prevYYYY, true, true));

	// Make a month drop-down
	this.wwrite('<select class="calMonthChoice" onchange="' + this.buildCallText('this.value', '\'' + this.gYear + '\'') + '">')
	for (monthNo = 0; monthNo < 12; monthNo++) {
		this.wwrite('<option value="' + monthNo + '"')
		if (monthNo == this.gMonth)
			this.wwrite(' selected="selected"')
		this.wwrite('>' + this.monthName(monthNo) + '</option>')
	}
	this.wwrite('</select>');

	// Make a next month link
	this.wwrite(this.buildLinkText(nextMM, nextYYYY, false, true));

	this.wwrite('</td><td class="calInputCell">');

	// Make a previous year link
	this.wwrite(this.buildLinkText(this.gMonth, (parseInt(this.gYear)-1), true, false));

	// Make a year text field
	this.wwrite('<input type="text" class="calYearChoice" value="' + this.gYear + '" size="4" onchange="' + this.buildCallText('\'' + this.gMonth + '\'', 'this.value') + '"/>');

	// Make a next year link
	this.wwrite(this.buildLinkText(this.gMonth, (parseInt(this.gYear)+1), false, false));

	this.wwrite("</td></tr></table>");

	// Get the complete calendar code for the month..
	this.wwrite(this.getMonthlyCalendarCode());

	this.wwrite("</body></html>");

	this.gWinCal.document.close();
}

Calendar.prototype.wwrite = function(wtext) {
	this.gWinCal.document.writeln(wtext);
}

Calendar.prototype.cal_header = function() {	
	var vCode = 
		'<tr class="calHeaderRow">' +
		'<td class="calHeaderCell">Sun</td>' +
		'<td class="calHeaderCell">Mon</td>' +
		'<td class="calHeaderCell">Tue</td>' +
		'<td class="calHeaderCell">Wed</td>' +
		'<td class="calHeaderCell">Thu</td>' +
		'<td class="calHeaderCell">Fri</td>' +
		'<td class="calHeaderCell">Sat</td>' +
		'</tr>';
	return vCode;
}

Calendar.prototype.cal_data = function() {

	// Start with the day of the month being negative.
	var vDate = new Date();
	vDate.setDate(1);
	vDate.setMonth(this.gMonth);
	vDate.setFullYear(this.gYear);
	var nDayOfMonth = 1 - vDate.getDay();

	var nLastDayOfMonth = this.daysInMonth(this.gMonth, this.gYear);
	var sCode = "";

	while (nDayOfMonth <= nLastDayOfMonth) {

		// Write a week at a time.
		sCode += '<tr class="calWeekRow">';
		for (dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
			if ((nDayOfMonth >= 1) && (nDayOfMonth <= nLastDayOfMonth))
				// If the day of the month is between 1 and the end of the month, write it normally
				sCode += this.dayCell(nDayOfMonth, dayOfWeek);
			else
				// Otherwise, write a blank cell
				sCode += '<td class="calEmptyCell"></td>';
			nDayOfMonth++;
		}
		sCode += '</tr>';

	}
	
	return sCode;
}

Calendar.prototype.dayCell = function(day, dayOfWeek) {
	return (
		'<td class="' + this.cellClassName(dayOfWeek, day) + '" ' + 
		'onClick="returnDay(\'' + day + '\');">' + 
		day + 
		'</td>'
	)
}

Calendar.prototype.cellClassName = function(dayOfWeek, day) {

	var sClassName = "";

	// Return special formatting for the weekend day.
	if ((dayOfWeek == 0) || (dayOfWeek == 6))
		sClassName = "calWeekendCell";
	else
		sClassName = "calWeekdayCell";

	// Special formatting for today
	if (day == this.gNowDay && this.gMonth == this.gNowMonth && this.gYear == this.gNowYear)
		sClassName += " calTodayCell";

	// Special formatting for the starting date
	if (day == this.gStartDay && this.gMonth == this.gStartMonth && this.gYear == this.gStartYear)
		sClassName += " calCurrentCell";

	return sClassName;
}

Calendar.prototype.stringToDate = function(sDate) {

	// Replace dots or dashes with slashes
	var tempDate = sDate.replace(/[\.\-]/g, '/');

	var aDate = new Date(tempDate);

	// Special test for Safari
	if (aDate.valueOf() == -2147483648000) {
		// Strip off any time (stuff after a space) and try again.
		// Most Javascript engines can handle time, but Safari does not.
		// This will cause problems with "Oct 10, 2005"
		if (tempDate.indexOf(' ') > -1) {
			tempDate = tempDate.substring(0, tempDate.indexOf(' '));
		}
		aDate = new Date(tempDate);
	}

	// if this is a date, return it, 
	if (aDate.getDate()) {
		return this.sanifyDate(aDate);
	}

	// Otherwise, try to add the current year.
	var now = new Date();
	aDate = new Date(tempDate + '/' + now.getFullYear());
	if (aDate.getDate()) {
		return this.sanifyDate(aDate);
	} else {
		return null;
	}
}

Calendar.prototype.sanifyDate = function(aDate) {
	var tempDate = aDate;
	var year = tempDate.getFullYear();
	if (Math.max(year, 50) == 50) year += 2000;
	if (Math.max(year, 100) == 100) year += 1900;
	tempDate.setFullYear(year);
	return (tempDate);
}
