//
// "drawCalendar" object - displays one month
//
function drawCalendar() {

	// from: http://www.javascriptkit.com/script/cut20.shtml
	// Copyright 1996 - Tomer and Yehuda Shiran
	// Feel free to "steal" this code provided that you leave this notice as is.
	// Additional examples from the book can be found at http://www.geocities.com/SiliconValley/9000/
	// For more information contact Tomer or Yehuda Shiran yshiran@iil.intel.com

	function leapYear(year) {
		if (year % 4 == 0) // basic rule
		return true // is leap year
		/* else */ // else not needed when statement is "return"
		return false // is not leap year
	}
	
	function getDays(month, year) {
		// create array to hold number of days in each month
		var ar = new Array(12)
		ar[0] = 31 // January
		ar[1] = (leapYear(year)) ? 29 : 28 // February
		ar[2] = 31 // March
		ar[3] = 30 // April
		ar[4] = 31 // May
		ar[5] = 30 // June
		ar[6] = 31 // July
		ar[7] = 31 // August
		ar[8] = 30 // September
		ar[9] = 31 // October
		ar[10] = 30 // November
		ar[11] = 31 // December
		
		// return number of days in the specified month (parameter)
		return ar[month]
	}
	
	this.setCal = function (strLink) {
		// standard time attributes
		var now = new Date()
		var year = now.getFullYear();
		var month = now.getMonth()
		var date = now.getDate()
		now = null
		
		// create instance of first day of month, and extract the day on which it occurs
		var firstDayInstance = new Date(year, month, 1)
		var firstDay = firstDayInstance.getDay()
		firstDayInstance = null
		
		// number of days in current month
		var days = getDays(month, year)
		
		// call function to draw calendar
		this.drawCal(firstDay + 1, days, date, month, year, strLink)
	}
	
	this.drawCal = function (firstDay, lastDate, date, month, year, strLink) {
		// constant table settings
		var border = 0 // 3D height of table's border
		var cellspacing = 0 // width of table's border
		var todayColor = "red" // color specifying today's date in the calendar
		
		var monthName = new Array(12)
		monthName[0] = "January"
		monthName[1] = "February"
		monthName[2] = "March"
		monthName[3] = "April"
		monthName[4] = "May"
		monthName[5] = "June"
		monthName[6] = "July"
		monthName[7] = "August"
		monthName[8] = "September"
		monthName[9] = "October"
		monthName[10] = "November"
		monthName[11] = "December"
		
		
		// create basic table structure
		var text = "" // initialize accumulative variable to empty string
		
		text += '<TABLE BORDER=' + border + ' CELLSPACING=' + cellspacing;
		text += '>' // table settings
		text += '<tr>';
		text += '<td align=right><b>';
		if (strLink != '') text += '<a href="' + strLink + '" >';
		text += '&lt;';
		if (strLink != '') text += '</a>';
		text += '</b></td>';
		text += '<td COLSPAN=5 align=center>';
		if (strLink != '') text += '<a href="' + strLink + '" >';
		text += '<b>' + monthName[month] + ' ' + year + '</b>';
		if (strLink != '') text += '</a>';
		text += '</td>';
		text += '<td align=left><b>';
		if (strLink != '') text += '<a href="' + strLink + '" >';
		text += '&gt;';
		if (strLink != '') text += '</a>';
		text += '</b></td>';
		text += '</tr>';
		
		// variables to hold constant settings
		var openCol = '<TD>'
		var closeCol = '&nbsp;</TD>'
		
		// create array of abbreviated day names
		var weekDay = new Array(7)
		weekDay[0] = "Sun"
		weekDay[1] = "Mon"
		weekDay[2] = "Tue"
		weekDay[3] = "Wed"
		weekDay[4] = "Thu"
		weekDay[5] = "Fri"
		weekDay[6] = "Sat"
		
		// create first row of table to set column width and specify week day
		text += '<TR>';
		for (var dayNum = 0; dayNum < 7; ++dayNum) {
			text += openCol + weekDay[dayNum] + closeCol 
		}
		text += '</TR>'
		
		// declaration and initialization of two variables to help with tables
		var digit = 1
		var curCell = 1
		
		for (var row = 1; row <= Math.ceil((lastDate + firstDay - 1) / 7); ++row) {
			text += '<TR>';
			for (var col = 1; col <= 7; ++col) {
				if (digit > lastDate) break;
				if (curCell < firstDay) {
					text += '<TD>&nbsp;</TD>';
					curCell++
				} else {
					text += '<TD>'
					if (strLink != '') text += '<a href="' + strLink + '" >';
					if (digit == date) text += '<FONT COLOR="' + todayColor + '">'
					text += digit
					if (digit == date) text += '</font>';
					if (strLink != '') text += '</a>';
					text += '&nbsp;</TD>'
					digit++;
				}
			}
			text += '</TR>'
		}
		
		// close all basic table tags
		text += '</TABLE>'
		
		// print accumulative HTML string
		document.write(text) 
	}
}

//
// "getChurchYear" object: creates and displays the "church year"
//
function getChurchYear() {
	var easterDateList = new Array(
	/* 2000*/ new Date("April 23, 2000"),
	/* 2001*/ new Date("April 15, 2001"),
	/* 2002*/ new Date("March 31, 2002"),
	/* 2003*/ new Date("April 20, 2003"),
	/* 2004*/ new Date("April 11, 2004"),
	/* 2005*/ new Date("March 27, 2005"),
	/* 2006*/ new Date("April 16, 2006"),
	/* 2007*/ new Date("April 08, 2007"),
	/* 2008*/ new Date("March 23, 2008"),
	/* 2009*/ new Date("April 12, 2009"),
	/* 2010*/ new Date("April 04, 2010"),
	/* 2011*/ new Date("April 24, 2011"),
	/* 2012*/ new Date("April 08, 2012"),
	/* 2013*/ new Date("March 31, 2013"),
	/* 2014*/ new Date("April 20, 2014"),
	/* 2015*/ new Date("April 05, 2015"),
	/* 2016*/ new Date("March 27, 2016"),
	/* 2017*/ new Date("April 16, 2017"),
	/* 2018*/ new Date("April 01, 2018"),
	/* 2019*/ new Date("April 21, 2019"),
	/* 2020*/ new Date("April 12, 2020"),
	/* 2021*/ new Date("April 04, 2021"),
	/* 2022*/ new Date("April 17, 2022"),
	/* 2023*/ new Date("April 09, 2023"),
	/* 2024*/ new Date("March 31, 2024"),
	/* 2025*/ new Date("April 20, 2025"),
	/* 2026*/ new Date("April 05, 2026"),
	/* 2027*/ new Date("March 28, 2027"),
	/* 2028*/ new Date("April 16, 2028"),
	/* 2029*/ new Date("April 01, 2029"),
	/* 2030*/ new Date("April 21, 2030"),
	/* 2031*/ new Date("April 13, 2031"),
	/* 2032*/ new Date("March 28, 2032"),
	/* 2033*/ new Date("April 17, 2033"),
	/* 2034*/ new Date("April 09, 2034"),
	/* 2035*/ new Date("March 25, 2035"),
	/* 2036*/ new Date("April 13, 2036"),
	/* 2037*/ new Date("April 05, 2037"),
	/* 2038*/ new Date("April 25, 2038"),
	/* 2039*/ new Date("April 10, 2039"),
	/* 2040*/ new Date("April 01, 2040"),
	/* 2041*/ new Date("April 21, 2041"),
	/* 2042*/ new Date("April 06, 2042"),
	/* 2043*/ new Date("March 29, 2043"),
	/* 2044*/ new Date("April 17, 2044"),
	/* 2045*/ new Date("April 09, 2045"),
	/* 2046*/ new Date("March 25, 2046"),
	/* 2047*/ new Date("April 14, 2047"),
	/* 2048*/ new Date("April 05, 2048"),
	/* 2049*/ new Date("April 18, 2049"),
	/* 2050*/ new Date("April 10, 2050"),
	/* 2051*/ new Date("April 02, 2051"),
	/* 2052*/ new Date("April 21, 2052"),
	/* 2053*/ new Date("April 06, 2053"),
	/* 2054*/ new Date("March 29, 2054"),
	/* 2055*/ new Date("April 18, 2055"),
	/* 2056*/ new Date("April 02, 2056"),
	/* 2057*/ new Date("April 22, 2057"),
	/* 2058*/ new Date("April 14, 2058"),
	/* 2059*/ new Date("March 30, 2059"),
	/* 2060*/ new Date("April 18, 2060"),
	/* 2061*/ new Date("April 10, 2061"),
	/* 2062*/ new Date("March 26, 2062"),
	/* 2063*/ new Date("April 15, 2063"),
	/* 2064*/ new Date("April 06, 2064"),
	/* 2065*/ new Date("March 29, 2065"),
	/* 2066*/ new Date("April 11, 2066"),
	/* 2067*/ new Date("April 03, 2067"),
	/* 2068*/ new Date("April 22, 2068"),
	/* 2069*/ new Date("April 14, 2069"),
	/* 2070*/ new Date("March 30, 2070"),
	/* 2071*/ new Date("April 19, 2071"),
	/* 2072*/ new Date("April 10, 2072"),
	/* 2073*/ new Date("March 26, 2073"),
	/* 2074*/ new Date("April 15, 2074"),
	/* 2075*/ new Date("April 07, 2075")
	)
	
	var strYear = new Array("Year A", "Year B", "Year C")
	var strDailyYear = new Array("Year One", "Year Two")
	var strDOW = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

	this.setYear = function(xYear) {
		var ix1;
		var ix2 = 0;
		var xDate;

		this.currYear = xYear;

		this.xmasDate = new Date(this.currYear-1, 11, 25);
	
		this.adventDate = new Date(this.xmasDate);
		var x3 = this.xmasDate.getDay();
		if (x3 == 0) x3 = 7;
		dateAdd(this.adventDate, -(x3+21));
	
		this.xmasSeasonDate = new Date(this.xmasDate);
		var x3 = this.xmasSeasonDate.getDay();
		dateAdd(this.xmasSeasonDate, 7-x3);
		
		this.epiphDate = new Date(this.currYear, 0, 6);
		this.epiphSeasonDate = new Date(this.epiphDate);
		var x3 = this.epiphSeasonDate.getDay();
		dateAdd(this.epiphSeasonDate, 7-x3);
	
		this.easterDate = easterDateList[this.currYear-2000];
	
		this.epiphLastDate = new Date(this.easterDate);
		dateAdd(this.epiphLastDate, -49);
	
		this.ashWedDate = new Date(this.easterDate);
		dateAdd(this.ashWedDate, -46);
		this.lentDate = new Date(this.easterDate);
		dateAdd(this.lentDate, -42);
		this.pentDate = new Date(this.easterDate);
		dateAdd(this.pentDate, 49);
		this.palmDate = new Date(this.easterDate);
		dateAdd(this.palmDate, -7);
		this.trinDate = new Date(this.pentDate);
		dateAdd(this.trinDate, 7);
	
		var xmasDateNext = new Date(this.currYear, 11, 25);
		this.adventDateNext = new Date(xmasDateNext);
		var x3 = xmasDateNext.getDay();
		if (x3 == 0) x3 = 7;
		dateAdd(this.adventDateNext, -(x3+21));
	
		this.pentLastDate = new Date(this.adventDateNext);
		dateAdd(this.pentLastDate, -7);
	
		this.nameList = new Array();
		this.weekList = new Array();

		xDate = new Date(this.adventDate);
		for (ix1 = 1; ix1 <= 4; ix1++) {
			this.nameList[ix2] = fixOrdinal(ix1 + "th Week of Advent");
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
		}   
	
		this.nameList[ix2] = "Christmas: ("+ strDOW[this.xmasDate.getDay()] + ")";
		this.weekList[ix2++] = this.xmasDate;

		xDate = new Date(this.xmasSeasonDate);
		for (ix1 = 1; xDate < this.epiphDate; ix1++) {
			this.nameList[ix2] = "Week " + ix1 + " Christmas";
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
		}   
	
		this.nameList[ix2] = "Epiphany: ("+ strDOW[this.epiphDate.getDay()] + ")";
		this.weekList[ix2++] = this.epiphDate;

		xDate = new Date(this.epiphSeasonDate);
		for (ix1 = 1; xDate < this.epiphLastDate; ix1++) {
			this.nameList[ix2] = "Week " + ix1 + " Epiphany";
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
		}   
		this.nameList[ix2] = "Last Week Epiphany";
		this.weekList[ix2++] = this.epiphLastDate;
	
		this.nameList[ix2] = "Ash Wed";
		this.weekList[ix2++] = this.ashWedDate;
	
		var xDate = new Date(this.lentDate);
		for (ix1 = 1; ix1 <= 5; ix1++) {
			this.nameList[ix2] = fixOrdinal("Week of " + ix1 + "th Sunday in Lent");
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
		}   
	
		this.nameList[ix2] = "Holy Week";
		this.weekList[ix2++] = this.palmDate;
		this.nameList[ix2] = "Easter Week";
		this.weekList[ix2++] = this.easterDate;
		var xDate = new Date(this.easterDate);
		dateAdd(xDate, 7);
		for (ix1 = 2; xDate < this.pentDate; ix1++) {
			this.nameList[ix2] = fixOrdinal("Week of " + ix1 + "th Sunday after Easter");
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
		}   
		this.nameList[ix2] = "Week of Whitsunday (Pentecost)";
		this.weekList[ix2++] = this.pentDate;
		this.nameList[ix2] = "Week of Holy Trinity Sunday";
		this.weekList[ix2++] = this.trinDate;
		xDate = new Date(this.pentDate);
		dateAdd(xDate, 14);

		var ixProper = this.pentDate.getTime() - (new Date(this.currYear, 4, 8)).getTime();
		ixProper += (4*60*60*1000);
		ixProper /= (7*24*60*60*1000);
		ixProper = Math.floor(ixProper);
		ixProper += 3;
		for (ix1 = 2; xDate < this.pentLastDate; ix1++) {
			this.nameList[ix2] = fixOrdinal("Wk of " + ix1 + "th Sun after Pentecost: Proper " + ixProper);
			this.weekList[ix2++] = new Date(xDate);
			dateAdd(xDate, 7);
			ixProper++;
		}   
		this.nameList[ix2] = "Last Wk Pentecost";
		this.weekList[ix2++] = this.pentLastDate;
		this.nameList[ix2] = "Week 1 Advent";
		this.weekList[ix2++] = this.adventDateNext;
		this.weekCount = ix2;

		this.lectionaryYear = strYear[(this.currYear+2)%3];
		this.dailyOfficeYear = strDailyYear[(this.currYear+1)%2] 
	}

	this.writeYearAsTable = function() {
		var ix1;
		
		//
		// Write out the year.
		//
		document.writeln("<table>");
		document.writeln("<tr><td colspan=2>" + (this.currYear-1) + " - " + this.currYear + "</td></tr>");
		document.writeln("<tr><td colspan=2>Lectionary: " + this.lectionaryYear + "</td></tr>");
		document.writeln("<tr><td colspan=2>Daily Office: " + this.dailyOfficeYear + "</td></tr>");
	
		for (ix1 = 0; ix1 < this.weekCount; ix1++ ) {
			document.writeln("<tr><td>" + this.nameList[ix1] + ': </td><td style="vertical-align: middle; ">' + formatDateMMDDYYYY(this.weekList[ix1]) + "</td></tr>");
		}   
		document.writeln("</table>")
	}

	this.setDate = function(xDate) {
		//
		// Check if date prior to 11/27.  If so, then assume it's before advent.
		//
		var testDate = new Date(xDate.getFullYear(), 10, 27);
		if (xDate.getTime() <= testDate.getTime()) {
			this.setYear(xDate.getFullYear());
			return;
		}

		//
		// Check for exact start of advent
		//
		var xmasDate = new Date(xDate.getFullYear(), 11, 25);
	
		var adventDate = new Date(xmasDate);
		var x3 = xmasDate.getDay();
		if (x3 == 0) x3 = 7;
		dateAdd(adventDate, -(x3+21));
		if (xDate.getTime() < adventDate.getTime()) {
			this.setYear(xDate.getFullYear());
		} else {
			this.setYear(xDate.getFullYear()+1);
		}
	}

	function fixOrdinal(inStr) {
		outStr = inStr.replace("1th","1st"); 
		outStr = outStr.replace("2th","2nd"); 
		outStr = outStr.replace("3th","3rd"); 
		outStr = outStr.replace("11st","11th"); 
		outStr = outStr.replace("12nd","12th"); 
		outStr = outStr.replace("13rd","13th"); 
		return outStr;
	}

	function localDateDiff(date1, date2) {
		var delta = date1.getTime() - date2.getTime();
		
		delta += (4*60*60*1000);
		delta /= (24*60*60*1000);
		return Math.floor(delta);
	}

	//
	// Initialize up for today
	//
	this.setDate(new Date());
}

