<!--
	var Calendar = new Class({
	
		// implements
		Implements: [Options],

		// options
		options: {
			ID: 0,
			date: new Date(),
			callbackSelectDate: null,
			callbackPrevMonth: null,
			callbackNextMonth: null,
			callbackDisabled: null,
			months: new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
			days: new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')
		},
		
		// initialization
		initialize: function(options) {
			// set options
			this.setOptions(options);
			
			// Create calendar
			var table = $(this.options.ID).set({
				'class': 'calendar',
				'cellspacing': 0,
				'cellpadding': 0,
				'summary': "This month's calendar"
			});
			if ( !table )
				alert("No calendar table with that ID exists: " + this.options.ID);
		
			// Caption
			this.createCaption(this.options.date).inject(table);
		
			// Head
			this.createHead(this.options.date).inject(table);
		
			// Body
			this.createBody(this.options.date).inject(table);
		},
		
		isToday: function(year, month, day) {
			if ( this.options.date.getFullYear() == year && this.options.date.getMonth() == month && this.options.date.getDate() == day )
				return true;
				
			return false;
		},
		
		selectDate: function(year, month, day) {
			this.draw(year, month);
			//Object.setClass('selected');
		},
		
		createCaption: function(date) {
			// Create caption
			var caption = new Element('caption');
			
			// <<
			if ( this.options.callbackPrevMonth != null )
			{
				var anchor = new Element('a', {
					'href': "javascript:" + GetFunctionName(this.options.callbackPrevMonth) + "(" + date.getFullYear() + ", " + date.getMonth() + ");",
					'html': "&laquo;"
				}).inject(caption);
				
				// Month name
				caption.appendText(' ' + this.options.months[date.getMonth()] + ' ');
				
				// >>
				var anchor = new Element('a', {
					'href': "javascript:" + GetFunctionName(this.options.callbackNextMonth) + "(" + date.getFullYear() + ", " + (date.getMonth() + 2) + ");",
					'html': "&raquo;"
				}).inject(caption);
			} else {
				caption.appendText("\u00AB " + this.options.months[date.getMonth()] + " \u00BB");
			}
			
			return caption;
		},

		createHead: function(date) {
			// Setup table header (Days)
			var tr = new Element('tr');
			for ( var i = 0; i < this.options.days.length; i++ )
			{
				new Element('th', {
					'scope': 'col',
					'abbr': this.options.days[i],
					'title': this.options.days[i],
					'text': this.options.days[i].charAt(0)
				}).inject(tr);
			}
			
			// Create table head
			return new Element('thead').grab(tr);
		},
		
		createBody: function(date) {
			// Create table body
			var tbody = new Element('tbody');
		
			// Create calendar body
			var tr = new Element('tr');
			for ( var i = 0; i < (date.firstDayOfMonth() + date.daysInMonth() >= 36 ? 42 : 35); i++ )
			{
				var td = new Element('td');
				
				var cellData = document.createTextNode((i < date.firstDayOfMonth() || (i - date.firstDayOfMonth() + 1) > date.daysInMonth()) ? "\u00a0" : (i - date.firstDayOfMonth() + 1));
				if ( this.isToday(date.getFullYear(), date.getMonth(), i - date.firstDayOfMonth() + 1) )
					td.addClass('today');
				else if ( this.options.callbackDisabled && this.options.callbackDisabled(date.getFullYear(), date.getMonth() + 1, i - date.firstDayOfMonth() + 1) )
					td.addClass('disabled');
				else if ( i - date.firstDayOfMonth() + 1 <= date.daysInMonth() )
				{
					if ( this.options.callbackSelectDate != null )
					{
						var anchor = document.createElement('a');
						anchor.setAttribute('href', "javascript:" + GetFunctionName(this.options.callbackSelectDate) + "(" + date.getFullYear() + ", " + (date.getMonth() + 1) + ", " + (i - date.firstDayOfMonth() + 1) + ");");
						anchor.appendChild(cellData);
						cellData = anchor;
					}
				}
				td.appendChild(cellData);
				tr.appendChild(td);
					
				if ( (i + 1) % 7 == 0 )
				{
					tbody.appendChild(tr);
					tr = document.createElement('tr');
				}
			}
		
			return tbody;
		},
		
		draw: function() {
			// Requires first 2 parameters for now
			if ( arguments.length < 2 )
				alert('Draw function requires at least 2 arguments');
				
			var year = arguments[0];
			if ( !year )
				alert('Draw function requires parameter: year');
			
			var month = arguments[1];
			if ( !month )
				alert('Draw function requires parameter: month');
				
			var day = arguments[2];
			if ( !day )
				day = 1;
				
			var date = new Date(year, month, day);
			
			// Get calendar table
			var table = $(this.options.ID);
			if ( !table )
				alert("No calendar table with that ID exists: " + this.options.ID);

			// Remove caption
			var caption = table.getElementsByTagName('caption')[0];
			table.removeChild(caption);
			
			// Remove thead
			var thead = table.getElementsByTagName('thead')[0];
			table.removeChild(thead);
			
			// Remove tbody
			var tbody = table.getElementsByTagName('tbody');
			if ( tbody.length == 1 ) // Firefox
				table.removeChild(tbody[0]);
			else // IE
				table.removeChild(tbody[1]);
			
			// Caption
			this.createCaption(date).inject(table);
		
			// Head
			this.createHead(date).inject(table);
		
			// Body
			this.createBody(date).inject(table);
		}
	});
	
	function GetFunctionName(fn)
	{
		if ( fn.name ) // Firefox
			return fn.name;
			
		var m = fn.toString().match(/^\s*function\s+([^\s\(]+)/);
		return m ? m[1] : "";
	}
//-->