function Calendar( school, year, month )
{
	this.school = school;
	this.today = new Date();

	this.id = "calendar-" + this.today.getTime();

	if( year == undefined && month == undefined )
	{
		this.year = this.today.getFullYear();
		this.month = this.today.getMonth() + 1;
	}
	else
	{		
		this.year = year;
		this.month = month;
	}

	this.retrieved = new Array();
	this.events = new Array();
	this.monthNamesLong = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
}

Calendar.prototype.getDaysInMonth = function( year, month ) 
{
	var m = [ 31,28,31,30,31,30,31,31,30,31,30,31 ];
	if( month != 2 ) return m[ month - 1 ];
	if( year%4 != 0 ) return m[ 1 ];
	if( year%100 == 0 && year%400 != 0 ) return m[1];
	return m[ 1 ] + 1;
}

Calendar.prototype.getMonthStartDay = function( year, month ) 
{
	var date = new Date();
	date.setFullYear( year, month - 1, 1 );
	return date.getDay();
}

Calendar.prototype.getMonthEndDay = function( year, month ) 
{	
	var date = new Date();
	date.setFullYear( year, month - 1, this.getDaysInMonth( year, month ) );
	return date.getDay();
}

Calendar.prototype.create = function( container )
{
	var loading = document.createElement( "div" );
	loading.id = this.id + "-loading";
	loading.className = "loading";
	loading.innerHTML = "Loading...";

	var controls = document.createElement( "div" );
	controls.id = this.id + "-controls";
	controls.className = "controls";

	var previous = document.createElement( "div" );
	previous.id = this.id + "-controls-previous";
	previous.calendar = this;
	previous.className = "previous";
	previous.innerHTML = "Previous";
	previous.onclick = function()
	{
		this.calendar.changeMonth( this.calendar.month - 1 );
	};

	var current = document.createElement( "div" );
	current.id = this.id + "-controls-current";
	current.className = "current";
	current.innerHTML = "Current";

	var next = document.createElement( "div" );
	next.id = this.id + "-controls-next";
	next.calendar = this;
	next.className = "next";
	next.innerHTML = "Next";
	next.onclick = function()
	{
		this.calendar.changeMonth( this.calendar.month + 1 );
	};

	controls.appendChild( previous );
	controls.appendChild( next );
	controls.appendChild( current );

	var table = document.createElement( "table" );
	table.cellSpacing = 1;
	table.cellPadding = 0;
	table.className = "cal-table";
	table.id = this.id + "-table";

	var rowDays = table.insertRow( 0 );
	
	var cellSunday = rowDays.insertCell( 0 );
	cellSunday.className = "day-name";
	cellSunday.innerHTML = "Sunday";

	var cellMonday = rowDays.insertCell( 1 );
	cellMonday.className = "day-name";
	cellMonday.innerHTML = "Monday";

	var cellTuesday = rowDays.insertCell( 2 );
	cellTuesday.className = "day-name";
	cellTuesday.innerHTML = "Tuesday";

	var cellWednesday = rowDays.insertCell( 3 );
	cellWednesday.className = "day-name";
	cellWednesday.innerHTML = "Wednesday";

	var cellThursday = rowDays.insertCell( 4 );
	cellThursday.className = "day-name";
	cellThursday.innerHTML = "Thursday";

	var cellFriday = rowDays.insertCell( 5 );
	cellFriday.className = "day-name";
	cellFriday.innerHTML = "Friday";

	var cellSaturday = rowDays.insertCell( 6 );
	cellSaturday.className = "day-name";
	cellSaturday.innerHTML = "Saturday";

	var monthSelector = document.createElement( "div" );
	monthSelector.className = "cal-monthselect";
	monthSelector.name = "month";

	calendar = this;

	var selectMonth = document.createElement( "select" );
	selectMonth.id = this.id + "-monthselect";
	selectMonth.className = "monthselect";
	for( i = 0; i < this.monthNamesLong.length; i++ )
	{
		selectMonth.options[ i ] = new Option( this.monthNamesLong[ i ], i );
	}
	selectMonth.onchange = function()
	{
		monthNum = parseInt( this.options[ this.selectedIndex ].value ) + 1;
		calendar.changeMonth( monthNum );
	};

	var selectYear = document.createElement( "select" );
	selectYear.id = this.id + "-yearselect";
	selectYear.name = "year";
	selectYear.className = "yearselect";

	for( i = ( this.year - 2 ); i < ( this.year + 5 ); i++ )
	{
		selectYear.options[ selectYear.options.length ] = new Option( i, i );
	}
	selectYear.onchange = function()
	{
		yearNum = parseInt( this.options[ this.selectedIndex ].value );
		calendar.changeYear( yearNum );
	};

	monthSelector.appendChild( selectMonth );	
	monthSelector.appendChild( document.createTextNode( " , " ) );	
	monthSelector.appendChild( selectYear );

	container.appendChild( loading );
	container.appendChild( controls );
	container.appendChild( table );
	container.appendChild( monthSelector );

	this.updateSelects();

	this.drawMonth( this.year, this.month );
}

Calendar.prototype.updateSelects = function()
{
	document.getElementById( this.id + "-monthselect" ).selectedIndex = this.month - 1;

	selectYear = document.getElementById( this.id + "-yearselect" );
	selectYear.options.length = null;
	for( i = ( this.year - 2 ); i < ( this.year + 5 ); i++ )
	{
		selectYear.options[ selectYear.options.length ] = new Option( i, i );
	}
	for( i = 0; i < selectYear.length; i++ )
	{
		if( selectYear.options[ i ].value == this.year )
		{
			selectYear.selectedIndex = i;
			break;
		}
	}
}

Calendar.prototype.changeYear = function( year )
{
	this.year = year;

	this.updateSelects();

	this.drawMonth( this.year, this.month );
}

Calendar.prototype.changeMonth = function( month )
{
	if( month > 12 )
	{
		this.month = 1;
		this.year++;
	}
	else if( month < 1 )
	{
		this.month = 12;
		this.year--;
	}
	else
	{
		this.month = month;
	}

	this.updateSelects();

	this.drawMonth( this.year, this.month );
}

Calendar.prototype.drawMonth = function( year, month )
{
	var current = document.getElementById( this.id + "-controls-current" );
	current.innerHTML = this.monthNamesLong[ month - 1 ] + ", " + year;

	var startCell = this.getMonthStartDay( year, month );
	var endCell = startCell + this.getDaysInMonth( year, month );

	var rows = Math.ceil( ( endCell + ( 6 - this.getMonthEndDay( year, month ) ) ) / 7 );
	var day = 0;

	var table = document.getElementById( this.id + "-table" );

	if( table.rows.length > 0 )
	{
		for( var r = table.rows.length - 1; r >= 1 ; r-- )
		{
			table.deleteRow( r );
		}
	}

	for( var r = 0; r < rows; r++ )
	{
		var row = table.insertRow( r + 1 );

		for( var i = 0; i < 7; i++ )
		{
			var cellNum = ( r * 7 ) + i;
			day = ( cellNum >= startCell ) && ( cellNum < endCell ) ? ( day + 1 ) : 0;

			var thisDate = new Date();
			thisDate.setFullYear( this.year, this.month - 1, day );

			var isToday = false;
			if( this.year == this.today.getFullYear() && this.month - 1 == this.today.getMonth() && day == this.today.getDate() )
			{
				isToday = true;
			}

			var cell = row.insertCell( i );
			if( day > 0 ) cell.id = this.year + "-" + ( (this.month < 10 ) ? "0" + this.month : this.month ) + "-" + ( ( day < 10 ) ? "0" + day : day );
			cell.className = day > 0 ? ( isToday ? "today" : "day" ) : "empty";
			
			var divDay = document.createElement( "div" );
			if( day > 0 ) divDay.id = "day-number-" + this.year + "-" + ( (this.month < 10 ) ? "0" + this.month : this.month ) + "-" + ( ( day < 10 ) ? "0" + day : day );
			divDay.className = "day-number";
			divDay.innerHTML = ( day > 0 ) ? day : "";

			var divEvents = document.createElement( "ul" );
			if( day > 0 ) divEvents.id = "day-events-" + this.year + "-" + ( (this.month < 10 ) ? "0" + this.month : this.month ) + "-" + ( ( day < 10 ) ? "0" + day : day );
			divEvents.className = "events";

			cell.appendChild( divDay );
			cell.appendChild( divEvents );

			var thisMonth = ( ( month < 10 ) ? "0" + month : month );
			var thisDay = ( ( day < 10 ) ? "0" + day : day );

			this.drawEvents( year, thisMonth, thisDay );
		}
	}
	this.getEvents( this.year, this.month );
}

Calendar.prototype.addEvent = function( event )
{
	var year = event.startDateYear;
	var month = event.startDateMonth;
	var day = parseInt( event.startDateDay );

	day = day < 10 ? "0" + day : day;

	if( this.events[ year + "-" + month + "-" + day ] == undefined )
	{
		this.events[ year + "-" + month + "-" + day ] = new Array();
	}

	this.events[ year + "-" + month + "-" + day ].push( event );
}

Calendar.prototype.drawEvents = function( year, month, day )
{
	if( this.events[ year + "-" + month + "-" + day ] && this.events[ year + "-" + month + "-" + day ].length > 0 )
	{
		if( !document.getElementById( "day-events-" +  year + "-" + month + "-" + day ) )
		{
			return false;
		}		

		var ulEvents = document.getElementById( "day-events-" +  year + "-" + month + "-" + day );

		this.events[ year + "-" + month + "-" + day ].sort( sortTime );
				
		for( var e = 0; e < this.events[ year + "-" + month + "-" + day ].length; e++ )
		{
			var event = this.events[ year + "-" + month + "-" + day ][ e ];

			if( event.title == " " ) continue;

			var liEvent = document.createElement( "li" );

			var spanTitle = document.createElement( "span" );
			spanTitle.className = "title";
			spanTitle.innerHTML = event.title;
			
			if( event.allDay == false && event.startTime != "-1" ) 
			{ 			
				var spanTime = document.createElement( "span" );
				spanTime.className = "time";

				minutes = event.startTime.substr( 3, 2 );
				ampm = "AM";
				hours = parseInt( event.startTime.substr( 0, 2 ), 10 );				
				if( hours > 12 )
				{
					ampm = "PM";
					hours = hours - 12;
				}
				startTime = hours + ":" + minutes + " " + ampm;

				spanTime.innerHTML = startTime + " ";
				liEvent.appendChild( spanTime ); 
			}
			else if( event.allDay == true )
			{
				liEvent.className = "allday";
			}
			else if( event.multiDay == true )
			{
				liEvent.className = "multiday";
			}

			liEvent.appendChild( spanTitle );

			ulEvents.appendChild( liEvent );
		}
	}
}

function sortTime(a, b)
{
	return parseInt( a.startTime.replace( ":", "" ), 10 ) - parseInt( b.startTime.replace( ":", "" ), 10 );
}

Calendar.prototype.getEvents = function( year, month )
{
	if( this.retrieved[ year + "-" + month ] ) return false;

	document.getElementById( this.id + "-loading" ).style.display = "block";

	ajax = createAjaxObj();
	if( ajax ) 
	{	
		calendar = this;

		ajax.onreadystatechange = function() 
		{ 
			if( ajax.readyState == 4 ) 
			{
				if( ajax.status == 200 ) 
				{
					var xml = ajax.responseXML;
					var text = ajax.responseText;
					var events = xml.getElementsByTagName("event");
					
					var title = "";
					var start = "";
					var end = "";
					var allday = false;

					for( i = 0; i < events.length; i++ )
					{
						title = events[i].getElementsByTagName("title")[0].firstChild ? events[i].getElementsByTagName("title")[0].firstChild.nodeValue : "";
						start = events[i].getElementsByTagName("start")[0].firstChild ? events[i].getElementsByTagName("start")[0].firstChild.nodeValue : "";
						end = events[i].getElementsByTagName("end")[0].firstChild ? events[i].getElementsByTagName("end")[0].firstChild.nodeValue  : "";
						allday = events[i].getElementsByTagName("allday")[0].firstChild ? events[i].getElementsByTagName("allday")[0].firstChild.nodeValue : "";
	
						var event = new Event();

						event.title = title;
						
						event.startDate( start );
						event.endDate( end );

						event.allDay = allday == "1" ? true : false;

						if( event.getStartDate() != event.getEndDate() && event.allDay == false )
						{
							event.multiDay = true;							
							
							var startLoopAt = parseInt( event.startDateDay ) + 0;
							var endLoopAt = event.endDateDay;

							if( event.endDateMonth > event.startDateMonth )
							{
								endLoopAt = calendar.getDaysInMonth( newEvent.startDateYear, newEvent.startDateMonth );
							}

							for( j = startLoopAt; j <= endLoopAt; j++ )
							{
								var newEvent = new Event();
								newEvent.title = event.title;
								newEvent.startDateYear = event.startDateYear;
								newEvent.startDateMonth = event.startDateMonth;
								newEvent.startDateDay = j;

								newEvent.endDateYear = event.endDateYear;
								newEvent.endDateMonth = event.endDateMonth;
								newEvent.endDateDay = event.endDateDay;

								newEvent.startTime = "-1";
								newEvent.endTime = "-1";

								newEvent.multiDay = true;

								calendar.addEvent( newEvent );
							}
						}
						else
						{

							calendar.addEvent( event );
						}
					}					

					for( d = 0; d <= calendar.getDaysInMonth( calendar.year, calendar.month ); d++ )
					{
						var day = d < 10 ? "0" + d : d;
						var month = month < 10 ? "0" + calendar.month: calendar.month;
						calendar.drawEvents( year, month, day );
					}
					
					calendar.retrieved[ calendar.year + "-" + calendar.month ] = true;

					document.getElementById( calendar.id + "-loading" ).style.display = "none";

				}
			}
		};

		try 
		{
			var url = ( window.location.href.indexOf( "https://" ) == 0 ) ? "https://" : "http://";
			url += getDomain() + "/schools/api/calendar/?school=" + this.school + "&year=" + this.year + "&month=" + this.month;

			ajax.open( "GET", url, true );
		} 
		catch( err ) 
		{ 
			alert( "XMLHttpRequest.open() failed: " + err ); 
			return;
		}
		ajax.send( null );
	}
	else
	{
		alert( "Init failed" ); 
		return;
	}
}

function Event()
{
	this.startDateYear = 0;
	this.startDateMonth = 0;
	this.startDateDay = 0;

	this.endDateYear = 0;
	this.endDateMonth = 0;
	this.endDateDay = 0;

	this.startTime = 0;
	this.endTime = 0;

	this.allDay = false;
	this.multiDay = false;
}

Event.prototype.getStartDate = function()
{
	return this.startDateYear + "-" + this.startDateMonth + "-" + this.startDateDay;
}

Event.prototype.getEndDate = function()
{
	return this.endDateYear + "-" + this.endDateMonth + "-" + this.endDateDay;
}

Event.prototype.startDate = function( start )
{
	this.startDateYear = start.substr( 0, 4 );
	this.startDateMonth = start.substr( 5, 2 );
	this.startDateDay = start.substr( 8, 2 );
	this.startTime = start.substr( 11, 5 );
}

Event.prototype.endDate = function( end )
{
	this.endDateYear = end.substr( 0, 4 );
	this.endDateMonth = end.substr( 5, 2 );
	this.endDateDay = end.substr( 8, 2 );
	this.endTime = end.substr( 11, 5 );
}