Calendar = Class.create();
Calendar.prototype = {
	initialize: function(container) {
		this.container = container;
		this.navContainer = 'calendar_navigation';
		this.weekClass = 'calendar_week';
		this.dayClass = 'calendar_day';
		this.blankDayClass = 'calendar_blank_day';
		this.todayClass = 'calendar_today';
		this.months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
		this.daysInMonth;
		this.weeksInMonth;
		this.endOfMonth = false;
		this.startOfMonth = false;
		this.today = new Date();
		this.target = new Date(this.today);
		this.target.setDate(1);
		this.events = new CalendarEvents(this);
		var calendar = this;
		Event.observe('last', 'click', function (e) { calendar.lastMonth() });
		Event.observe('next', 'click', function (e) { calendar.nextMonth() });
		this.construct();
		return this;
	},
	construct: function() {
		this.month = this.target.getMonth();
		$('month').innerHTML = this.months[this.month] + ' ' + ((this.target.getYear() < 2000) ? this.target.getYear() + 1900 : this.target.getYear());
		if (!Element.empty(this.container)) 
			this.deconstruct();
		this.weeksInMonth = Math.ceil((this.firstDayOfMonth() + this.daysInMonth()) / 7);
		for (var x = 0; x < this.weeksInMonth; x++)
			$(this.container).appendChild(this.constructWeek());
		this.events.loadEvents();
	},
	deconstruct: function() {
		for (var x = ($(this.container).childNodes.length - 1); x >= 0; x--)
			Element.remove($(this.container).childNodes[x]);
	},
	constructWeek: function() {
		var week = document.createElement('div');
		Element.addClassName(week, this.weekClass);
		for (var x = 0; x < 7; x++)
			week.appendChild(this.constructDay(x));
		return week;
	},
	constructDay: function(x) {
		var day = document.createElement('div');
		if ((this.target.getDate() <= this.daysInMonth()) && (this.target.getMonth() == this.month) && (this.endOfMonth == false)) {
			if (this.startOfMonth == false) {
				if (this.firstDayOfMonth() == x)
					this.startOfMonth = true;	
			}
			if (this.startOfMonth == true) {
				if (this.target.getTime() == this.today.getTime())
					Element.addClassName(day, this.todayClass);
				else
					Element.addClassName(day, this.dayClass);
				day.innerHTML = this.target.getDate();
				day.setAttribute('date', (this.target.getMonth() + 1) + '-' + this.target.getDate() + '-' + ((this.target.getYear() < 2000) ? this.target.getYear() + 1900 : this.target.getYear()));
				day.setAttribute('timestamp', this.target.getTime());
				if (this.target.getDate() == this.daysInMonth())
					this.endOfMonth = true;
				if (this.target.getDate() < this.daysInMonth())
					this.target.setDate(this.target.getDate() + 1);
			} else {
				Element.addClassName(day, this.blankDayClass);	
			}
		} else {
			Element.addClassName(day, this.blankDayClass);
		}
		return day;
	},
	nextMonth: function() {
		this.startOfMonth = false;
		this.endOfMonth = false;
		this.target.setDate(1);
		this.target.setMonth(this.target.getMonth() + 1);
		this.construct();
	},
	lastMonth: function() {
		this.startOfMonth = false;
		this.endOfMonth = false;
		this.target.setDate(1);
		this.target.setMonth(this.target.getMonth() - 1);
		this.construct();
	},
	daysInMonth: function() {
		var daysInMonth = new Array(31, ((this.target.getYear() % 4 == 0 && this.target.getYear() % 100 != 0) || this.target.getYear() % 400 == 0 ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		return daysInMonth[this.target.getMonth()];
	},
	firstDayOfMonth: function() {
		var temp = new Date(this.target);
		temp.setDate(1);
		return temp.getDay();
	}
}

CalendarEvents = Class.create();
CalendarEvents.prototype = {
	initialize: function(calendar) {
		this.calendar = calendar;
		this.eventContainer = 'event_list';
		this.eventClass = 'calendar_event';
		this.dates = null;
		this.selected = new Date();
	},
	loadEvents: function() {
		var events = this;
		var opt = {
			method: 'get',
			parameters: 'month=' + (this.calendar.target.getMonth() + 1) + '&year=' + ((this.calendar.target.getYear() < 2000) ? this.calendar.target.getYear() + 1900 : this.calendar.target.getYear()),
			onSuccess: function(t) { events.parseEvents(t) },
			onFailure: function(t) { alert(t) }
		}
		new Ajax.Request('xml/calendar.php', opt);
	},
	parseEvents: function(t) {
		var xml = t.responseXML;
		var calendarXML = xml.getElementsByTagName('calendar')[0];
		var dateXML = calendarXML.getElementsByTagName('date');
		this.dates = new Array(dateXML.length);
		for (var x = 0; x < dateXML.length; x++) {
			var eventXML = dateXML[x].getElementsByTagName('event');
			this.dates[x] = new Array(2);
			this.dates[x]['date'] = dateXML[x].getAttribute('id');
			this.dates[x]['event'] = new Array(eventXML.length);
			for (var y = 0; y < eventXML.length; y++) {
				this.dates[x]['event'][y] = new Array(9);
				try { this.dates[x]['event'][y]['name'] = eventXML[y].getElementsByTagName('name')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['name'] = '' }
				try { this.dates[x]['event'][y]['startTime'] = eventXML[y].getElementsByTagName('startTime')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['startTime'] = '' }
				try { this.dates[x]['event'][y]['endTime'] = eventXML[y].getElementsByTagName('endTime')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['endTime'] = '' }
				try { this.dates[x]['event'][y]['locale'] = eventXML[y].getElementsByTagName('locale')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['locale'] = '' }
				try { this.dates[x]['event'][y]['description'] = eventXML[y].getElementsByTagName('description')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['description'] = '' }
				var contact = eventXML[y].getElementsByTagName('contact')[0];
				try { this.dates[x]['event'][y]['organization'] = contact.getElementsByTagName('organization')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['organization'] = '' }
				try { this.dates[x]['event'][y]['contactName'] = contact.getElementsByTagName('name')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['contactName'] = '' }
				try { this.dates[x]['event'][y]['contactEmail'] = contact.getElementsByTagName('email')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['contactEmail'] = '' }
				try { this.dates[x]['event'][y]['contactWeb'] = contact.getElementsByTagName('web')[0].firstChild.data } catch (e) { this.dates[x]['event'][y]['contactWeb'] = '' }
			}	
		}
		this.addEvents();
	},
	addEvents: function() {
		var days = $A($$('#' + this.calendar.container + ' div.' + this.calendar.dayClass));
		var events = this;
		days.each(function(d) {
			for (var x = 0; x < events.dates.length; x++) {
				if (events.dates[x]['date'] == d.getAttribute('date')) {
					Element.addClassName(d, events.eventClass);
					Event.observe(d, 'click', function(e) { events.displayEvents(e) });	
				}
			}
		});
	},
	displayEvents: function(e) {
		if (!Element.empty(this.eventContainer)) {
			for (var x = ($(this.eventContainer).childNodes.length - 1); x >= 0; x--)
				Element.remove($(this.eventContainer).childNodes[x]);
		}
		var element = Event.element(e);
		this.selected.setTime(element.getAttribute('timestamp'));
		var events = this;
		var e = this.dates.detect( function (d) {
			if (d['date'] == element.getAttribute('date'))
				return true;
		});
		e['event'].each( function (e) {
				$('event_date').innerHTML = events.calendar.months[events.selected.getMonth()] + " " + events.selected.getDate() + ", " + ((events.selected.getYear() < 2000) ? events.selected.getYear() + 1900 : events.selected.getYear());
				new Insertion.Bottom(events.eventContainer, '<h1>' + e['name'] + '</h1>');
				new Insertion.Bottom(events.eventContainer, '<h2>' + e['organization'] + '</h2>');
				new Insertion.Bottom(events.eventContainer, '<h2>' + e['locale'] + '</h2>');
				new Insertion.Bottom(events.eventContainer, '<h2>' + e['startTime'] + ((e['endTime'] != '') ? (' - ' + e['endTime']) : '') + '</h2>');
				new Insertion.Bottom(events.eventContainer, '<p>' + e['description'] + '</p>');								
		});
	}
}

function createCalendar() {
	var calendar = new Calendar('calendar_chart');
}

Event.observe(window, 'load', function (e) { createCalendar() });