MooTools.lang.setLanguage("sv-SE");

EventCalendar = new Class({
	baseElement: null,
	eventNodes: new Array(),
	eventNodesByMonth: {},
	currentMonth: '',
	
	initialize: function(baseElement) {
		this.baseElement = baseElement;
		this.initializeEventNodes();
		this.initializeTimeline();
		this.selectCurrentMonth();
		this.drawGuiElements();
		this.draw();
	},
	
	initializeEventNodes: function() {
		this.baseElement.getElements('div.event').each(function(eventElement) {
			this.eventNodes.push(new EventNode(eventElement));
		}, this);
	},
	
	initializeTimeline: function() {
		this.sortEventNodesByEventDate();
		this.groupEventNodesByMonth();
	},
	
	sortEventNodesByEventDate: function() {
		this.eventNodes.sort(function(node1, node2) { return node1.compareTo(node2); });
	},
	
	groupEventNodesByMonth: function() {
		this.eventNodes.each(function(node) {
			if (node.eventDate) {
				this.initializeEventMonth(node.getMonthIdentifier());
				this.eventNodesByMonth[node.getMonthIdentifier()].push(node);
			}
		}, this);
	},
	
	initializeEventMonth: function(monthIdentifier) {
		if (this.eventNodesByMonth[monthIdentifier] == null) {
			this.eventNodesByMonth[monthIdentifier] = new Array();
		}
	},
	
	drawGuiElements: function() {
		this.navigationBar = new Element('div', { 'class': 'calendar-navigation' });
		
		this.navigationBack = new Element('a', { 'html': this.getPreviousMonthName(), 'href': '#' });
		this.navigationBack.addEvent('click', this.goBack.bindWithEvent(this));
		
		this.navigationNow = new Element('span', { 'class': 'today' });
		
		this.navigationForward = new Element('a', { 'html': this.getNextMonthName(), 'href': '#' });
		this.navigationForward.addEvent('click', this.goForward.bindWithEvent(this));
		
		this.navigationBar.adopt(new Element('span', { 'class': 'back' }).adopt(this.navigationBack));
		this.navigationBar.adopt(this.navigationNow);
		this.navigationBar.adopt(new Element('span', { 'class': 'forward' }).adopt(this.navigationForward));
		this.baseElement.adopt(this.navigationBar);
		
		this.eventListElement = new Element('div', { 'class': 'event-list' });
		this.baseElement.adopt(this.eventListElement);
	},
	
	getPreviousMonthName: function() { return this.getMonthNameFor(this.getPreviousMonth()); },
	getNextMonthName: function() { return this.getMonthNameFor(this.getNextMonth()); },
	getCurrentMonthName: function() { return this.getMonthNameFor(this.getCurrentMonth(), '%B %Y'); },
	getPreviousMonth: function() {
		previousMonthIdentifier = this.getPreviousMonthIdentifier();
		return previousMonthIdentifier ? this.eventNodesByMonth[previousMonthIdentifier][0].eventDate : null;
	},
	
	getNextMonth: function() {
		nextMonthIdentifier = this.getNextMonthIdentifier();
		return nextMonthIdentifier ? this.eventNodesByMonth[nextMonthIdentifier][0].eventDate : null;
	},
	
	getPreviousMonthIdentifier: function() {
		var monthIdentifiers = this.getAllMonthIdentifiers();
		var monthIndex = monthIdentifiers.find(this.currentMonth);
		if (monthIndex > 0) {
			return monthIdentifiers[monthIndex - 1];
		}
	},
	
	getNextMonthIdentifier: function() {
		var monthIdentifiers = this.getAllMonthIdentifiers();
		var monthIndex = monthIdentifiers.find(this.currentMonth);
		if (monthIndex < (monthIdentifiers.length - 1)) {
			return monthIdentifiers[monthIndex + 1];
		}
	},
	
	getCurrentMonth: function() {
		return this.eventNodesByMonth[this.currentMonth][0].eventDate;
	},
	
	getMonthNameFor: function(month, format) {
		var formatString = format ? format : '%B';
		if (month) {
			return month.format(formatString);
		} else {
			return '';
		}
	},
	
	selectCurrentMonth: function() {
		var upcomingMonths = this.getAllMonthIdentifiers().filter(function(monthIdentifier) {
			return (parseInt(monthIdentifier) >= parseInt(new Date().format('%Y%m')));
		});
		if (upcomingMonths.length > 0) {
			this.currentMonth = upcomingMonths[0];
		} else {
			this.currentMonth = this.getAllMonthIdentifiers().getLast();
		}
	},
	
	getAllMonthIdentifiers: function() {
		var monthIdentifiers = [];
		for (var i in this.eventNodesByMonth) {
			monthIdentifiers.push(i);
		}
		return monthIdentifiers;
	},
	
	draw: function() {
		this.clear();
		this.redrawNavigation();
		this.redrawEventList();
	},
	
	clear: function() {
		this.getCurrentEvents().each(function(eventNode) {
			eventNode.dispose();
		});
		this.eventListElement.getElements('h2').destroy();
	},
	
	redrawNavigation: function() {
		this.navigationBack.set('html', this.getPreviousMonthName());
		this.navigationForward.set('html', this.getNextMonthName());
		this.navigationNow.set('html', this.getCurrentMonthName());
	},
	
	redrawEventList: function() {
		var events = this.getCurrentEvents();
		var pastEvents = events.filter(function(eventNode) {
			return eventNode.eventDate < new Date();
		});
		var upcomingEvents = events.filter(function(eventNode) {
			return eventNode.eventDate >= new Date();
		});
		
		if (pastEvents.length > 0 && upcomingEvents.length > 0) {
			this.drawEventsSeparator('upcoming');
		}
		this.drawEvents(upcomingEvents);
		if (pastEvents.length > 0 && upcomingEvents.length > 0) {
			this.drawEventsSeparator('past');
		}
		this.drawEvents(pastEvents);
	},
	
	getCurrentEvents: function() {
		return this.eventNodesByMonth[this.currentMonth];
	},
	
	drawEvents: function(eventNodes) {
		eventNodes.each(function(eventNode) {
			eventNode.insertInto(this.eventListElement);
		}, this);
	},
	
	drawEventsSeparator: function(string) {
		strings = {
			'sv': { 'upcoming': 'Kommande h&auml;ndelser', 'past': 'Tidigare h&auml;ndelser' }
		}
		this.eventListElement.adopt(new Element('h2', { 'class': 'current-past-separator', 'html': strings['sv'][string] }));
	},
	
	goBack: function() {
		this.clear();
		var previousMonthIdentifier = this.getPreviousMonthIdentifier();
		if (previousMonthIdentifier) {
			this.currentMonth = previousMonthIdentifier;
			this.draw();
		}
	},
	
	goForward: function() {
		this.clear();
		var nextMonthIdentifier = this.getNextMonthIdentifier();
		if (nextMonthIdentifier) {
			this.currentMonth = nextMonthIdentifier;
			this.draw();
		}
	}
});

EventNode = new Class({
	baseElement: null,
	eventDate: new Date(),
	
	initialize: function(nodeElement) {
		this.baseElement = nodeElement;
		this.parseEventDateFromClassName();
		this.dispose();
	},
	
	parseEventDateFromClassName: function() {
		var dateMatch = this.baseElement.get('class').match(/event-date-(\d{4}-\d{2}-\d{2})/);
		if (dateMatch) {
			this.eventDate = Date.parse(dateMatch[1]);
		} else {
			if (console != null) { console.log('Could not parse event date from class name: ' + this.baseElement.get('class')); }
		}
	},
	
	compareTo: function(otherNode) {
		if (this.eventDate == otherNode.eventDate) {
			return 0;
		} else {
			return this.eventDate < otherNode.eventDate ? -1 : 1;
		}
	},
	
	getMonthIdentifier: function() {
		return this.eventDate.format('%Y%m');
	},
	
	insertInto: function(element) {
		element.adopt(this.baseElement);
		this.baseElement.setStyles({ 'position': 'relative', 'top': '', 'left': '' });
	},
	
	dispose: function() {
		this.baseElement.setStyles({ 'position': 'absolute', 'top': '-9000px', 'left': '-9000px' });
	}
});

window.addEvent('domready', function() {
	$$('.event-calendar').each(function(calendarElement) {
		new EventCalendar(calendarElement);
	});
});

Array.prototype.find = function(value) {
	var foundElements = this.map(function(myValue, myKey) {
		return (myValue == value ? myKey : null);
	}).clean();
	
	return foundElements.length > 0 ? foundElements[0] : false;
}