if(!Function.prototype.bind) Function.prototype.bind = function() {
	var __method = this, args = arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments), object = args.shift();
	return function() {
		return __method.apply(object, args.concat(arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments)));
	}
};

/**
 * addEvent & removeEvent -- cross-browser event handling
 * Copyright (C) 2006  Dao Gottwald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact information:
 *   Dao Gottwald  <dao at design-noir.de>
 *   Herltestraße 12
 *   D-01307, Germany
 *
 * @version  1.1.6
 */

/*@cc_on if (window.addEventListener) { @*/
	function addEvent (o, type, fn) {
		o.addEventListener (type, fn, false);
	}
	function removeEvent (o, type, fn) {
		o.removeEventListener (type, fn, false);
	}
/*@cc_on } else if (window.attachEvent) {
	function addEvent (o, type, fn) {
		if (!o._events) o._events = {};
		var queue = o._events[type];
		if (!queue) {
			o._events[type] = [fn];
			if (!o._events._callback)
				o._events._callback = function (e) { Event._callListeners (e, o) };
			o.attachEvent ('on' + type, o._events._callback);
		} else if (Event._fnIndex (o, type, fn) == -1)
			queue[queue.length] = fn;
		else return;
		Event._mem[Event._mem.length] = [o, type, fn];
	}
	function removeEvent (o, type, fn) {
		var i = Event._fnIndex (o, type, fn);
		if (i < 0) return;
		var queue = o._events[type];
		if (queue.calling) {
			delete queue[i];
			if (queue.removeListeners)
				queue.removeListeners[queue.removeListeners.length] = i;
			else
				queue.removeListeners = [i];
		} else
			if (queue.length == 1)
				Event._detach (o, type);
			else
				queue.splice (i, 1);
	}
	var Event = {
		AT_TARGET : 2,
		BUBBLING_PHASE : 3,
		stopPropagation : function() { this.cancelBubble = true },
		preventDefault : function() { this.returnValue = false },
		_mem : [],
		_callListeners : function (e, o) {
			e.stopPropagation = Event.stopPropagation;
			e.preventDefault = Event.preventDefault;
			e.currentTarget = o;
			e.target = e.srcElement;
			e.eventPhase = e.currentTarget == e.target ? Event.AT_TARGET : Event.BUBBLING_PHASE;
			switch (e.type) {
				case 'mouseover':
					e.relatedTarget = e.fromElement;
					break;
				case 'mouseout':
					e.relatedTarget = e.toElement;
			}
			var queue = o._events[e.type];
			queue.calling = true;
			for (var i=0, l = queue.length; i < l; i++)
				if (queue[i])
					queue[i].call(o,e);
			queue.calling = null;
			if (!queue.removeListeners)
				return;
			if (queue.length == queue.removeListeners.length) {
				Event._detach (o, e.type);
				return;
			}
			queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b});
			var i = queue.removeListeners.length;
			while (i--)
				queue.splice (queue.removeListeners[i], 1);
			if (queue.length == 0)
				Event._detach (o, e.type);
			else
				queue.removeListeners = null;
		},
		_detach : function (o, type) {
			o.detachEvent ('on' + type, o._events._callback);
			delete o._events[type];
		},
		_fnIndex : function (o, type, fn) {
			var queue = o._events[type];
			if (queue)
				for (var i=0, l = queue.length; i < l; i++)
					if (queue[i] == fn)
						return i;
			return -1;
		},
		_cleanup : function() {
			for (var m, i=0; m = Event._mem[i]; i++)
				if (m[1] != 'unload' || m[2] == Event._cleanup)
					removeEvent (m[0], m[1], m[2]);
		}
	};
	addEvent (window, 'unload', Event._cleanup);
} @*/

/**
 * function whenDOMReady
 * Copyright (C) 2006  Dao Gottwald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact information:
 *   Dao Gottwald  <dao at design-noir.de>
 *   Herltestraße 12
 *   D-01307, Germany
 *
 * @version  1.1
 * @url      http://design-noir.de/webdev/JS/whenDOMReady/
 */

function whenDOMReady (fn) {
	/*@cc_on @if (@_win32) var f = arguments.callee; @end @*/
	var callback = function() {
		/*@if (@_win32) f.script.onreadystatechange = null; @end @*/
		removeEvent (window, 'load', callback);
		if (document.removeEventListener)
			document.removeEventListener('DOMContentLoaded', callback, false);
		fn();
	};
	if (document.addEventListener)
		document.addEventListener('DOMContentLoaded', callback, false);
	/*@if (@_win32) else if (!f.__ie_queue) {
		f.__ie_queue = [fn];
		document.write("<script id=__ie_scriptdummy defer src=javascript:void(0)><\/script>");
		f.script = document.getElementById("__ie_scriptdummy");
		f.script.onreadystatechange = function() {
			if (this.readyState == "complete") {
				removeEvent (window, 'load', callback);
				for (var i=0, cb; cb = f.__ie_queue[i]; i++)
					cb();
				f.script.onreadystatechange = null;
			}
		};
	} else
		f.__ie_queue[f.__ie_queue.length] = fn;
	@end @*/
	addEvent (window, 'load', callback);
}

function getElementsByClassName(parent, tagName, className){
	var haystack = parent.getElementsByTagName(tagName),
	collection = [],
	pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
	for (var i=0, ele; ele = haystack[i]; i++)
		if (pattern.test(ele.className))
			collection.push(ele);
	return collection;
}

/* Galerie */
whenDOMReady (function() {
	var galerien = getElementsByClassName(document, 'div', 'Galerie');
	if (galerien.length == 0)
		return;
	Galerie.prototype._load = Galerie.prototype.load;
	Galerie.prototype.load = function (url, prefetch) {
		if (this._load (url, prefetch)) {
			if (prefetch)
				this.getTitle (url);
			return true;
		}
		return false;
	};
	var set = {};
	Galerie.prototype._getTitle = Galerie.prototype.getTitle;
	Galerie.prototype.getTitle = function (url) {
		if (!set[url]) {
			set[url] = true;
			this.setTitle (url, this._getTitle(url).replace(/^\d+(?:$|_)/,'').replace(/_/g,' ').replace(/([a-z])([A-Z\d])/g,'$1 $2'));
			var queryUrl = url, galerie = this;
			if (queryUrl.indexOf ('/') == -1)
				queryUrl = window.location.pathname.replace (/[^\/]+$/, '') + queryUrl;
			request ('/ajax_pop.php', 'GET', 'pic='+escape(queryUrl), function (http) {
				var title = http.responseText.replace(/^\s+|\s+$/g,'');
				if (title && !/CAMERA|DIGITAL/.test(title))
					galerie.setTitle (url, title);
			});
		}
		return this._getTitle(url);
	};
	for (var i=0; i < galerien.length; i++)
		new Galerie (galerien[i]);
});

/* E-Mail-Adressen */
whenDOMReady (function() {
	var link, all = document.getElementsByTagName('a');
	for (var i=0, ele; ele = all[i]; i++)
		if (!ele.href && ele.firstChild && ele.firstChild.nodeValue)
			if (/\)$/.test(ele.firstChild.nodeValue)) {
				link = ele.firstChild.nodeValue.match(/^(.*) \((.*?) at (.*?)\)$/);
				if (link) {
					ele.firstChild.nodeValue = link[1];
					ele.href = 'mailto:' + link[2] + '@' + link[3];
				}
			} else {
				link = ele.firstChild.nodeValue.match(/^(.*) at (.*)$/);
				if (link)
					ele.href = 'mailto:' + (ele.firstChild.nodeValue = link[1] + '@' + link[2]);
			}
});

function toggle (layer) {
	document.getElementById(layer).style.display = document.getElementById(layer).style.display == 'block' ? 'none' : 'block';
}

function disable_form (ele) {
	for (var i=0; i < ele.length; i++)
		ele[i].disabled = true;
}

function enable_form (ele) {
	for (var i=0; i < ele.length; i++)
		ele[i].disabled = false;
}

var fela = {
	selectTarget : null ,
	Select : function (input) {
		input.blur();
		this.selectTarget = input;
		var s = document.getElementById('felaselect');
		if (s.childNodes.length == 0) {
			disable_form (input.form.elements);
			request ('ajax_felaselect.php', 'GET', '', function (http) {
					input.form.style.display = 'none';
					s.innerHTML = http.responseText;
					s.style.display = 'block';
					s.scrollIntoView(false);
					enable_form (input.form.elements);
				});
		} else {
			input.form.style.display = 'none';
			s.style.display = 'block';
			s.scrollIntoView(false);
		}
	} ,
	selectNarrowRequest : null ,
	SelectNarrow : function (form) {
		var laender = [], fela = this;
		for (var i=0; i < form.elements.land.length; i++)
			if (form.elements.land[i].checked)
				laender.push(form.elements.land[i].value);
		this.selectNarrowRequest = request ('ajax_felaliste.php', 'GET', {
				laender : laender.join(',') ,
				alter : form.elements.alter.value
				/*@cc_on , preventCache : (new Date).getTime() @*/
			}, function (http) {
				if (http == fela.selectNarrowRequest)
					document.getElementById('felaselect-liste').innerHTML = http.responseText;
			});
	} ,
	SelectConfirm : function (val) {
		if (this.selectTarget) {
			this.selectTarget.value = val;
			this.SelectAbort();
		} else
			window.location.href = '.?modul=fela-anmeldung&auswahl=' + escape (val);
	} ,
	SelectAbort : function () {
		document.getElementById('felaselect').style.display = 'none';
		var f = document.getElementById('felaanmeldung');
		f.style.display = 'block';
		f.scrollIntoView();
	} ,
	infoCache : {} ,
	Info : function (s) {
		var id = s.options[s.selectedIndex].value;
		if (this.infoCache[id])
			this.InfoDisplay(id);
		else
			request ('ajax_felainfo.php', 'GET', {id:id}, this.InfoDisplay.bind(this, id));
	} ,
	InfoDisplay : function (id, http) {
		var container = document.getElementById('felainfo');
		if (http)
			this.infoCache[id] = http.responseText;
		container.innerHTML = this.infoCache[id];
		document.getElementById('felainfo').scrollIntoView(false);
		new Galerie(container);
	} ,
	AnmeldenCheck : function (formular) {
		formular = formular.elements;
		var fehler;
		if (formular.name.value == '')
			fehler = { name		: 'Bitte den Namen angeben.' };
		else if (formular.vorname.value == '')
			fehler = { vorname	: 'Bitte den Vornamen angeben.' };
		else if (!/^\s*\d+\D+\d+\D+\d+\s*$/.test(formular.gebdatum.value))
			fehler = { gebdatum	: 'Bitte geben Sie das korrekte Geburtsdatum an.' };
		else if (!/\w+\b.*?\d/.test(formular.str_nr.value))
			fehler = { str_nr	: 'Bitte geben Sie die korrekte Straße und Hausnummer an.' };
		else if (!/^\s*\d+\b.*?\w+\s*$/.test(formular.plz_ort.value))
			fehler = { plz_ort	: 'Bitte die korrekte Postleitzahl und den Wohnort angeben.' };
		else if (!/^\s*\d+(?:\D*\d+)*\s*$/.test(formular.telefon.value))
			fehler = { telefon	: 'Bitte geben Sie Ihre korrekte Telefonnummer an.' };
		else if (formular.ziel.value == '')
			fehler = { ziel		: 'Bitte geben Sie den gewünschten Zielort und Termin an.' };
		else {
			disable_form (formular);
			return true;
		}
		for (var i in fehler) {
			formular[i].focus();
			alert(fehler[i]);
		}
		return false;
	} ,
	Anmelden : function (data, statusCode, statusMessage) {
		var formular = document.getElementById('felaanmeldung').elements;
		enable_form (formular);
		if (data == 'ok') {
			formular.vorname.value = '';
			formular.gebdatum.value = '';
			alert('Das Formular wurde abgeschickt. Wenn Sie eine gültige E-Mail-Adresse angegeben haben, bestätigen wir die Anmeldung noch einmal per Mail.\nEine Buchungsbestätigung kommt nach spätestens zwei Wochen mit der Post. Diese enthält eine verbindliche Anmeldung, ein Informationsblatt sowie einen Überweisungsträger für den Teilnehmerbeitrag. Außerdem liegt der Insolvenzversicherungsschein bei.\n\nWenn Sie möchten, können Sie sofort eine weitere Anmeldung tätigen.');
		} else
			alert(data);
	}
}


/* Belegungspläne */
whenDOMReady (function(){
	try {
		var kalender = document.getElementById('kalender').getElementsByTagName('table')[0];
	} catch(e) {
		return;
	}
	var tr = kalender.getElementsByTagName('tr');
	var monat_aktiv;
	var tag_aktiv;
	addEvent (kalender, 'mouseover',function(e){
		e.stopPropagation();
		var is_td = /^td$/i.test(e.target.nodeName);
		var is_th = !is_td && /^th$/i.test(e.target.nodeName);
		var is_thead = /^thead$/i.test(e.target.parentNode.parentNode.nodeName);
		if (!is_th && !(is_td && !is_thead))
			return;
		if (!is_thead && e.target.parentNode != tag_aktiv) {
			if (tag_aktiv)
				tag_aktiv.className = '';
			tag_aktiv = e.target.parentNode;
			tag_aktiv.className = 'hover';
		}
		var monat = e.target.parentNode.childNodes;
		for (var i=0; i < monat.length; i++) {
			if (monat[i] == e.target) {
				monat = i;
				break;
			}
		}
		if (monat == monat_aktiv || (!is_thead && is_th))
			return;
		for (var i=0; i < tr.length; i++) {
			tr[i].childNodes[monat].className += ' hover';
			if (monat_aktiv)
				tr[i].childNodes[monat_aktiv].className = tr[i].childNodes[monat_aktiv].className.replace(/(?:^| )hover/,'');
		}
		monat_aktiv = monat;
	});
});