/**
 * Copyright (c) 2006 Timothy Grant Vogelsang
 *
 * Author: Timothy Grant Vogelsang <tvogelsang@gmail.com>
 */

/**
 * CalendarControl Class
 *
 */
var CalendarControl = Class.create();

CalendarControl.prototype = {
	/**
	 * Declare public values.
	 */
	variables: {
		dates: null,
		sessionDates: null,
		endDate: null,
		startDate: null,
		selectedDate: null
	},
	parameters: null,
	
	/**
	 * Gets the calendar name.
	 */
	getName: function() {
		return this.parameters.name;
	},
	
	/**
	 * Gets the calendar object.
	 */
	getObject: function() {
		return $(this.getName());
	},
	
	/**
	 * Gets the calendar year value.
	 */
	getCalendarYear: function() {
		return this.parameters.currentDate.getFullYear();
	},
	
	/**
	 * Gets the calendar month value.
	 */
	getCalendarMonth: function() {
		return this.parameters.currentDate.getMonth();
	},
	
	/**
	 * Gets the calendar month name value.
	 */
	getCalendarMonthName: function() {
		return monthNames[this.parameters.currentDate.getMonth()];
	},
	
	/**
	 * Gets the calendarControl object.
	 */
	getCalendarControl: function() {
		return $(this.parameters.clientId);
	},
	
	/**
	 * This public function handles the initialization routines.
	 */
	initialize: function(parameters) {
		this.parameters = parameters;
		
		this.variables.selectedDate = this.parameters.currentDate;
		
		this.render();
	},
	
	/**
	 * This public function handles the initialization of the calendar
	 * variables.
	 */
	initializeCalendar: function() {
		// Get start of the month
		this.variables.startDate =
			new Date(this.getCalendarYear(), this.getCalendarMonth(), 1);
		
		// Get end of the month
		this.variables.endDate =
			new Date(this.getCalendarYear(), this.getCalendarMonth() + 1, 0);
		
		this.variables.dates = new Array();
		
		var startDate = new Date(this.variables.startDate.getTime() -
			(this.variables.startDate.getDay() * 1000 * 60 * 60 * 24));
		var endDate = new Date(this.variables.endDate.getTime() +
			((6 - this.variables.endDate.getDay()) * 1000 * 60 * 60 * 24));
		
		var currentDate = new Date(startDate.getTime());
		
		// Scroll through the start and end date
		for (i = 0; currentDate.getTime() < endDate.getTime(); i++) {
			if (i > 0)
				currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1);
			
			this.variables.dates[i] = currentDate;
		}
	},
	
	/**
	 * This public function handles the initialization of the calendar
	 * contents.
	 */
	initializeContents: function() {
		var currentDate = this.parameters.currentDate;
		var responseText = null;
		
		new Ajax.Request('/en/includes/calendarView.aspx?CurrentDate=' + (currentDate.getMonth() + 1) + '/' +
																		currentDate.getDate() + '/' + 
																		currentDate.getFullYear(),
						{
							method: 'get',
							onSuccess: function(transport) {
								this.variables.sessionDates = eval(transport.responseText);
								
								// Only if we have a response
								if (this.variables.sessionDates) {
									var dates = $A(this.variables.dates);
									
									// Scroll through the dates
									dates.each( function(date) {
										var span = $('_' + getDateId(date));
										
										// Scroll through each of the rows
										for (i = 0; this.variables.sessionDates.length > i; i++) {
											if (getDateBetween(this.variables.sessionDates[i][0],
																this.variables.sessionDates[i][1], date)) {
												this.renderContentDate(span, this.variables.sessionDates[i]);
												
												break;  // stop
											}
										}
									}.bindAsEventListener(this) );
								}
							}.bindAsEventListener(this)
						} );
	},
	
	/**
	 * This public function handles the render of the control.
	 */
	render: function() {
		var calendarControl = this.getCalendarControl();
		
		calendarControl.className = 'calendarControl';
		calendarControl.style.width = this.parameters.width + 'px';
		
		this.initializeCalendar();
		
		this.renderContents(calendarControl);
		
		this.initializeContents();
	},
	
	/**
	 * This public function handles the render of the calendar title.
	 */
	renderTitle: function(calendarControl) {
		calendarControl.innerHTML =
			'<div id="calendarControlControlTitle" class="calendarControlTitle">' +
				'<table cellpadding="0" cellspacing="0" border="0" width="100%">' +
					'<tr>' +
						'<td align="center"><a href="#" onclick="' + this.getName() +  '.onPreviousClick(); return false;">&lt;&lt;</a></td>' +
						'<td align="center">' + this.getCalendarMonthName() + '&nbsp;' + this.getCalendarYear() + '</td>' +
						'<td align="center"><a href="#" onclick="' + this.getName() +  '.onNextClick(); return false;">&gt;&gt;</a></td>' +
					'</tr>' +
				'</table>' +
			'</div>';
	},
	
	/**
	 * This public function handles the render of the calendar contents.
	 */
	renderContents: function(calendarControl) {
		this.renderTitle(calendarControl);
		
		var content = '';
		
		content = '<div id="calendarControlControlContent" class="calendarControlContent">' +
				'<table cellpadding="0" cellspacing="0" border="0" width="100%" class="calendarControlDays">' +
					'<tr>';
		
		// Scroll through the days of the week
		for (i = 0; days.length > i; i++) {
			content += '<td>' + days[i] + '</td>';
		}
		
		content += '</tr>' +
				'</table>' +
				'<table cellpadding="0" cellspacing="0" border="0" width="100%" class="calendarControlDates">';
		
		content += this.renderContentDates();
		
		content += '</table>' +
			'</div>';
		
		calendarControl.innerHTML += content;
		
		var contentItems = '';
	},
	
	/**
	 * This public function handles the render of the calendar dates.
	 */
	renderContentDates: function() {
		var contentDates = '';
		
		// Scroll through the dates
		for (i = 0; this.variables.dates.length > i; i++) {
			var currentDate = this.variables.dates[i];
			
			// Start row
			if (currentDate.getDay() == 0) {
				if ((this.variables.dates.length - i) > 7)
					contentDates += '<tr class="calendarControlDateTop">';
				else
					contentDates += '<tr class="calendarControlDateBottom">';
			}
			
			contentDates += '<td id="_' + getDateId(currentDate) + '"';
			
			// Render weekend style
			if (currentDate.getDate() == this.variables.selectedDate.getDate() &&
				currentDate.getMonth() == this.variables.selectedDate.getMonth())
				contentDates += ' class="Selected"';
			else if (currentDate.getMonth() != this.getCalendarMonth())
				contentDates += ' class="NotAvailable"';
			
			contentDates += ' onClick="' + this.getName() + '.onDateClick(' + currentDate.getTime() + ')">' +
								'<table cellpadding="0" cellspacing="0" border="0" width="100%" class="calendarControlDetails">' +
									'<tr>' +
										'<td valign="top">' +
											currentDate.getDate() + 
										'</td>' +
									'</tr>' +
								'</table>' +
							'</td>';
			
			// End row
			if (currentDate.getDay() == 6)
				contentDates += '</tr>';
		}
		
		return contentDates;
	},
	
	/**
	 * This public function handles the render of the calendar date.
	 */
	renderContentDate: function(span, row) {
		if (span.className != 'Selected')
			span.className = 'Available';
		span._className = 'Available';
	},
	
	/**
	 * This public function handles the colour calendar date routine.
	 */
	colourCalendarDate: function(date) {
		var element = $('_' + getDateId(date));
		
		if (element) {
			// Render weekend style
			if (date.getDate() == this.variables.selectedDate.getDate() &&
				date.getMonth() == this.variables.selectedDate.getMonth())
				element.className = 'Selected';
			else if (date.getMonth() != this.getCalendarMonth())
				element.className = 'NotAvailable';
			else
				element.className = element._className || '';
		}
	},
	
	/**
	 * This public function handles the date click event.
	 */
	onDateClick: function(time) {
		// Previous date
		previousDate = this.variables.selectedDate;
		
		// Select current date
		this.variables.selectedDate = new Date(time);
		
		this.colourCalendarDate(this.variables.selectedDate);
		this.colourCalendarDate(previousDate);
		
		window.open(externalLink);
	},
	
	/**
	 * This public function handles the user previous click.
	 */
	onPreviousClick: function() {
		this.parameters.currentDate = new Date(this.getCalendarYear(), this.getCalendarMonth() - 1, 1);
		
		this.render();
	},
	
	/**
	 * This public function handles the user next click.
	 */
	onNextClick: function() {
		this.parameters.currentDate = new Date(this.getCalendarYear(), this.getCalendarMonth() + 1, 1);
		
		this.render();
	}
	
}

/**
 * This public function handles the conversion of date to string.
 */
function getDateId(date) {
	var result = (date.getMonth() + 1) + '_' +
				date.getDate() + '_' +
				date.getFullYear();
	
	return result;
}

/**
 * This public function handles the conversion of date to string.
 */
function getDate(date) {
	var result = (date.getMonth() + 1) + '/' +
				date.getDate() + '/' +
				date.getFullYear();
	
	return result;
}
/**
 * This public function checks the dates are equal.
 */
function getDateBetween(between1, between2, date) {
	between1 = new Date(Date.UTC(between1.getFullYear(), between1.getMonth(), between1.getDate(), 0, 0, 0));
	between2 = new Date(Date.UTC(between2.getFullYear(), between2.getMonth(), between2.getDate(), 23, 59, 59));

	return (between1.getTime() <= date.getTime() && between2.getTime() >= date.getTime());
}