/**
 * Calendar is used to popup a one-month calendar and fill an associated text box with the date
 * There is only one calendar object per document, referenced by Calendar.getCalendar()
 * The Calendar object in this file uses a separate browser window
 * This contrasts with the Calendar object in calendar.js, which uses a popup in the same browser window.
 */
function Calendar() {

	// initialize data properties
	this.theWindow = null;
	this.image = null;
	this.textBox = null;
	this.displayedDate = null;
	this.months = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	this.days = new Array("M", "T", "W", "T", "F", "S", "S");
	this.oneDayMs = 1000 * 60 * 60 * 24; // milliseconds in one day

	// private methods properties
	this.formatDate = formatDate;
	this.setContent = setContent;
	this.strToDate = strToDate;

	// private methods (alphabetical)

	function formatDate(theDate) {
		var month = theDate.getMonth() + 1;
		if (month < 10) month = "0" + month;
		var day = theDate.getDate();
		if (day < 10) day = "0" + day;
		var year = theDate.getFullYear();
		var result = month + "/" + day + "/" + year;
		return result;
	}


	function setContent(theDate) {

		// initialize the document		
		this.displayedDate = theDate;
		this.textBox.value = this.formatDate(theDate);
		var d = this.theWindow.document;
		d.open();
		
		// <head>
		d.writeln("<head>");
		d.writeln("<title> Date </title>");
		d.writeln("");
		d.writeln("<style><!--"); 
		d.writeln("SELECT.cal_month {");
		d.writeln("	border:		1pt solid black;");
		d.writeln("	font-size:	8pt;");
		d.writeln("}");

		d.writeln("SELECT.cal_year {");
		d.writeln("	border:		1pt solid black;");
		d.writeln("	font-size:	8pt;");
		d.writeln("}");

		d.writeln("INPUT.cal_button {");
		d.writeln("	font-size:	8pt;");
		d.writeln("	text-align:	center;");
		d.writeln("}");

		d.writeln("TR.cal_header {");
		d.writeln("	height:			30;");
		d.writeln("	border-bottom:	1pt solid black;");
		d.writeln("	background:		#993399;");
		d.writeln("}");

		d.writeln("TD.cal_header {");
		d.writeln("	font-size:			10pt;");
		d.writeln("	font-family:		sans-serif;");
		d.writeln("	color:			    white;");
		d.writeln("	text-align:		    center;");
		d.writeln("}");

		d.writeln("TD.cal_dayrow {");
		d.writeln("	font-size:			8pt;");
		d.writeln("	font-family:		sans-serif;");
		d.writeln("	text-align:			center;");
		d.writeln("	text-decoration: 	none;");
		d.writeln("	text-align:			center;");
		d.writeln("	color:				black;");
		d.writeln("}");
		
		d.writeln("A.cal_currday {");
		d.writeln("	font-size:			8pt;");
		d.writeln("	font-family:		sans-serif;");
		d.writeln("	text-align:			center;");
		d.writeln("	text-decoration: 	none;");
		d.writeln("	text-align:			center;");
		d.writeln("	font-weight:        bold;");
		d.writeln("	color:				blue;");
		d.writeln("}");

		d.writeln("A.cal_currmo {");
		d.writeln("	font-size:			8pt;");
		d.writeln("	font-family:		sans-serif;");
		d.writeln("	text-align:			center;");
		d.writeln("	text-decoration: 	none;");
		d.writeln("	text-align:			center;");
		d.writeln("	font-weight:        bold;");
		d.writeln("	color:				black;");
		d.writeln("}");

		d.writeln("A.cal_notcurrmo {");
		d.writeln("	font-size:			8pt;");
		d.writeln("	font-family:		sans-serif;");
		d.writeln("	text-align:			center;");
		d.writeln("	text-decoration: 	none;");
		d.writeln("	text-align:			center;");
		d.writeln("	color:				black;");
		d.writeln("}");
		d.writeln("--></style>");
		d.writeln("");
		d.writeln("</head>");
		
		// <body>
		d.writeln("");
		d.writeln("<body bgcolor=#CCCCCC>");
		d.writeln("");
		d.writeln("<TABLE Cellpadding=0 Cellspacing=0 border=0 width=100%>");

		// decrement month button
		d.writeln("");
		d.writeln("  <TR><TD><TABLE width=100% Cellpadding=0 Cellspacing=0 border=0>");
		d.writeln("    <TR Class=cal_header>");
		d.writeln("      <TD Class=cal_header align=left>");
		d.writeln("        <INPUT Type=Button Value='&lt;' Class=cal_button OnClick='javascript:window.opener.Calendar.decMonthBtnClick()'> ");
		d.writeln("      </TD>");

		// month/day title
		d.writeln("      <TD Class=cal_header align=center>");
		var theMonth = theDate.getMonth();
		d.writeln("        " + this.months [theMonth] + ' ' + new String(theDate.getFullYear()).slice(-2));
		d.writeln("      </TD>");

		// increment month button
		d.writeln("      <TD Class=cal_header align=right>");
		d.writeln("        <INPUT Type=Button Value='&gt;' Class=cal_button OnClick='javascript:window.opener.Calendar.incMonthBtnClick();'>");
		d.writeln("      </TD>");
		d.writeln("    </TR>");
		d.writeln("  </TABLE></TD></TR>");

		// calculate on what date calendar starts (Mon - Sun)
		var dateValue = new Date(theDate);
		dateValue.setDate(1);
		var dayDecrement = dateValue.getDay() - 1;
		if (dayDecrement < 0) dayDecrement = 6;
		dateValue = new Date(dateValue.getTime() - dayDecrement * this.oneDayMs);


		// days of week
		d.writeln("");
		d.writeln("  <TR><TD><TABLE width=100% Cellpadding=1 Cellspacing=1 border=0>");
		d.writeln("    <TR>");
		var day;
		for (var day = 0; day < 7; day++) {
			d.writeln("      <TD class=cal_dayrow align=center>");
			d.writeln("        " + this.days [day]);
			d.writeln("      </TD>");
		}
		d.writeln("    </TR>");

		// output 6 rows x 7 days
		var theDay = theDate.getDate();
		for (row = 0; row < 6; row++) {
			d.writeln("    <TR>");
			for (day = 0; day < 7; day++) {
				var monthValue = dateValue.getMonth();
				var dayValue = dateValue.getDate();
				d.write("      <TD align=center> <a class=");
				if (monthValue == theMonth) {
					if (dayValue == theDay) {
						d.write('cal_currday');
					} else {
						d.write('cal_currmo');
					}
				} else {
					d.write('cal_notcurrmo');
				}
				d.writeln(" href=javascript:window.opener.Calendar.dayClick(" +
					eval(monthValue) + "," +
					eval(dayValue) + "," +
					eval(dateValue.getFullYear()) + ")>" +
					eval(dayValue) + "</a></TD>");
				dateValue = new Date(dateValue.getTime() + this.oneDayMs);
			}
			d.writeln("    </TR>");
		}
		d.writeln("  </TABLE></TD></TR>");

		// finish up
		d.writeln("");
		d.writeln("</TABLE>");
		d.writeln("</body>");
		d.close();
		
	}

	function strToDate(dateStr) {

		// validate the date; return today if invalid
		var result = new Date();
		var dateParts = dateStr.split("/");
		if (dateParts.length != 3) return result;
		if (dateParts [0].search("[^0-9]") > -1) return result;
		if ((dateParts [0] < 1) || (dateParts [0] > 12)) return result;
		if (dateParts [1].search("[^0-9]") > -1) return result;
		if ((dateParts [1] < 1) || (dateParts [1] > 31)) return result;
		if (dateParts [2].search("[^0-9]") > -1) return result;
		if ((dateParts [2] >= 0) && (dateParts [2] <= 99)) dateParts [2] = 2000 + parseInt(dateParts [2]);
		if ((dateParts [2] < 1990) || (dateParts [2] > 2099)) return result;
		
		// set the date
		result.setDate(dateParts [1]); // must be first, in case new month has fewer days than this month
		result.setMonth(dateParts [0] - 1);
		result.setFullYear(dateParts [2]);
		return result;
	}

}

// event methods (not for public use)

Calendar.decMonthBtnClick = function() {
	var calendar = Calendar.getCalendar();
	var newDate = new Date(calendar.displayedDate);
	var month = newDate.getMonth() - 1;
	if (month >= 0) {
		newDate.setMonth(month);
	} else {
		newDate.setMonth(11);
		newDate.setFullYear(newDate.getFullYear() - 1);
	}
	calendar.setContent(newDate);
}

Calendar.dayClick = function(month, day, year) {
	var calendar = Calendar.getCalendar();
	calendar.setContent(new Date(year, month, day));
	Calendar.hide();
	if (Calendar.additionalJavaScript != '') {
		eval(Calendar.additionalJavaScript);
	}
}

Calendar.incMonthBtnClick = function() {
	var calendar = Calendar.getCalendar();
	var newDate = new Date(calendar.displayedDate);
	var month = newDate.getMonth() + 1;
	if (month < 12) {
		newDate.setMonth(month);
	} else {
		newDate.setMonth(0);
		newDate.setFullYear(newDate.getFullYear() + 1);
	}
	calendar.setContent(newDate);
}

// public methods

Calendar.getCalendar = function() {
	if (Calendar.theCalendar == null) Calendar.theCalendar = new Calendar();
	return Calendar.theCalendar;
}
Calendar.theCalendar = null;
Calendar.additionalJavaScript = '';

Calendar.hide = function() {
	var calendar = Calendar.getCalendar();
	if (calendar.theWindow == null) return;
	if (calendar.theWindow.closed) return;
	calendar.theWindow.close();
}

Calendar.show = function(event, textBox, image) {

	// set the contents using the text box date
	var calendar = Calendar.getCalendar();
	var x = event.screenX + (image.width / 2);
	var y = event.screenY - (image.height / 2);
	if ((calendar.theWindow != null) && !calendar.theWindow.closed) {
		calendar.theWindow.moveTo(x, y);
		calendar.theWindow.focus();
	} else {
		var features = "toolbar=no,status=no,resizable=no,width=125,height=175"
		features += ",left=" + x + ",screenX=" + x;
		features += ",top=" + y + ",screenY=" + y;
		calendar.theWindow = window.open("", "", features);
	}
	calendar.image = image;
	calendar.textBox = textBox;
	calendar.setContent(calendar.strToDate(textBox.value));

}

