/*

------------
Installation
------------

Call jaxCalendarRegister() during your document's onLoad() event to add a 
calendar to your document.  The calendar will be appended to the element 
specified by you, and will bear dimensions + look and feel as described by 
the jax-calendar.css file.  The slideshow is mostly self contained, but 
there are some steps you'll need to follow to get it working:

	1) include jax-calendar.js in your html (via <script> tag),
	2) include common/jax-xmlhttprequest.js  in your html (via <script> tag),
	3) include the contents of jax-calendar.css in your html or other css 
	   file (via <style> or <link> tags),
	4) in the body of your html have a tag with an id (preferably a <div> tag),
	5) call jaxCalendarRegister() on document load,
	6) write a server-side response script that gathers stored content (like
	   from a database) and returns it.

Parameter descriptions for jaxSlideshowRegister():

	contentURL: url that returns an xml feed to populate the slideshow
	id:         id of the element (preferably div) to append slideshow to
	
-------
Credits
-------

Authored by Dan Juliano in December 2006.

*/

var calDate = new Date();
var calYear = calDate.getFullYear();
var calMonth = calDate.getMonth();
var calMonthStart = 0;
var calMonthEmpty = true;
var calMonthJump = 0;
var calMessageDays = null;
var calMessageTitles = null;
var calMessageDescriptions = null;
var calURL = "";
var calVisible = false;

function jaxCalendarRegister(url, id) {
	calURL = url;

	jaxCalendarBuildCalendar(id);
	jaxCalendarPopulateDaysOfMonth();
}

function jaxCalendarBuildCalendar(id) {
	var html = "\n";
	
	html += "";
	
	// The 'date' div displays an expanded description off 
	// to the side of the main calendar.
	html += "<div id=\"calendar_message\" class=\"calendar_message\"></div>\n";
	
	// Set up the main displayable calendar div.
	html += "<div class=\"calendar_container\">\n";
	
	html += "	<div id=\"calendar_month\">&nbsp;</div>\n";
	html += "	<table class=\"calendar_days\">\n";
	html += "		<tr><th>S</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th></tr>\n";
	html += "		<tr>\n";
	
	// Generate 42 placeholders for days of the month.
	var day_id = "";
	for (var i = 0; i < 42; i++) {
		day_id = "calendar_" + i;
		html += "			<td id=\"" + day_id + "\">&nbsp;</td>\n";
		if (i % 7 == 6) html += "		</tr>\n			<tr>\n";
	}
	html += "		</tr>\n";
	
	html += "		<tr>\n";
	html += "			<td id=\"calendar_scroll_left\" onClick=\"\">&lt;</td>\n";
	html += "			<td id=\"calendar_loading\" colspan=\"5\"></td>\n";
	html += "			<td id=\"calendar_scroll_right\" onClick=\"\">&gt;</td>\n";
	html += "		</tr>\n";
	html += "	</table>\n";
	html += "</div>\n";
	
	document.getElementById(id).innerHTML = html;
	document.getElementById(id).style.visibility = "visible";
}

function jaxCalendarPopulateDaysOfMonth() {
	
	// Use an array of day counters to determine how many days in the passd-in month.
	var days = "31,28,31,30,31,30,31,31,30,31,30,31".split(",");
	if (calYear % 4 == 0) days = "31,29,31,30,31,30,31,31,30,31,30,31".split(",");
	var month_days = days[parseInt(calMonth)];
	
	// Which day of the week did the first day of the month start on?
	var month_start = new Date(calYear, calMonth, 1);
	calMonthStart = month_start.getDay();
	
	// Create calendar for the passed-in month;
	var id = "";
	var element = null;
	var counter = 1;
	for (var i = 0; i < 42; i++) {
		id = "calendar_" + i;
		element = document.getElementById(id);
		if ((i >= parseInt(calMonthStart)) && (i < (parseInt(month_days) + parseInt(calMonthStart)))) {
			element.innerHTML = counter++;
		} else {
			element.innerHTML = "&nbsp;";
		}
		element.className = "";
		element.onclick = null;
	}
	
	// Fill 'full month' description at the top.
	var months = "January,February,March,April,May,June,July,August,September,October,November,December".split(",");
	document.getElementById("calendar_month").innerHTML = months[calMonth] + " " + calYear;
	
	// Reset loading div, reset message div, and block ajax requests.
	document.getElementById("calendar_loading").innerHTML = "Loading";
	jaxEffectFadeReset("calendar_loading", "in");
	jaxCalendarBlockNewRequestBlock();
	
	// Call out to the server to get events for the current month.
	var url = calURL + "&year=" + calYear + "&month=" + (calMonth + 1);
	xmlRequest(url, null, jaxCalendarHandleXML);
}

function jaxCalendarBumpMonth(months) {
	if (calMonth + months < 0) {
		calDate.setFullYear(calYear - 1, (calMonth + months) + 12, 1);
	} else if (calMonth + months > 11) {
		calDate.setFullYear(calYear + 1, (calMonth + months) - 12, 1);
	} else {
		calDate.setFullYear(calYear, calMonth + months, 1);
	}
	calYear = calDate.getFullYear();
	calMonth = calDate.getMonth();
	jaxCalendarPopulateDaysOfMonth();
}
function jaxCalendarBumpMonthNoRequest(months) {
	calMonthJump += months;
}
function jaxCalendarCheckForBump() {
	if (calMonthJump == 0) return;
	var months = calMonthJump;
	calMonthJump = 0;
	jaxCalendarBumpMonth(months);
}

function jaxCalendarHandleXML(xml) {
	calMessageDays = xml.getElementsByTagName("day");
	calMessageTitles = xml.getElementsByTagName("title");
	calMessageDescriptions = xml.getElementsByTagName("description");
	var length = calMessageDays.length;

	var day = "";
	var message = "";
	var id = "";
	var element = null;
	
	calMonthEmpty = false;
	
	// Check for month with no events.
	if (length == 0) {
		calMonthEmpty = true;
		document.getElementById("calendar_loading").innerHTML = "<span class=\"calendar_noevents\">No events</span>";
	} else {
		jaxEffectFadeOut("calendar_loading");
	}
	
	// Highlight the days in the grid which contain events.
	for (var i = 0; i < length; i++) {
		day = calMessageDays[i].firstChild.nodeValue;
		if (day.length == 2 && day.indexOf("0") == 0) day = day.substring(1);
		message = calMessageDescriptions[i].firstChild.nodeValue;
		id = "calendar_" + (parseInt(calMonthStart) + (parseInt(day) - 1)); // day array is zero based ...
		element = document.getElementById(id);
		element.className = "calendar_day";
		element.onclick = function(event) { jaxCalendarShowMessage(this); };
	}
	
	// Hide the loading message, allow new ajax requests.
	jaxCalendarAllowNewRequest();
	jaxCalendarCheckForBump();
}

function jaxCalendarShowMessage(element) {

	if (calMonthEmpty == true) return;
	if (element == null) return;
	
	var html = "";
	html += "<div class=\"calendar_message_exit\" onClick=\"jaxCalendarHideMessage();\">X</div>\n";
	
	var day = (parseInt(element.id.split("_")[1]) + 1) - parseInt(calMonthStart);
	var months = "January,February,March,April,May,June,July,August,September,October,November,December".split(",");
	var month = months[calMonth] + " " + day;
	html += "\t<h4 class=\"calendar_message_month\">" + month + "</h4>\n";
	
	var xmlDay = null;
	var xmlTitle = null;
	var xmlDescription = null;
	var length = calMessageDays.length;
	
	// Highlight the days in the grid which contain events.
	for (var i = 0; i < length; i++) {
		xmlDay = calMessageDays[i].firstChild.nodeValue;
		if (xmlDay == day) {
			xmlTitle = calMessageTitles[i].firstChild.nodeValue;
			xmlDescription = calMessageDescriptions[i].firstChild.nodeValue;
			html += "\t<h5 class=\"calendar_message_title\">" + xmlTitle + "</h5>\n";
			html += "\t<p class=\"calendar_message_description\">" + xmlDescription + "</p>\n";
		}
	}
	document.getElementById("calendar_message").innerHTML = html;
	if (!calVisible) jaxEffectFadeIn("calendar_message");
	calVisible = true;
}
function jaxCalendarHideMessage() {
	jaxEffectFadeOut('calendar_message');
	calVisible = false;
}

function jaxCalendarBlockNewRequestBlock() {
	document.getElementById("calendar_scroll_left").onclick = function() { jaxCalendarBumpMonthNoRequest(-1); };
	document.getElementById("calendar_scroll_right").onclick = function() { jaxCalendarBumpMonthNoRequest(1); };
}
function jaxCalendarAllowNewRequest() {
	document.getElementById("calendar_scroll_left").onclick = function() { jaxCalendarBumpMonth(-1); };
	document.getElementById("calendar_scroll_right").onclick = function() { jaxCalendarBumpMonth(1); };
}
