/*Purpose: Generic calendar code
Original author: Robert Seber
Author's version: 26
Passed testing on: IE5 PC, IE5 Mac, NS4 PC, NS6 PC, NS4 Mac

Modifications made by: 
Reasons for modification: 
Modifier's version: 
Passed testing on: 
*/

var formFieldNameDayDate = 'dateDay';
var	formFieldNameMonthYearDate = 'dateMonthYear';
// Extend date functions

Date.prototype.getDayNum   = function(){      return this.getDate()    }
Date.prototype.setDayNum   = function(day){   this.setDate(day)        }
Date.prototype.getMonthNum = function(){      return this.getMonth()+1 }
Date.prototype.getMonthAsString = function(){      
	switch (this.getMonth()+1)
	{
		case 1: monthStr = 'January'; break;
		case 2: monthStr = 'February'; break;
		case 3: monthStr = 'March'; break;
		case 4: monthStr = 'April'; break;
		case 5: monthStr = 'May'; break;
		case 6: monthStr = 'June'; break;
		case 7: monthStr = 'July'; break;
		case 8: monthStr = 'August'; break;
		case 9: monthStr = 'September'; break;
		case 10: monthStr = 'October'; break;
		case 11: monthStr = 'November'; break;
		case 12: monthStr = 'December'; break;
	}
 	return monthStr
}
Date.prototype.setMonthNum = function(month){ this.setMonth(month-1)   }
Date.prototype.getYearNum  = function(){      return this.getFullYear()}
Date.prototype.setYearNum  = function(year){  this.setYear(year)       }

Date.prototype.getDayOfWeekNum = function(firstDay){
	var day = this.getDay()-firstDay;
	if (day < 0) return day + 7;
	else return day;
}

Date.prototype.setDayMonthYear = function(day,month,year){
	this.setFullYear(year);
	this.setMonth(month-1);
	this.setDate(day);
	this.setHours(12);
}

Date.prototype.addDay = function(){
	this.setDate(this.getDate()+1);
}

Date.prototype.addMonth = function(){
	this.setMonth(this.getMonth()+1);
}

Date.prototype.addYears = function(numberOfYears){
	this.setYear(this.getFullYear()+numberOfYears);
}

Date.prototype.nextMonth = function(){
	if (this.getMonth()+1 > 12)
	{this.setMonth(1);
	 this.setYear(this.getFullYear()+1);
	}
	else
	{this.setMonth(this.getMonth()+1);
	 this.setYear(this.getFullYear());
	}
}

Date.prototype.previousMonth = function(){
	if (this.getMonth()-1 == 0)
	{this.setMonth(12);
	 this.setYear(this.getFullYear()-1);
	}
	else
	{this.setMonth(this.getMonth()-1);
	 this.setYear(this.getFullYear());
	}
}

Date.prototype.copyTo = function(date2){
	date2.setTime(this.getTime());
}

Date.prototype.getMonthComparator = function(){//Returns int to allow comparison
	return this.getYearNum()*100 + this.getMonthNum();
}

Date.prototype.getDayComparator = function(){//Returns int to allow comparison
	return this.getYearNum()*10000 + this.getMonthNum()*100 + this.getDayNum();
}

Date.isDate = function(day,month,year){//Checks if a date is valid
	if (year>999 && year<10000){
		var dt = new Date(year,month-1,day);
		return dt.getDate()==day && dt.getMonth()==month-1 && dt.getFullYear()==year;
	}
	return false;
}

//Calendar initialisation functions

function Calendar(){
	this.width = 190;
	this.height = 165;
	this.firstDayOfWeek = 1;
	this.todaysDate = new Date();
	this.selectedDate = new Date();
	this.earliestDate = new Date();
	this.earliestDate.setDayMonthYear(1,1,1000);
	this.latestDate = new Date();
	this.latestDate.setDayMonthYear(1,1,3000);
	this.viewDate = new Date();
	this.counterDate = new Date();
	this.outputWindow = new Object();
	this.getFormDay = new Function();
	this.getFormMonth = new Function();
	this.getFormYear = new Function();
	this.setFormDate = new Function();
	this.clearFormDate = new Function();
	this.id = Math.ceil(Math.random()*99999);
	this.outputHtml = "";
	this.styleSheetPath = "";
	this.showTodayControl = true;
	this.showClearControl = true;
	this.showYearControls = true;
	this.showDecadeControls = false;
	this.monthsText = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	this.dayText = new Array("M","T","W","T","F","S","S");
	this.nextYearText = "Next";
	this.previousYearText = "Prev";
	this.nextDecadeText = " Next 10";
	this.previousDecadeText = "Prev 10";
	this.todayText = "Today";
	this.clearText = "Clear Form";
	this.closeText = "Close";
	this.validSelectedDate = false;
}

Calendar.prototype.setTodaysDate = function(day,month,year){
	this.todaysDate.setDayMonthYear(day,month,year);
}

Calendar.prototype.setSelectedDate = function(day,month,year){
	this.selectedDate.setDayMonthYear(day,month,year);
	this.setViewDate(day,month,year);
}

Calendar.prototype.setEarliestDate = function(day,month,year){
	this.earliestDate.setDayMonthYear(day,month,year);
}

Calendar.prototype.setLatestDate = function(day,month,year){
	this.latestDate.setDayMonthYear(day,month,year);
}

Calendar.prototype.setViewDate = function(day,month,year){
	this.viewDate.setDayMonthYear(day,month,year);
}

//Output functions

Calendar.prototype.writeLn = function(text){
	this.outputHtml += text + "\n";
}

Calendar.prototype.writeTableStart = function(){
	this.writeLn('<table width="100%" border="0" cellspacing="0" cellpadding="2">');
}

Calendar.prototype.writeTableDivider = function(){
	this.writeLn('</td></tr><tr><td>');
}

Calendar.prototype.writeTableEnd = function(){
	this.writeLn('</table>');
}

Calendar.prototype.writeCalendar = function(){
	this.outputHtml = "";
	this.outputWindow.document.open();
	this.writeLn('<html><head>');
	if (!isIEPC()) this.writeLn('<base href="' + window.location.href + '">');
	this.writeLn('<title>Calendar</title>');
	this.writeLn('<link rel="StyleSheet" href="'+this.stylesheetPath+'" type="text/css">');
	this.writeLn('</head>');
	this.writeLn('<body marginheight="0" marginwidth="0" topmargin="0" leftmargin="0"><center>');
	this.writeLn('<table border="0" width="100%" cellspacing="0" cellpadding="0"><tr><td class="background">');
	this.writeYearControls();
	this.writeTableDivider();
	//this.writeMonthControls();
	//this.writeTableDivider();
	this.writeMonth();
	this.writeBottomControl(this.showTodayControl,"calendar.selectToday()",this.todayText);
//	this.writeBottomControl(this.showClearControl,"calendar.clear()",this.clearText);
	this.writeBottomControl(true,"window.close()",this.closeText);
	this.writeLn('</td></tr></table>');
	this.writeLn('</center></body></html>');
	this.outputWindow.document.write(this.outputHtml);
	this.outputWindow.document.close();
	this.outputHtml = "";
	this.outputWindow.calendar = this;
}

Calendar.prototype.writeYearControls = function(){
	this.writeTableStart();
	var earliestYear = this.earliestDate.getYearNum();
	var viewYear = this.viewDate.getYearNum();
	var latestYear = this.latestDate.getYearNum();
	//var earliestMonth = this.earliestDate.getMonthNum();
	//var viewMonth = this.viewDate.getMonthNum();
	//var latestMonth = this.latestDate.getMonthNum();

	this.writeLn('<tr>');
	if (this.showYearControls) this.writeYearControl(this.viewDate.getDayComparator()>=this.earliestDate.getDayComparator(),'viewMonth(-1)','<img src="/images/chevrons_orange_previous.gif" width="11" height="9" alt="Previous month" border="0">');/*this.previousYearText*/
	//if (this.showDecadeControls) var params = ' rowspan="2"';
	else var params = "";	
	this.writeLn('<td class="year" width="40%"'+params+'">' + this.viewDate.getMonthAsString() + '<BR>'+this.viewDate.getYearNum() + '</td>');
	if (this.showYearControls) this.writeYearControl(this.viewDate.getDayComparator()<=this.latestDate.getDayComparator(),'viewMonth(1)','<img src="/images/chevrons_orange.gif" width=11 height=9 alt="Next month" border=0>');/*this.nextYearText*/
	this.writeLn('</tr>');
	/*if (this.showDecadeControls) {
		this.writeLn('<tr>');
		this.writeYearControl(viewYear-10>=earliestYear,'changeViewYear(-10)',this.previousDecadeText);
		this.writeYearControl(viewYear+10<=latestYear,'changeViewYear(10)',this.nextDecadeText);
		this.writeLn('</tr>');
	}*/
	this.writeTableEnd();
}

Calendar.prototype.writeYearControl = function(isEnabled,methodText,displayText){
	if (isEnabled){
		this.writeLn('<td class="control" width="30%" nowrap><a href="javascript:calendar.'+methodText+'">&nbsp;'+displayText+'&nbsp;</a></td>');
	} else {
		this.writeLn('<td class="disabledcontrol" width="30%" nowrap>&nbsp;&nbsp;</td>');
	}
}

Calendar.prototype.writeMonthControls = function(){
	this.viewDate.copyTo(this.counterDate);
	this.counterDate.setMonthNum(1);
	this.writeTableStart();
	this.writeLn('<tr>');
	for (var i=1;i<=12;i++){
		if (this.counterDate.getMonthComparator()<this.earliestDate.getMonthComparator() || this.counterDate.getMonthComparator()>this.latestDate.getMonthComparator()){
			this.writeLn('<td class="disabledmonth" width="17%" title="Month unavailable">'+this.monthsText[i-1]+'</td>');
		} else if (this.counterDate.getMonthComparator()==this.viewDate.getMonthComparator()){
			this.writeLn('<td class="viewmonth" width="17%" title="Selected Month">'+this.monthsText[i-1]+'</td>');
		} else {
			this.writeLn('<td class="month" width="17%"><a href="javascript:calendar.viewMonth('+i+')" title="Display this month">'+this.monthsText[i-1]+'</a></td>');
		}
		if (i==6) this.writeLn('</tr><tr>');
		this.counterDate.addMonth();
	}
	this.writeLn('</tr>');
	this.writeTableEnd();
}

Calendar.prototype.writeMonth = function(){
	this.viewDate.copyTo(this.counterDate);
	this.writeTableStart();
	this.writeLn('<tr>');
	for (var i=0;i<7;i++){
		this.writeLn('<td class="dayofweek" width="14%">'+this.dayText[i]+'</td>');
	}
	this.writeLn('</tr>');
	var i=0;
	while (this.counterDate.getMonthNum()==this.viewDate.getMonthNum()){
		this.writeWeek();
		i++;
	}
	if (i<6){
		this.writeLn('<tr>');
		this.writeBlankDays(7);
		this.writeLn('</tr>');
	}
	this.writeTableEnd();
}

Calendar.prototype.writeWeek = function(){
	this.writeLn('<tr>');
	var dayOfWeek = this.counterDate.getDayOfWeekNum(this.firstDayOfWeek);
	this.writeBlankDays(dayOfWeek);
	var i;
	for (i=dayOfWeek;i<7;i++){
		if (this.counterDate.getMonthNum()==this.viewDate.getMonthNum()){
			this.writeDay();
		} else break;
	}
	this.writeBlankDays(7-i);
	this.writeLn('</tr>');
}

Calendar.prototype.writeDay = function(){
	var day = this.counterDate.getDayNum();
	var month = this.counterDate.getMonthNum();
	var year = this.counterDate.getYearNum();
	if (this.counterDate.getDayComparator()>=this.earliestDate.getDayComparator() && this.counterDate.getDayComparator()<=this.latestDate.getDayComparator()) {
		if (this.validSelectedDate && this.counterDate.getDayComparator()==this.selectedDate.getDayComparator()){
			this.writeLn('<td class="selectedDay" width="14%" title="Selected day"><a href="javascript:calendar.selectDay('+day+','+month+','+year+')">'+this.counterDate.getDayNum()+'</a></td>');
		} else {
			this.writeLn('<td class="day" width="14%" title="Select this day"><a href="javascript:calendar.selectDay('+day+','+month+','+year+')">'+this.counterDate.getDayNum()+'</a></td>');
		}
	} else {
		this.writeLn('<td class="disabledday" width="14%" title="Day unavailable">'+this.counterDate.getDayNum()+'</td>');
	}
	this.counterDate.addDay();
}

Calendar.prototype.writeBlankDays = function(colspan){
	if (colspan>0) this.writeLn('<td colspan="'+colspan+'" class="blankday">&nbsp;</td>');
}

Calendar.prototype.writeBottomControl = function(isEnabled,methodText,displayText){
	if (isEnabled){
		this.writeTableDivider();
		this.writeTableStart();
		this.writeLn('<tr><td class="dayofweek">&nbsp; &nbsp; &nbsp; &nbsp; <a href="javascript:'+methodText+'" class="closeLink">'+displayText+'</a> &nbsp; &nbsp; &nbsp; &nbsp;</td></tr>');
		this.writeTableEnd();
	}
}

//User actions

function isIEPC(){
	return navigator.platform.indexOf("Win")!=-1 && navigator.appVersion.indexOf("MSIE")!=-1;
}

Calendar.prototype.open = function(dayDate, monthYearDate){
	if ((dayDate) && (dayDate != ''))
		formFieldNameDayDate = dayDate;
	if ((monthYearDate) && (monthYearDate != ''))
		formFieldNameMonthYearDate = monthYearDate;
	var yearSpan = this.latestDate.getYearNum()-this.earliestDate.getYearNum();
	if (yearSpan == 0){
		//this.showYearControls = false;
		this.showDecadeControls = false;
	} else {
		this.showYearControls = true;
		if (yearSpan >= 10) this.showDecadeControls = true;
		else this.showDecadeControls = false;
	}
	if (this.todaysDate.getDayComparator()>this.earliestDate.getDayComparator() && this.todaysDate.getDayComparator()<this.latestDate.getDayComparator()){
		this.showTodayControl = true;
	} else {
		this.showTodayControl = false;
	}
	var formDay = this.getFormDay(formFieldNameDayDate);
	var formMonth = this.getFormMonthNum(this.getFormMonth(formFieldNameMonthYearDate));
	var formYear = this.getFormYear(formFieldNameMonthYearDate);

	this.validSelectedDate = Date.isDate(formDay,formMonth,formYear);
	if (this.validSelectedDate){
		this.setSelectedDate(formDay,formMonth,formYear);
		if (this.selectedDate.getMonthComparator()<this.earliestDate.getMonthComparator()){
			this.earliestDate.copyTo(this.viewDate);
		} else if (this.selectedDate.getMonthComparator()>this.latestDate.getMonthComparator()){
			this.latestDate.copyTo(this.viewDate);
		}
	}
	if (isIEPC()){
		this.close();
		//Fixes access / callee bug in IE PC
	}
	this.outputWindow = window.open("javascript:''","calendar" + this.id,"width="+this.width+",height="+this.height+",noresize");
	this.viewDate.setDayNum(1);
	this.writeCalendar();
	this.outputWindow.focus();
}

Calendar.prototype.close = function(){
	if (this.outputWindow && this.outputWindow.close) this.outputWindow.close();
}

Calendar.prototype.clear = function(){
	this.clearFormDate();
	this.validSelectedDate = false;
	this.close();
}

Calendar.prototype.selectDay = function(day,month,year){
	this.setSelectedDate(day,month,year);
	this.setFormDate(day,month,year,formFieldNameDayDate,formFieldNameMonthYearDate);
	document.getElementById(formFieldNameDayDate).onchange();
	this.close();
}

Calendar.prototype.viewMonth = function(changeBy){
	if (changeBy == 1)
		this.viewDate.nextMonth();
	else
		this.viewDate.previousMonth();
	this.writeCalendar();
}

Calendar.prototype.selectToday = function(){
	this.todaysDate.copyTo(this.viewDate);
	this.todaysDate.copyTo(this.selectedDate);
	this.setFormDate(this.selectedDate.getDayNum(),this.selectedDate.getMonthNum(),this.selectedDate.getYearNum(),formFieldNameDayDate,formFieldNameMonthYearDate);
	this.viewDate.setDayNum(1);
	this.writeCalendar();
}

Calendar.prototype.changeViewYear = function(changeBy){
	this.viewDate.addYears(changeBy);
	if (this.viewDate.getMonthComparator()<this.earliestDate.getMonthComparator()) this.viewDate.setMonthNum(this.earliestDate.getMonthNum());
	else if (this.viewDate.getMonthComparator()>this.latestDate.getMonthComparator()) this.viewDate.setMonthNum(this.latestDate.getMonthNum());
	this.writeCalendar();
}
