//constants
var days = new Array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday");
var months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

$(function() {
	//global variables
	var date = new Date();
	var date_day = parseInt(date.getDate());
	var date_month = parseInt(date.getMonth());
	var date_year = parseInt(date.getFullYear());
	
	$.each($(".calendar"), function() {
		//private variables
		var current_date = $(this).find(".current_date a");
		var current_day = $(this).find(".curr_day");
		var current_month = $(this).find(".curr_month");
		var current_year = $(this).find(".curr_year");
		
		var month_value = $(this).find(".month_value");
		var year_value = $(this).find(".year");
		
		var month = $(this).find(".month");
		var month_button = month.find(".option_button");
		var month_options = month.find(".month_options");
		var month_options_items = month_options.find("li a");
		
		var year_up = $(this).find(".increase_year");
		var year_down = $(this).find(".decrease_year");
		
		var weeks_alldays = $(this).find(".weeks");
		var weeksdays = weeks_alldays.find(".currMonthDay");
		
		//event - month_options
		$(window).bind("click", function () {
			month_options.slideUp("fast");
		});

		month_button.live("click", function() {
			month_options.slideToggle("fast");
			return false;
		});
		
		//event - select month
		month_options_items.click(function() {
			date_month = month_options_items.index(this);
			month_options.slideUp("fast");
			loadDate(date_month, date_year);
			return false;
		});
		
		//event - move year up
		year_up.bind("click", function() {
			date_year = date_year+1;
			loadDate(date_month, date_year);
			return false;
		});
		
		//event - move year down
		year_down.bind("click", function() {
			date_year = date_year-1;
			loadDate(date_month, date_year);
			return false;
		});
		
		//event - select current date
		current_date.bind("click", function() {
			date_day = parseInt(current_day.text());
			date_month = parseInt(current_month.text())-1;
			date_year = parseInt(current_year.text());
			
			loadDate(date_month, date_year);
			return false;
		});
		
		//event - select a day
		weeksdays.live("click", function() {
			var selectedDay = parseInt($(this).text());
		
			//formulate a date from the selected day
			var selectedDate = new Date();
			
			selectedDate.setDate(selectedDay);
			selectedDate.setMonth(date_month);
			selectedDate.setFullYear(date_year);
			
			//just ouput a nicely formated date for now
			var dayExt = getDateExt(selectedDay);
			
			var weekDayNum = parseInt(selectedDate.getDay())-1;
			if (weekDayNum==-1) weekDayNum=6;
			
			var dayTitle = days[weekDayNum];
			var monthTitle = months[date_month].substring(0,3); //nice short month

			alert("Selected: " + dayTitle + " " + $(this).text() + dayExt + " " + monthTitle + " " + date_year);
		
			return false;
		});
		
		//START - load the defaults
		current_day.text(date_day.toString());
		current_month.text((date_month+1).toString());
		current_year.text(date_year.toString());
		
		loadDate(date_month, date_year);
		
		//load a date into the calendar
		function loadDate(date_month, date_year) {
			var month_name = months[date_month];
			
			//set the titles
			month_value.text(month_name);
			year_value.text(date_year.toString());
			
			//set the selected month option
			month_options.find(".current_month_option").removeClass("current_month_option");
			month_options.find("li:contains(" + month_name + ")").addClass("current_month_option");
			
			//make an actual date out of the given day/month/year
			var selectedDate = new Date();
			
			selectedDate.setDate(1); //get the first day of the selected month
			selectedDate.setMonth(date_month);
			selectedDate.setFullYear(date_year);
			
			//populate the days
			var startDay = selectedDate.getDay()-1;
			if (startDay==-1) startDay=6;
			
			var weekNum = 0, dayNum=0;
			var numDaysThisMonth = getDaysInMonth(date_month, date_year);
			
			//note: do not need to consider overflow as jan and dec have same num days
			var numDaysLastMonth = getDaysInMonth(date_month-1, date_year);
			
			//write out last month
			var weekDaysStr="<div class=\"week\">";
			
			for (var monthNum=numDaysLastMonth-startDay+1; dayNum<startDay; dayNum++, monthNum++) {
				weekDaysStr += "<a>" + monthNum.toString() + "</a>";
			}
			
			//write out this month
			for (var monthNum=1; monthNum < (numDaysThisMonth+1); dayNum++, monthNum++) {
				if (dayNum%7 == 0) weekDaysStr += "</div><div class=\"week\">";
				weekDaysStr += "<a href=\"#\" class=\"currMonthDay\">" + monthNum.toString() + "</a>";
			}
			
			//write out next month
			for (var monthNum=1; dayNum<42; dayNum++, monthNum++) {
				if (dayNum%7 == 0) weekDaysStr += "</div><div class=\"week\">";
				weekDaysStr += "<a>" + monthNum.toString() + "</a>";
			}
			weekDaysStr += "</div>";
			
			weeks_alldays.html(weekDaysStr);
			
			//highlight the current day
			weeks_alldays.find(".currDay").removeClass("currDay");
			if ((date_month == parseInt(current_month.text())-1) && (date_year == parseInt(current_year.text()))) {
				$.each(weeks_alldays.find(".currMonthDay"), function() {
					if ($(this).text()==current_day.text()) {
						$(this).addClass("currDay");
						return;
					}
				});
			}
		}
	});
});

/**
* Get number of days in a month
* @param month::int (0-11)
* @param year::int
* @return number of days in month::int
*/
function getDaysInMonth(month, year) {
	var numDays = 31;
	
	switch (parseInt(month)) {
		case 3: case 5: case 8: case 10: 
			numDays=30;
			break;
		case 1:
			if (parseInt(year)%4==0) numDays=29; //compensate for leap years
			else numDays = 28;
			break;
	}
	
	return numDays;
}

/*
* Get the extra 'st'/'nd','rd'/'th' extension on a given day
* @param day number of month::int
* @return extension::String
*/
function getDateExt(day) {
	//get the last character
	var dayStr = day.toString();
	
	//exception: if second to last character is a 1, then is is definately 'th'
	if ((dayStr.length>1) && (parseInt(dayStr[dayStr.length-2])==1))
		return "th";
	
	//otherwise, decide from the last character
	var lastChar = parseInt(dayStr[dayStr.length-1]);
	var ext = "th";
	switch (lastChar) {
		case 1: ext="st"; break;
		case 2: ext="nd"; break;
		case 3: ext="rd"; break;
	}
	return ext;
}