function addDayClasses() {
	$("#event-calendar table tbody td").each(function() {
		if (!$(this).hasClass("inactive")) {
			if (!$(this).hasClass("rnd")) {
				var rnd = Math.floor(Math.random() * 5);
				$(this).addClass("rnd rnd-" + rnd);
			}
		}
	});
}

$(document).ready(function() {
	addDayClasses();
	
	$('#event-calendar table a').click(function() {
		var self = $(this);
		var target = self.attr('href');
		
		//$('#event-calendar table td').removeClass('active');
		//self.parent('td').addClass('active');
		
		$('#event-calendar table td').removeClass('selected');
		self.parent('td').addClass('selected');
		
		$('#event-description li').hide();
		$(target).show();
		
		return false;
	});
	
	$('#event-calendar table td.selected a').click();
});

/*
function initEventCalendar() {
	/*
	 * Initialise calendar widget with the following constants. Change these
	 * values in accordance with changes to the source HTML document.
	 * /

	var calendar = document.getElementById('event-calendar');

	if (calendar) {
		Calendar.init({
			title        : document.getElementById('calendar_month').firstChild,
			tBody        : calendar.getElementsByTagName('tbody')[0],
			next         : document.getElementById('event-next'),
			previous     : document.getElementById('event-prev'),
			description  : document.getElementById('event-description'),
			uriTemplate  : document.getElementsByTagName("h1")[0].getElementsByTagName("a")[0].getAttribute("href") + 'calendar-ajax/{$year}/{$month}/',
			titleTemplate: '{$month} {$year}'
		});
	}
}

var Calendar = {
	init: function(options) {
		/*
		 * Initialise `Calendar` constants and assign event handlers.
		 * /

		var events = options.description.getElementsByTagName('li'),
		    links  = options.tBody.getElementsByTagName('td'),
		    title  = options.title.firstChild.data;

		Calendar.DETAIL  = Calendar.getByClass(events, 'active');
		Calendar.ACTIVE  = Calendar.getByClass(links, 'active');
		Calendar.OPTIONS = options;
		Calendar.DATE    = new Date('1 ' + title);
		Calendar.TMP     = document.createDocumentFragment(),
		Calendar.MONTHS  = {}; // Cache
		Calendar.BODY    = Calendar.MONTHS[title] = options.tBody;
		Calendar.BUSY    = false;

		options.tBody.parentNode.onclick = Calendar.showEvent;

		options.next.onclick = options.previous.onclick = Calendar.showMonth;
	},

	showEvent: function() {
		/*
		 * Since this "click" event is defined on the <table> element, we must
		 * determine whether the event's target element is an <a> element that
		 * references a corresponding event description. If so, transfer the
		 * "active" `className` to this description, and similar for the clicked
		 * <td> element.
		 * /

		var evt    = arguments[0] || event,
		    target = evt.target || evt.srcElement, // W3C || Microsoft
		    item   = document.getElementById(/[^#]+$/.exec(target.href));

		if (item) {
			Calendar.ACTIVE.className   = '';
			Calendar.DETAIL.className   = '';
			item.className              = 'active';
			target.parentNode.className = 'active';

			Calendar.DETAIL = item;
			Calendar.ACTIVE = target.parentNode;
		}

		return false;
	},

	showMonth: function() {
		/*
		 * If the `Calendar.MONTHS` cache contains an existing <tbody> for this
		 * month, use that; otherwise add a new <tbody> to the cache and request
		 * this month's event data.
		 * /

		console.log("show month" + Calendar.BUSY)

		if (Calendar.BUSY) return false;

		var date         = Calendar.DATE,
		    displacement = (this !== Calendar.OPTIONS.previous) ? 1 : -1;

		Calendar.DATE.setMonth(date.getMonth() + displacement);

		var year      = date.getFullYear(),
		    month     = date.getMonth(),
		    monthName = Calendar.MONTH_NAMES[month],
		    template  = Calendar.OPTIONS.titleTemplate,
		    title     = Calendar.format(template, 'month,year', monthName, year),
		    previous  = Calendar.BODY,
		    current;

		if (title in Calendar.MONTHS) {
			current = Calendar.MONTHS[title];

		} else {
			Calendar.BUSY = true;
			Calendar.sendEventsRequest(Calendar.DATE);

			current = Calendar.MONTHS[title] = previous.cloneNode(true);

			var daysOffset = (date.getDay() + 6) % 7, // Adjust for M..S week
			    daysAmount = new Date(year, month + 1, 0).getDate(),
			    cells      = current.getElementsByTagName('td'),
			    i          = 42;

			while (i--) {
				if (i < daysOffset || i >= daysOffset + daysAmount) {

					cells[i].className = 'inactive';
					cells[i].innerHTML = '';

				} else {

					cells[i].className = '';
					cells[i].innerHTML = i - daysOffset + 1;
				}
			}
		}

		previous.parentNode.replaceChild(current, previous);

		Calendar.OPTIONS.title.firstChild.data = title;

		Calendar.BODY = current;

		return false;
	},

	format: function(template, order) {
		/*
		 * Format `template` with names given by `order` and values given as
		 * remaining arguments.
		 * /

		var names = order.match(/[\w-]+/g),
		    data  = {},
		    i     = 1;

		for (var j = 0, name; name = names[j]; ++j) {
			data[name] = arguments[j + 2];
		}

		return template.replace(/\{\$(.+?)}/g, function(match, name) {
			return data[name];
		});
	},

	getByClass: function(nodeList, className) {
		/*
		 * Abstraction to help `Calendar.init`. Return the first element in
		 * `nodeList` that has class `className`.
		 * /

		var i = nodeList.length,
		    r = new RegExp('(?:\\s|^)' + className + '(?:\\s|$)');

		while (i--) {
			if (r.test(nodeList[i].className)) return nodeList[i];
		}

		return null;
	},

	sendEventsRequest: function(date) {
		/*
		 * Issue an `XMLHttpRequest` to the URI obtained by evaluating the
		 * provided URI template with `date`'s year and month.
		 * /

		var template = Calendar.OPTIONS.uriTemplate,
		    year     = date.getFullYear(),
		    month    = date.getMonth() + 1;

		if (month < 10) month = '0' + month;

		var resource = Calendar.format(template, 'year month', year, month),
		    client   = window.XMLHttpRequest
			               ? new XMLHttpRequest()
			               : new ActiveXObject('Microsoft.XMLHTTP');

		client.open('GET', resource, true);
		client.send(null);

		if (client.addEventListener) {
			client.addEventListener('load', Calendar.insertEvents, false);

		} else {
			client.onreadystatechange = function() {
				Calendar.insertEvents.call(client);
			};
		}
	},

	insertEvents: function() {
		if (this.readyState == 4) {

			var xml = this.responseXML;

			if (xml) {
				
				/*
				 * Add links to the related <tbody> element. Append event
				 * descriptions to the description container element.
				 * /

				var title    = xml.documentElement.getAttribute('month'),
				    cells    = Calendar.BODY.getElementsByTagName('td'),
				    offset   = (new Date('1 ' + title).getDay() + 6) % 7 - 1,
				    template = '<a href="#event-{$id}">{$day}</a>',
				    tmp      = Calendar.TMP,
				    events   = xml.getElementsByTagName('event'),
				    i        = events.length,
				    id,
				    event,
				    day,
				    item,
				    cellIndex,
				    cell;

				while (i--) {
					event          = events[i];
					day            = parseInt(event.getAttribute('day'));
					item           = tmp.appendChild(document.createElement('li'));
					id             = event.getAttribute('id');
					item.id        = "event-" + id;
					item.innerHTML = event.firstChild.data;
					cellIndex      = day + offset;
					cell           = cells[cellIndex];
					cell.innerHTML = Calendar.format(template, 'id day', id, day);
				}

				Calendar.OPTIONS.description.appendChild(tmp);

				Calendar.BUSY = false;
				
				addDayClasses();

			} else {
				/*
				 * Handle error. This includes the case where `this.status != 200`.
				 *
				 * Currently, errors are handled by re-issuing the request after a
				 * 2.5 second delay, but the following statement should be changed
				 * if alternate error handling measures are required.
				 * /

				setTimeout(Calendar.sendEventsRequest, 2500, Calendar.DATE);
			}
		}
	}
};

Calendar.MONTH_NAMES = [
	'January',
	'February',
	'March',
	'April',
	'May',
	'June',
	'July',
	'August',
	'September',
	'October',
	'November',
	'December'
];

if (document.addEventListener) {
	/*
	 * Multiple EventListeners are added for `Calendar.init` to accommodate
	 * browsers that do not fire a "DOMContentLoaded" event.
	 *
	 * If the browser does fire a "DOMContentLoaded" event, the "load" listener
	 * must be removed to avoid duplicate calls.
	 * /

	window.addEventListener('load', initEventCalendar, false);

	document.addEventListener('DOMContentLoaded', initEventCalendar, false);

	document.addEventListener(
		'DOMContentLoaded',
		function() {
			window.removeEventListener('load', initEventCalendar, false);
		},
		false);

} else {
	/*
	 * Set `window.onload` to `Calendar.init`, preserving the previous `onload`
	 * handler if it exists.
	 * /

	var previousLoadHandler = window.onload,
	    combinedLoadHandler = function() {
		                          previousLoadHandler.apply(this, arguments);
		                          initEventCalendar();
	                          };

	window.onload = previousLoadHandler
		                ? combinedLoadHandler
		                : initEventCalendar;
}
*/
