/**
* Event calendar widget
*
*/
function EventCalendar(el) {

	// Properties
	this.container = $(el).addClass('event-calendar');
	this.current = new Date();
	this.navLabelWidth = 0;
	this.ui = {
		/* Month navigation */
		navMonth: null,
		navMonthLabel: null,
		navMonthPrev: null,
		navMonthNext: null,

		/* Day blocks */
		dayContainer: null,
		dayHeader: null,
		dayBlocks: null,

		/* Event info */
		eventInfo: null
	};
	this.events = $.evalJSON(this.container.find('input[type=hidden]').val());

	// UI: Month navigation
	var cWidth = this.container.outerWidth();
	this.ui.navMonth = $('<div class="ec-nav-month"><a class="ec-nav-month-prev" href="#"><span>Previous month</span></a><a class="ec-nav-month-next" href="#"><span>Next month</span></a><p><span>'+this.getMonthName(this.current.getMonth())+'</span></p></div>');
	this.ui.navMonthPrev = this.ui.navMonth.children('a.ec-nav-month-prev');
	this.ui.navMonthNext = this.ui.navMonth.children('a.ec-nav-month-next');
	this.ui.navMonthLabel = this.ui.navMonth.children('p');
	this.container.append(this.ui.navMonth);

	// Month nav handlers
	this.ui.navMonthPrev.bind('click', {calendar: this, dir: -1}, this.doNavMonth);
	this.ui.navMonthNext.bind('click', {calendar: this, dir: 1}, this.doNavMonth);

	// Position month label in center of container
	this.navMonthLabelWidth = this.ui.navMonthLabel.width();
	var s = this.ui.navMonthLabel.children('span');
	s.css('left', (this.navMonthLabelWidth-s.width())/2);

	// UI: Days
	this.ui.dayContainer = $('<div class="ec-day-container"><table><thead><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr></thead><tbody></tbody></table></div>');
	this.ui.dayHeader = this.ui.dayContainer.find('table thead tr');
	this.ui.dayBlocks = this.ui.dayContainer.find('table tbody');
	this.container.append(this.ui.dayContainer);
	this.ui.dayContainer.children('table').width(this.ui.dayContainer.width());

	// UI: Event details
	this.ui.eventInfo = $('<div class="ec-event-info"></div>');
	this.container.append(this.ui.eventInfo);

	this.renderDays();
}

/**
* Move to next month.
* This is the handler for the next/prev month arrow buttons.
*
* @param Event
* @return false
*/
EventCalendar.prototype.doNavMonth = function(ev) {
	var cal = ev.data.calendar;
	var dir = ev.data.dir;
	var nm = cal.current.getMonth()+dir;
	cal.current.setMonth(nm<0 ? nm+12 : (nm>11 ? nm-12 : nm));
	var monthName = cal.getMonthName(cal.current.getMonth());
	if(nm<0 || nm>11) {
		cal.current.setYear(parseInt(cal.current.getFullYear())+dir);
	}
	cal.ui.dayBlocks.fadeOut('fast', function() {
		cal.renderDays();
	});

	var span = cal.ui.navMonthLabel.children('span');
	var sWidth = span.width();
	span.animate({left: parseInt(span.css('left'))-(cal.navMonthLabelWidth*dir), opacity: 0}, 500, 'swing', function() {
		span.html(monthName+' '+cal.current.getFullYear());
		var l = (cal.navMonthLabelWidth-span.width())/2;
		span.css('left', l+(cal.navMonthLabelWidth*dir)).animate({left: l, opacity: 1}, 500, 'swing');
	});
	return false;
}

/**
* Utility function that returns the month name for the given month number.
*
* @param int Month number (0-11)
* @return string
*/
EventCalendar.prototype.getMonthName = function(monthNum) {
	monthNum = monthNum<0 ? monthNum+12 : (monthNum>11 ? monthNum-12 : monthNum);
	return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][monthNum];
}

/**
* Render the day blocks for the current month/year. At the point this method is
* called the day blocks will have been faded out, so they are faded back in here.
*
* @return void
*/
EventCalendar.prototype.renderDays = function() {

	// Clear current blocks and re-render
	this.ui.dayBlocks.html('');
	var cy = this.current.getFullYear();
	var cm = this.current.getMonth()+1;
	var fd = new Date();
	fd.setFullYear(this.current.getFullYear());
	fd.setMonth(this.current.getMonth());
	fd.setDate(1);
	var ld = new Date();
	ld.setFullYear(this.current.getFullYear());
	ld.setMonth(this.current.getMonth()+1);
	ld.setDate(0);
	var fdDay = fd.getDay()<1 ? 6 : fd.getDay()-1;
	var ldDay = ld.getDay()<1 ? 6 : ld.getDay()-1;
	var c = 0;
	var html = '';
	for(var i=-fdDay; i<ld.getDate()+(6-ldDay); i++) {
		if(c%7==0) {
			html += '<tr>';
		}
		html += '<td>'+(i>=0 && i<ld.getDate() ? '<a href="#" rel="'+cy+'-'+cm+'-'+(i+1)+'">'+(i+1)+'</a>' : '&#160;')+'</td>';
		c++;
		if(c>0 && c%7==0) {
			html += '</tr>';
		}
	}
	this.ui.dayBlocks.html(html);
	this.ui.dayBlocks.find('a').bind('click', {calendar: this}, this.selectDate);
	if(this.events[cy] && this.events[cy][cm]) {
		for(var e in this.events[cy][cm].events) {
			var ev = this.events[cy][cm].events[e];
			this.ui.dayBlocks.find('a[rel='+cy+'-'+cm+'-'+ev._day+']').addClass('populated');
		}
	}

	// Fade in
	this.ui.dayBlocks.fadeIn('fast');
}

EventCalendar.prototype.selectDate = function(ev) {
	var cal = ev.data.calendar;
	var date = $(this).attr('rel').split('-');
	if(cal.events[date[0]][date[1]]) {
		cal.ui.eventInfo.css('display', 'none').html('');
		for(var i=0; i<cal.events[date[0]][date[1]].events.length; i++) {
			var event = cal.events[date[0]][date[1]].events[i];
			if(event._day==date[2]) {
				var el = $('<div class="box1"><p><strong></strong></p><p class="title3 left"></p><p class="right"><a class="link1">Read More</a></p></div>');
				el.find('p strong').html(event.heading);
				el.find('p.title3').html(event.eventDate);
				el.find('a').attr('href', event._url);
				cal.ui.eventInfo.append(el);
			}
		}
		cal.ui.eventInfo.slideDown(500);
	}
	else {
		cal.ui.eventInfo.css('display', 'none').html('');
	}
	return false;
}
