/**
 *	Reisplanner Calendar
 *	-------------------------------
 */

function Calendar(node) {
    
	this.container = node;
	this.table = node.getElementsByTagName('table')[0];
	this.body = node.getElementsByTagName('tbody')[0];                            
	this.currentCell = null;
	this.mode = '';
	
	var selects = node.getElementsByTagName("select");
	
	EventListener.addEvent(this.table, 'mouseup', this.scope(this.getDate));
	EventListener.addEvent(this.table, 'mousemove', this.scope(this.hoverDate));
	EventListener.addEvents(selects, 'change', this.scope(this.upDate));

	var now = new Date();
	this.now = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    this.chooseDate(selects[0]);
}

Calendar.prototype = {
    upDate:function(e) {     
		var target = EventListener.getTarget(e, 'select');
		if(target) {
			this.chooseDate(target);
		}
	},

	chooseDate:function(target) {
		var selects = target.parentNode.getElementsByTagName("select");
		var year = parseInt(selects[1].value, 10);
        var month = parseInt(selects[0].value, 10) -1;       
	    this.setDate(new Date(year, month, 1));
	},

	setSelects:function() {
		function selectValue(select, value) {
        for (var i=0; i<select.options.length; i++) {
				if(select.options[i].value == value) {
					select.selectedIndex = i;
					break;
				}
			}
		}

		var date = this.selectedDate;
		var selects = this.container.getElementsByTagName("select");
		selectValue(selects[1], date.getFullYear());
		selectValue(selects[0], date.getMonth()+1);
	},

	copySelects:function(year, month) {
		var selects = this.container.getElementsByTagName("select");
        this.copyOptions(month, selects[0]);
		this.copyOptions(year, selects[1]);
	},

	copyOptions:function(origin, target) {
		for (var i=0; i<origin.options.length; i++) {
			var option = origin.options[i];
			try {				
				target.options[i] = new Option(option.text, option.value);
			} catch (e) { }
		}
	},

	setDate:function(date) {
		this.currentDate = date.getTime()? date : new Date();
		this.currentMonth = this.currentDate.getMonth();
		this.currentYear = this.currentDate.getFullYear();
        this.selectedDate = new Date(this.currentDate.getTime());
        this.setSelects();
		this.createTable();
	},

	setMode:function(mode) {
		this.mode = mode;
	},
	
	setAction:function(action) {
		this.action = action;
	},

	hoverDate:function(e) {
		var target = EventListener.getTarget(e);
		var day = target.innerHTML;
		if(this.currentCell && (!target || target != this.currentCell))
			ClassName.remove(this.currentCell, 'current');
		
		if(/td/i.test(target.nodeName) && /^[0-9]+$/.test(day) && !/past/.test(target.className)) {
			this.currentCell = target
			ClassName.add(target, 'current');
		}
	},

	getDate:function(e){
		var target = EventListener.getTarget(e);    
		var day = target.innerHTML;         
		
		if(/td/i.test(target.nodeName) && /^[0-9]+$/.test(day) && !/past/.test(target.className)) {
			try {
				this.action(new Date(this.currentYear, this.currentMonth, day));
			} catch (actionException) {
				alert('Error. No calendar action specified.');
			}
		}
	},

	createTable:function() {
		var date = this.currentDate;
		
		date.setDate(1);		
		var day, row, cell, endmode = false;
		var month = date.getMonth();
		var first = date.getDay();
		var days = first + 42;
		var body = document.createElement('tbody');
		
		this.currentCell = null;
		this.table.removeChild(this.body);
		this.body = this.table.appendChild(body);

		var selectFuture = /future/i.test(this.mode);
		var selectPast   = /past/i.test(this.mode);

		for(var i=0; i<days; i++) {
			day = i+1 - first;
			date.setMonth(month);
			
			if(day < 1) day = ' ';
			else {
				date.setDate(day);
				if(date.getMonth() != month) {
					day = ' ', endmode = true;
				}
			}

			if(i%7 == 0) {
				if(endmode) break;
				row = this.body.insertRow(i/7);
			}	
			
			cell = row.insertCell(i%7)
			cell.innerHTML = day;
			
			if((selectFuture && date < this.now) || (selectPast && date > this.now)) {
				cell.className = 'past';
			}

			if(day > 1 && Math.abs(this.selectedDate - date) < 86400000) {
				cell.className += ' today';
			}

			if(i%7 == 0 || i%7 == 6) {
				cell.className += ' weekend';
			}
		}
	},

	scope:function(method) {
		var scope = this;
		return function() {
			return method.apply(scope, arguments);
		}
	}
}