//var calendars = months = focus = current = filter = null;

var calendars = {};

/**
 * Kalender-Objekt
 */
calendar = function() {
	this.cid		= this.id.split('-').pop();
	this.form		= this.down('form.calendar-months');
	this.focus		= parseInt(this.form.elements['focus'].value);
	this.current	= parseInt(this.form.elements['current'].value);
	this.filter		= parseInt(this.form.elements['filter'].value);
	this.container	= this.down('div.calendar-month-container');
	this.week		= this.down('table.calendar-week');
	
	// Ermitteln der aktuell dargestellten Monate
	this.months		= new Hash();
	var last = null, mtables = this.select('table.calendar-month'), mt = 0;
	for (mt = 0; mt < mtables.length; mt++) {
		var mtid = (new String(mtables[mt].id)).split('-')[1];
		mtables[mt]._prevMonth = last;
		mtables[mt]._nextMonth = null;
		if (last != null) {
			this.months.get(last)._nextMonth = mtid;
		}
		this.months.set(mtid, mtables[mt]);
		last = mtid;
	}
}

/**
 * Anzeigen eines neuen Monats
 * 
 * @param {Number} d			Richtung
 */
calendar.prototype.getMonth = function(d) {
	var f = this.months.get(this.focus);
	
	// Wenn der nächste Monat gezeigt werden soll und dieser bereits geladen wurde ...
	if ((d > 0) && f._nextMonth && this.months.get(f._nextMonth)._nextMonth && this.months.get(this.months.get(f._nextMonth)._nextMonth)._nextMonth) {
		this.focusMonth(d);
		
	// Ansonste: Wenn der vorherige Monat gezeigt werden soll und dieser bereits geladen wurde ...
	} else if ((d < 0) && f._prevMonth && this.months.get(f._prevMonth)._prevMonth && this.months.get(this.months.get(f._prevMonth)._prevMonth)._prevMonth) {
		this.focusMonth(d);
		
	// Ansonsten: Laden des neuen Monats
	} else {
		new Ajax.Request('/', {method: 'post', parameters: {
			'type': 701,
			'tx_twmeinldistribution_calendar[cid]': this.cid,
			'tx_twmeinldistribution_calendar[focus]': this.focus,
			'tx_twmeinldistribution_calendar[current]': this.current,
			'tx_twmeinldistribution_calendar[diff]': d * 3,
			'tx_twmeinldistribution_calendar[filter]': this.filter
		}, onComplete: this.receiveMonth.bind(this, d)});
	}
	
	return false;
}

/**
 * Empfangen von Monatsdaten
 * 
 * @param {Number} d				Richtung
 * @param {Object} response			Anfrageobjekt
 */
calendar.prototype.receiveMonth = function(d, response) {
	var tmp			= new Element('div');
	tmp.update(response.responseText);
	var month		= tmp.firstChild;
	var fMonth		= this.months.get(this.focus);
	
	if (fMonth && month && month.tagName && (month.tagName.toLowerCase() == 'table')) {
		var ts		= month.id.split('-').pop();
		if (d > 0) {
			this.container.insert({bottom: month});
			var prev = this.months.get(fMonth._nextMonth)._nextMonth;
			month._prevMonth = prev;
			month._nextMonth = null;
			this.months.set(ts, month);
			this.months.get(prev)._nextMonth = ts;
		} else {
			this.container.setStyle({'left': (parseInt(this.container.getStyle('left') || 0) - 190) + 'px'});
			this.container.insert({top: month});
			var next = this.months.get(fMonth._prevMonth)._prevMonth;
			month._prevMonth = null;
			month._nextMonth = next;
			this.months.set(ts, month);
			this.months.get(next)._prevMonth = ts;
		}
		this.focusMonth(d);
	}
}

/**
 * Fokusieren eines bestimmten Monats
 * 
 * @param {Number} d			Distanz / Richtung
 */
calendar.prototype.focusMonth = function(d) {
	var fMonth = this.months.get(this.focus);
	if (d > 0) {
		new Effect.MoveBy(this.container, 0, -190, {duration: 0.5,  transition: Effect.Transitions.sinoidal});
		this.focus = fMonth._nextMonth;
	} else {
		new Effect.MoveBy(this.container, 0, 190, {duration: 0.5,  transition: Effect.Transitions.sinoidal});
		this.focus = fMonth._prevMonth;
	}
}

/**
 * Abrufen von Wochenterminen
 * 
 * @param {Number} current			Zeitstempel der abzurufenden Woche
 * @param {Node} week				Zeile
 * @return {Boolean}				FALSE
 */
calendar.prototype.getDates = function(current, week) {
	this.current		= current || this.current;
	new Ajax.Request('/', {method: 'post', parameters: {
		'type': 702,
		'tx_twmeinldistribution_calendar[cid]': this.cid,
		'tx_twmeinldistribution_calendar[focus]': this.focus,
		'tx_twmeinldistribution_calendar[current]': this.current,
		'tx_twmeinldistribution_calendar[filter]': this.filter
	}, onComplete: this.receiveDates.bind(this, week || null)});
	this.select('tr.toweek').invoke('removeClassName', 'toweek');
	return false;
}

/**
 * Empfangen von Wochenterminen
 * 
 * @param {Node} week				Anzuzeigende Woche
 * @param {Object} response			AJAX-Antwort
 */
calendar.prototype.receiveDates = function(week, response) {
	this.week.replace(response.responseText);
	this.week		= this.down('table.calendar-week');
	if (week) {
		wclass		= week.className.split(' ').without('week', 'toweek')[0];
		this.select('tr.' + wclass).invoke('addClassName', 'toweek');
	}
}

// Initialisierung beim vollständigen Laden der Seite
document.observe("dom:loaded", function() {
	for (var ci = $$('div.tx-twmeinldistribution-calendar'), cl = ci.length, c = 0; c < cl; ++c) {
		Object.extend(ci[c], calendar.prototype);
		calendar.apply(ci[c]);
		calendars[ci[c].cid] = ci[c];
	}
});