var Calendar = Class.create();

Calendar.prototype = {
	weekdays: new Array('Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag'), 
	wrapper: null, 
	eventList: null, 
	eventEl: null, 
	days: null,
	selectedDayId: 'selected-calendar-day', 
	dayTitle: null, 
	
	initialize: function (root, divId) {
		this.days = new Array();
		this.eventList = {};
		var feed = root.feed;
		this.wrapper = document.getElementById(divId);
	
		if (this.wrapper.childNodes.length > 1) {
			this.wrapper.removeChild(this.wrapper.lastChild);
		}
		var secondWrapper = document.createElement('div');
		Element.addClassName(secondWrapper, 'calendar-wrapper');
		this.wrapper.appendChild(secondWrapper);
		this.wrapper = secondWrapper;
	
		// create a new unordered list
		var calNav = document.createElement('ul');
		Element.addClassName(calNav, 'day-navigation');
		
		
		for(var date, day, i = 0; i < this.weekdays.length; i++) {
			date = new Date();
			date.setDate(date.getDate() + i);
			if(date.getDay() == 0 || date.getDay() == 6) {
				continue;
			}
			day = document.createElement('li');
			day.appendChild(document.createTextNode(this.weekdays[date.getDay()].substring(0, 3)));
			calNav.appendChild(day);
			this.days.push({
				date: date, 
				element: day
			});
			Event.observe(day, 'click', this.selectDate.bindAsEventListener(this));
		}
		
		
		this.wrapper.appendChild(calNav);
		this.dayTitle = document.createElement('h3');
		this.wrapper.appendChild(this.dayTitle);
		this.eventEl = document.createElement('ul');
		Element.addClassName(this.eventEl, 'events');
		this.wrapper.appendChild(this.eventEl);
		
		if(feed.entry) {
			this.addEvents(feed.entry);
		}
		this.showDate(new Date());
		calNav.firstChild.setAttribute('id', this.selectedDayId);
	},
	
	addEvents: function (events, eventType) {
		// loop through each event in the feed
		for (var i = 0; i < events.length; i++) {
			var entry = events[i];
			var title = entry.title.$t;
			var content = entry.content.$t;
			var start = this.parseGCalTime(entry['gd$when'][0].startTime);
			di = this.getDateIndex(start);
			if(!this.days[di]) {
				this.days[di] = new Array();
			}
			
			this.days[di].push({
				entry		: entry, 
				title		: title, 
				content		: content, 
				start		: start, 
				eventType	: eventType
			});
		}
	},
	
	getDateIndex: function (date) {
		return date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate();
	},
	
	selectDate: function (evt) {
		if($(this.selectedDayId)) {
			$(this.selectedDayId).setAttribute('id', '');
		}
		var element = Event.element(evt);
		for(var i = 0; i < this.days.length; i++) {
			if(this.days[i].element == element) {
				element.setAttribute('id', this.selectedDayId);
				this.showDate(this.days[i].date);
				return;
			}
		}
	},
	
	showDate: function (date) {
		di = this.getDateIndex(date);
		if (this.dayTitle.childNodes.length > 0) {
			this.dayTitle.removeChild(this.dayTitle.lastChild);
		}
		this.dayTitle.appendChild(document.createTextNode(this.weekdays[date.getDay()] + ' ' + date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.getFullYear()));
		while(this.eventEl.childNodes.length > 0) {
			this.eventEl.removeChild(this.eventEl.lastChild);
		}
		
		if(this.days[di]) {
			var events = this.days[di];
		
			for(var event, entry, i = 0; i < events.length; i++) {
				entry = document.createElement('li');
				event = events[i];
				entryTitle = document.createElement('h4');
				entryTitle.appendChild(document.createTextNode(event.title));
				entry.appendChild(entryTitle);
				
				if(typeof event.content != 'undefined') {
					entryContent = document.createElement('p');
					entryContent.appendChild(document.createTextNode(event.content));
					entry.appendChild(entryContent);
				}
				this.eventEl.appendChild(entry);
			}
		}
	}, 
	
	//Stolen from gcal samples and slightly modified to return a date object instead of a formatted string
	parseGCalTime: function (gCalTime) { 
		// text for regex matches
		var remtxt = gCalTime;
	
		function consume(retxt) {
			var match = remtxt.match(new RegExp('^' + retxt));
			if (match) {
				remtxt = remtxt.substring(match[0].length);
				return match[0];
			}
			return '';
		}
	
		// minutes of correction between gCalTime and GMT
		var totalCorrMins = 0;
	
		var year = consume('\\d{4}');
		consume('-?');
		var month = consume('\\d{2}');
		consume('-?');
		var dateMonth = consume('\\d{2}');
		var timeOrNot = consume('T');
	
		// if a DATE-TIME was matched in the regex 
		if (timeOrNot == 'T') {
			var hours = consume('\\d{2}');
			consume(':?');
			var mins = consume('\\d{2}');
			consume('(:\\d{2})?(\\.\\d{3})?');
			var zuluOrNot = consume('Z');
	
			// if time from server is not already in GMT, calculate offset
			if (zuluOrNot != 'Z') {
				var corrPlusMinus = consume('[\\+\\-]');
				if (corrPlusMinus != '') {
					var corrHours = consume('\\d{2}');
					consume(':?');
					var corrMins = consume('\\d{2}');
					totalCorrMins = (corrPlusMinus=='-' ? 1 : -1) * 
							(Number(corrHours) * 60 + 
				(corrMins=='' ? 0 : Number(corrMins)));
				}
			} 
	
			// get time since epoch and apply correction, if necessary
			// relies upon Date object to convert the GMT time to the local
			// timezone
			var originalDateEpoch = Date.UTC(year, month - 1, dateMonth, hours, mins);
			var gmtDateEpoch = originalDateEpoch + totalCorrMins * 1000 * 60;
			return new Date(gmtDateEpoch);
		}
		
		var date = new Date();
		date.setFullYear(year);
		date.setMonth(month - 1);
		date.setDate(dateMonth);
		return date;
	}
}

var calendarObj;

function handleGcalJson(root) {
	calendarObj = new Calendar(root, 'calendar');
}