
function DynamicCalendar( month, year, elementId ) {
	this.month = month;
	this.year = year;
	this.elementId = elementId;
	this.element = null;
	
	
	this.Load = function() {
		this.element = document.getElementById( this.elementId );
		this.Update();
	}
	this.Next = function() {
		this.month += 1;
		if( this.month > 11 ) {
			this.month = 0;
			this.year += 1;
		}
		this.Update();
	}
	this.Previous = function() {
		this.month -= 1;
		if( this.month < 0 ) {
			this.month = 11;
			this.year -= 1;
		}
		this.Update();
	}
	
	
	this.Update = function( response ) {
		if( response == undefined ) {
			// Render the calendar.
			this.element.innerHTML = this.RenderCalendar();
			var xmlrpc = new XMLRPCJob( '/xmlrpc/events.xmlrpc.php', 'm=' + ( this.month + 1 ) + '&y=' + this.year, false, this );
			xmlrpc.oncomplete = function() { this.callbackObject.Update( this.xmlHttp.responseXML ); }
			xmlrpc.Execute();
			return;
		}
		
		// Render the calendar.
		this.element.innerHTML = this.RenderCalendar( response );
		
		document.getElementById( this.elementId + 'Back' ).onclick = GetMethodReference( this, 'Previous' );
		document.getElementById( this.elementId + 'Forward' ).onclick = GetMethodReference( this, 'Next' );
	}
	
	
	this.RenderCalendar = function( xmlData ) {
		var events = new Array();
		
		if( xmlData != undefined ) {
			var eventData = xmlData.getElementsByTagName( 'event' );
			for( var i = 0; i < eventData.length; i++ ) {
				var event = eventData[ i ];
				var eventTitleEng = event.getElementsByTagName( 'titleEng' )[ 0 ];
				var eventTitleEst = event.getElementsByTagName( 'titleEst' )[ 0 ];
				var eventTimestamp = event.getElementsByTagName( 'timestamp' )[ 0 ];
				
				events.push( { titleEng : ( eventTitleEng.textContent == undefined ? eventTitleEng.text : eventTitleEng.textContent ), titleEst : ( eventTitleEst.textContent == undefined ? eventTitleEst.text : eventTitleEst.textContent ), timestamp : ( eventTimestamp.textContent == undefined ? eventTimestamp.text : eventTimestamp.textContent ) } );
			}
		}
		
		// Get a date object representing the first day of the target month.
		var monthStart = new Date( this.year, this.month, 1 );
		
		// Get a date object representing today.
		var today = new Date().getTime() / 1000;
	
		// Compute the number of days in this month.
		var monthLength = 32 - new Date( this.year, this.month, 32 ).getDate()
		
		// Figure out which day of the week the first day of this month is.
		var monthStartDay = monthStart.getDay();
		
		// Initialize the output string.
		var html = "<div class='month'><img id='" + this.elementId + "Back' src='/images/previous.png' alt='' title='' />" + this.MonthTextFromIndex( this.month ) + ", " + this.year + "<img id='" + this.elementId + "Forward' src='/images/next.png' alt='' title='' /></div>";
		
		
		html += "<table class='calendar" + ( xmlData == undefined ? ' loading' : '' ) + "' cellpadding='0' cellspacing='1' width='100%'>";
		html += "<tbody>";
		
		// Setup the day header.
		html += "<tr class='header'>";
		html += "<td width='15%'>Sun</td>";
		html += "<td width='14%'>Mon</td>";
		html += "<td width='14%'>Tue</td>";
		html += "<td width='14%'>Wed</td>";
		html += "<td width='14%'>Thu</td>";
		html += "<td width='14%'>Fri</td>";
		html += "<td width='15%'>Sat</td>";
		html += "</tr>";
		
		// Begin the first week.
		html += "<tr class='week'>";
		
		// A tracking variable for which day of the week the current iteration refers to.
		var currentDay = monthStartDay;
		
		// Fill in any days of the first week that fall in the previous month.
		for( var dayCounter = 0; dayCounter < currentDay; dayCounter++ ) {
			html += "<td class='invalid'></td>";
		}
		
		// Iterate through each day of the month, breaking at the end of each week.
		for( var currentDate = 1; currentDate <= monthLength; currentDate++ ) {
			// If this date in the month is a Sunday, start a new row.
			if( currentDay == 0 && currentDate != 1 ) html += "</tr><tr class='week'>";
			
			// Get the start and end timestamp for this day.
			var dayStart = new Date( this.year, this.month, currentDate, 0, 0, 0 ).getTime() / 1000;
			var dayStop = new Date( this.year, this.month, currentDate, 23, 59, 59 ).getTime() / 1000;
			
			// Check to see if any events occur on this day.
			var event = false;
			for( var i in events ) {
				if( events[ i ].timestamp >= dayStart && events[ i ].timestamp <= dayStop ) {
					event = true;
					break;
				}
			}
			
			var dayClass = ( today >= dayStart && today <= dayStop ? "today" : "" );
			if( event ) dayClass += ( dayClass.length > 0 ? " " : "" ) + "event";
			
			// Append the current day's html.
			html += "<td" + ( dayClass.length > 0 ? " class='" + dayClass + "'" : "" ) + ">";
			if( event ) html += "<a href='/calendar/" + this.year + "/" + ( this.month + 1 ) + "/'>";
			html += currentDate;
			if( event ) html += "</a>";
			html += "</td>";
			
			currentDay = ( currentDay + 1 ) % 7;
		}
		
		for( var dayCounter = ( currentDay == 0 ? 7 : currentDay ); dayCounter < 7; dayCounter++ ) {
			html += "<td class='invalid'></td>";
		}
		
		html += "</tr>";
		
		html += "</tbody>";
		html += "</table>";
		
		html += "<div class='detail'></div>";
		
		return html;
	}
	
	
	this.MonthIndexFromText = function( text ) {
		switch( text ) {
			case "January": return 0;
			case "February": return 1;
			case "March": return 2;
			case "April": return 3;
			case "May": return 4;
			case "June": return 5;
			case "July": return 6;
			case "August": return 7;
			case "September": return 8;
			case "October": return 9;
			case "November": return 10;
			case "December": return 11;
			default: return -1;
		}
	}
	
	this.MonthTextFromIndex = function( index ) {
		switch( index ) {
			case 0: return "January";
			case 1: return "February";
			case 2: return "March";
			case 3: return "April";
			case 4: return "May";
			case 5: return "June";
			case 6: return "July";
			case 7: return "August";
			case 8: return "September";
			case 9: return "October";
			case 10: return "November";
			case 11: return "December";
			default: return "Invalid";
		}
	}
}
