// Create a function for String elements to trim leading/ending whitespace
String.prototype.trim=function(){
    return this.replace(/^\s*|\s*$/g,'');
}

function ajaxCalendar(idContainer, drawSelect) {

	this.container = $(idContainer);
	this.eventsContainer;

	this.dataFile = '/calendar_data.xml.php';

	this.todaysDate = new Date();

	this.month = this.todaysDate.getMonth() + 1;
	this.year = this.todaysDate.getFullYear();
	this.days = new Array('S', 'M', 'T', 'W', 'T', 'F', 'S');
	this.months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

	this.selectedDate = new Date();

	this.myData = new Array;
	this.calDayDates = new Array();

	// hack: this is used so that call back functions access the correct instance of this object
	var me=this;

	// Used to outline the current date
	this.actualDay =  this.year + '_' + this.month + '_' + this.todaysDate.getDate();


	/*
	 * drawCalendar()
	 *
	 * creates and HTML calendar table
	 */
	this.drawCalendar = function() {

		if (!($(idContainer))) {			// Don't bother carrying on if the <div> isn't there
			return;
		}

		var calTable = document.createElement('table');
		calTable.style.margin = '0 auto';
		calTable.border = 0;
		calTable.cellSpacing = 0;

		if ($('calTable')) {
			this.container.replaceChild(calTable, $('calTable'));
		}
		else {
			this.container.appendChild(calTable);
		}
		calTable.id = 'calTable';

		var calTHead = document.createElement('thead');
		calTable.appendChild(calTHead);

		var calTBody = document.createElement('tbody');
		calTable.appendChild(calTBody);

		var calRow = document.createElement('tr');
		calTHead.appendChild(calRow);
/*
		// Display Date
		var calTd = document.createElement('th');
		calTd.innerHTML = '&laquo;';
		calTd.id = 'calPrevYear';
		calRow.appendChild(calTd);
*/
		var calTd = document.createElement('th');
		calTd.innerHTML = '&laquo;';
		calTd.id = 'calPrevMonth';
		calRow.appendChild(calTd);

		var calTd = document.createElement('th');
		calTd.colSpan = 5;
		calTd.style.textAlign = 'center';
		calTd.id = "calDisplayDate";
		calTd.innerHTML = this.months[this.month - 1] + ' ' + this.year;
		calRow.appendChild(calTd);

		var calTd = document.createElement('th');
		calTd.innerHTML = '&raquo;';
		calTd.id = 'calNextMonth';
		calRow.appendChild(calTd);
/*
		var calTd = document.createElement('th');
		calTd.innerHTML = '&raquo;';
		calTd.id = 'calNextYear';
		calRow.appendChild(calTd);
*/
		// Day Headers
		var calRow = document.createElement('tr');
		calTHead.appendChild(calRow);

		for (var i = 0; i < 7; i++) {
			var calTd = document.createElement('th');
			calTd.innerHTML = this.days[i];
			calTd.className = 'calDaysRow';

			calRow.appendChild(calTd);
		}

		// Days
		var startDate = new Date(this.year, this.month - 1, '1');
		var thisDate = new Date();
		var offset = startDate.getDay();
		var j = 0;

		var isLeap = false;
		var totalDaysPerMonth = [31, (isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

		do { // loop for each week until in next month

			calRow = document.createElement('tr');
			calTBody.appendChild(calRow);

			var totalDaysInMonth = totalDaysPerMonth[thisDate.getMonth()];

			// Each day of the week
			for (var i = 0; i < 7; i++) {

				thisDate = new Date(this.year, this.month - 1, '1');
				thisDate.setDate(startDate.getDate() + ((j * 7 + i) - offset));
				calTd = document.createElement('td');
				calTd.className = 'calDay';

				if (thisDate.getMonth() + 1 != this.month) {
					calTd.className += ' calDayInactiveMonth';
				}

				calRow.appendChild(calTd);
				calTd.innerHTML = thisDate.getDate();
				calTd.id = 'calDay_' + thisDate.getFullYear() + '_' + (thisDate.getMonth() + 1) + '_' + thisDate.getDate();

				this.calDayDates[calTd.id] = new Date(thisDate.getFullYear(), (thisDate.getMonth() + 1), thisDate.getDate());

				// only attach events to current month
				if (thisDate.getMonth() + 1 == this.month) {
					addEvent($('calDay_' + thisDate.getFullYear() + '_' + (thisDate.getMonth() + 1) + '_' + thisDate.getDate()), 'click', this.calDayClick);
					addEvent($('calDay_' + thisDate.getFullYear() + '_' + (thisDate.getMonth() + 1) + '_' + thisDate.getDate()), 'mouseover', this.calDayHover);
					addEvent($('calDay_' + thisDate.getFullYear() + '_' + (thisDate.getMonth() + 1) + '_' + thisDate.getDate()), 'mouseout', this.calDayOut);
				}
			}

			j++;
		}
		while (thisDate.getMonth() < this.month && thisDate.getFullYear() <= this.year && thisDate.getDate() < totalDaysInMonth);

		if ($('calDay_' + this.actualDay)) {
			$('calDay_' + this.actualDay).className += ' calDaySelected';
		}

		// Attach event listners
		addEvent($('calPrevMonth'), 'click', this.previousMonth);
		addEvent($('calNextMonth'), 'click', this.nextMonth);
/*
		addEvent($('calPrevYear'), 'click', this.previousYear);
		addEvent($('calNextYear'), 'click', this.nextYear);
*/

		// Are we drawing the select box also?
		if (drawSelect) {
			var selectBox = document.createElement('select');
				if ($('ajaxCalendarSelect')) {
					$(idContainer).replaceChild(selectBox, $('ajaxCalendarSelect'));
				}
				else {
					$(idContainer).appendChild(selectBox);
				}
				selectBox.id = 'ajaxCalendarSelect';
				addEvent($('ajaxCalendarSelect'), 'change', function(e) {
					var elmVal = $('ajaxCalendarSelect').value;
					var time = elmVal.split('|');

					//changeDate(parseInt(time[1]), parseInt(time[0]));
					window.location.replace('/events_calendar/' + (parseInt(time[1])) + '/' + (parseInt(time[0]) + 1) + '/');
				});
				selectBox.style.marginTop = '5px';

			this.dateObj = new Date();
			this.selectMonth = this.dateObj.getMonth();
			this.selectYear = this.dateObj.getFullYear();

			var j = 0;

			var option = document.createElement('option')
			option.innerHTML = 'select month...';
			selectBox.appendChild(option);

			for (var i = 0; i < 12; i++) {	// We'll put 12 months in the select box
				var currMonth = this.months[(this.selectMonth + j)];

				var option = document.createElement('option');
				option.value = this.selectMonth + j + '|' + this.selectYear;
				option.innerHTML = currMonth + ' ' + this.selectYear;
					selectBox.appendChild(option);

				j++;
				if ((this.selectMonth + j) == 12) {
					this.selectMonth = 0;
					j = 0;

					this.selectYear = this.dateObj.getFullYear() + 1;
				}
			}
		}

	} // this.create();


	/*
	 * gotoMonth(offset)
	 *
	 * adds 'offset' months to the current month and updates calendar
	 */
	this.gotoMonth = function(offset, actualMonth) {

		var thisDate = new Date(this.year, this.month - 1);
		var newDate = new Date(this.year, this.month - 1);

		if (actualMonth) {
			newDate.setMonth(actualMonth);
		}
		else {
			newDate.setMonth(thisDate.getMonth() + parseInt(offset));
		}

		this.year = newDate.getFullYear();
		this.month = newDate.getMonth() + 1;

		this.drawCalendar();
		this.markCalEvents();
	}

	/*
	 * gotoYear(offset)
	 *
	 * adds 'offset' years to the current year and updates calendar
	 */
	this.gotoYear = function(offset, actualYear) {

		var thisDate = new Date(this.year, this.month - 1);
		var newDate = new Date(this.year, this.month - 1);

		if (actualYear) {
			newDate.setFullYear(actualYear);
		}
		else {
			newDate.setMonth(thisDate.getMonth() + parseInt(offset));
		}

		this.year = newDate.getFullYear() + 1;
		this.month = newDate.getMonth();

		this.drawCalendar();
		this.markCalEvents();
	}


	/*
	 * changeDate(actualYear, actualMonth)
	 *
	 * Changes the date to the month supplied
	 */
	this.changeDate = function(actualYear, actualMonth) {

		var thisDate = new Date(this.year, this.month - 1);
		var newDate = new Date(this.year, this.month - 1);
		newDate.setFullYear(actualYear);
		newDate.setMonth(actualMonth);
		newDate.setDate(1);

		this.year = newDate.getFullYear();
		this.month = newDate.getMonth() + 1;

		this.drawCalendar();
		this.markCalEvents();
	}


	/*
	 * nextMonth()
	 * advances to the next month
	 */
	this.nextMonth = function() {
		me.gotoMonth(+1);
	}

	/*
	 * nextYear()
	 *
	 * advances to the next year
	 */
	this.nextYear = function() {
		me.gotoYear(+1);
	}

	/*
	 * previousMonth()
	 *
	 * advances to the previous month
	 */
	this.previousMonth = function() {
		me.gotoMonth(-1);
	}

	/*
	 * previousYear()
	 *
	 * advances to the previous year
	 */
	this.previousYear = function() {
		me.gotoYear(-1);
	}


	this.calDayClick = function(e) {
		var that = e.srcElement ? e.srcElement : this;

		if (that.className.indexOf('calDayEvent') != -1) {
			var url = that.id.split('_');
			var year = url[1];
			var month = url[2];
			var day = url[3];

			window.location.replace('/events_calendar/' + year + '/' + month + '/' + day + '/');
		}
	}

	this.calDayHover = function(e) {
		var that = e.srcElement ? e.srcElement : this;

		if (that.className.indexOf('calDayInactiveMonth') != -1) {
			// Don't highlight anything not in current month
		}
		else {
			that.style.backgroundColor = '#DDDDDD';
		}
	}

	this.calDayOut = function(e) {
		var that = e.srcElement ? e.srcElement : this;

		if (that.className.indexOf('calDaySelected') != -1) {
			that.style.backgroundColor = '#DDDDDD';
		}
		else if(that.className.indexOf('calDayEvent') != -1) {
			that.style.backgroundColor = '#FFFFFF';
		}
		else if (that.className.indexOf('calDayInactiveMonth') != -1) {
			// Don't highlight anything not in current month
		}
		else {
			that.style.backgroundColor = '#F5F5F3';
		}
	}


	this.markCalEvents = function() {
		var xmlhttp = new createRequestObject();
		xmlhttp.connect(this.dataFile, 'get', 'date='+me.year+'-'+me.month+'-1', this.addEvents);
	}

	this.addEvents = function(xml) {
		var response = xml.responseXML;
		var calEvents = response.getElementsByTagName('event_date');

		for (var i = 0; i < calEvents.length; i++) {
			if ($('calDay_' + calEvents[i].firstChild.data.trim()) && $('calDay_' + calEvents[i].firstChild.data.trim()).className.indexOf('calDayInactiveMonth') == -1) {
				$('calDay_' + calEvents[i].firstChild.data.trim()).className += ' calDayEvent';
			}
		}
	}

	this.drawCalendar();
	this.markCalEvents();

}
