/**
 * @author Matze
 */


var config = new Hash();

Object.extend(String.prototype, (function() {
	function escapeSpecialChars() {
		return this.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
	}
	
	return {
		escapeSpecialChars: escapeSpecialChars
	}
})());
$(document).observe("dom:loaded", function() {
	
	// wenn wir mit nem normalen Browser hier sind, initialisiere
	// die dynamischen Funktionalitaeten der Seite
	if (!isIE6OrLess()) {
		
		// Füge dem body Klasse hinzu, damit im CSS zwischen JS und
		// Non-JS unterschieden werden kann
		$(document.body).addClassName('dynd');
		
		// initialisiere globales Overlay
		window.overlay = new Overlay($('overlay'));

		$$('.presse .filter .pulldown').each(function(pulldown) {
			if (pulldown.hasClassName("datefilter")) {
				new Datefilterpulldown(pulldown);
			} else {
				new Filterpulldown(pulldown);
			}
		});
		
		// Initialisiere die JS-Pulldowns
		$$('.jspd').each(function(elm){
			new Pulldown(elm);
		});
		
		// Initialisiere den News-Pager
		if ($('feedcontent')) {
			new Feedpager($('feedcontent'), { showCount: 2 });
		}
		
		// Initialisiere die Initiativen-Links
		if (config.get("init-links")) {
			$(config.get("init-links")).each(function(elm) {
				new InitLink(elm);
			});
		}

		// Initialisiere den Chronik-Slider
		if ($('timelineslider')) {
			chronik = new ChronikSlider({});
		}
		
		// Initialisiere die Slideshows
		$$('.slideshow').each(function(elm){
			new Pager(elm, { showCount: 1 });
		});

		// Initialisiere die Auf-Zu-Schieber
		$$('.openhandler').each(function(elm){
			new Expandable(elm);
		});

		// Initialisiere die Slideshows
		$$('.picseriespager').each(function(elm){
			new Pager(elm, { showCount: 3 });
		});
		
		// Initialisiere die Accordions des Jahresberichts
		$$('.accordion').each(function(elm){
			accordion = new Accordion(elm);
		});

		// Initialisiere die Resizable Images des Jahresberichts
		$$('.resizableimg').each(function(elm){
			if (elm.down('a') && elm.down('a').down('img')) {
				var link = elm.down('a');
				var img = link.down('img');
				var smallsrc = img.src;
				var bigsrc = link.href;
				var captionWidth = false;
				
				if (elm.down('.imagecaption')) {
					captionWidth = elm.down('.imagecaption').getStyle('width');
				}
				
				link.observe("click", function(event){
					event.stop();
					
					if (img.src == smallsrc) {
						img.src = bigsrc;
						link.href = smallsrc;

						if (link.down('.plus') && link.down('.minus')) {
							link.down('.plus').setStyle('display:none;');
							link.down('.minus').setStyle('display:block;');
						}
						
						if (captionWidth) {
							elm.down('.imagecaption').setStyle('width:auto;');
							if (elm.down('.imagecaption').down('.caption-mini') && elm.down('.imagecaption').down('.caption-maxi')) {
								elm.down('.imagecaption').down('.caption-mini').setStyle('display:none;');
								elm.down('.imagecaption').down('.caption-maxi').setStyle('display:block;');
							}
						}
						
						link.title = link.title.replace(/Vergrößern/, "Verkleinern");
					} else {
						img.src = smallsrc;
						link.href = bigsrc;
						
						if (link.down('.plus') && link.down('.minus')) {
							link.down('.plus').setStyle('display:block;');
							link.down('.minus').setStyle('display:none;');
						}

						if (captionWidth) {
							elm.down('.imagecaption').setStyle('width:'+captionWidth+';');
							if (elm.down('.imagecaption').down('.caption-mini') && elm.down('.imagecaption').down('.caption-maxi')) {
								elm.down('.imagecaption').down('.caption-mini').setStyle('display:block;');
								elm.down('.imagecaption').down('.caption-maxi').setStyle('display:none;');
							}
						}
						
						link.title = link.title.replace(/Verkleinern/, "Vergrößern");
						
						// Ein Rendering-Bug im Firefox 3.6 erfordert diesen Trick mit sich aendernder Positionierung
						elm.setStyle('position:relative;');
						function bl(elm) {
							elm.setStyle('position:static;');
						}
						bl.delay(0.6, elm);						
					}
					
				});
			}
		});
		
		// initialisiere den Über-Uns-Link (Video)
		if ($('ueberuns')) {
			$('ueberuns').observe('click', function(event) {
				event.stop();
				
				if ($('ueberunscontent')) {
					$('ueberunscontent').setStyle("left:"+ ($(document.body).getWidth()/2 - $('ueberunscontent').getWidth()/2) +"px");
					overlay.show($('ueberunscontent'));
				}
			});
		}
		
		// initialisiere das Layer am Footer bei Klick auf Fingerstern
		if ($('layertrigger') && $('sternlayer')) {
			$('layertrigger').writeAttribute('aria-controls', $('sternlayer').identify());
			$('layertrigger').writeAttribute('aria-expanded', 'false');
			$('sternlayer').writeAttribute('aria-hidden', 'true');
			
			var onClose = function() {
				$('layertrigger').writeAttribute('aria-expanded', 'false');
				$('sternlayer').writeAttribute('aria-hidden', 'true');
				document.stopObserving("overlay:closed", onClose);
			}
			
			var onOpen = function() {
				$('layertrigger').writeAttribute('aria-expanded', 'true');
				$('sternlayer').writeAttribute('aria-hidden', 'false');
				document.stopObserving("overlay:opened", onOpen);
			}
			
			$('layertrigger').observe('click', function(event) {
				event.stop();
				if (overlay.show($('sternlayer'))) {
				}
				
				document.observe("overlay:opened", onOpen);
				document.observe("overlay:closed", onClose);
			});
			
			$('footerlogo').observe('mouseover', function(event) {
				if (!overlay.isOpen()) {
					Effect.Queues.get('footer').each(function(effect){
						effect.cancel();
					});
					
					new Effect.Parallel([new Effect.Morph($('layertrigger').down("img"), {
						style: "width:142px;",
						sync: true
					}), new Effect.Morph($('footerlogo'), {
						style: "top:-20px;",
						sync: true
					})], {
						duration: 0.5,
						delay: 0.1,
						queue: {
							scope: 'footer'
						}
					});
				}
			});
			
			$('footerlogo').observe('mouseout', function(event) {
				Effect.Queues.get('footer').each(function(effect) { effect.cancel(); });
				
				new Effect.Parallel([
						new Effect.Morph($('layertrigger').down("img"), {
							style: "width:75px;",
							sync: true
						}),
						new Effect.Morph($('footerlogo'), {
							style: "top:0px;",
							sync: true
						})
					], {
						duration:0.5,
						delay:0.1,
						queue: {
							scope:'footer'
						}
					}
				);
			});
		}
		
		// Versieh alle inputs, deren Inhalt ungueltig ist, mit dem entsprechenden ARIA-Attribut
		$$('label["for"]').each(function(label) {
			if (label.hasClassName('error')) {
				$(label.readAttribute("for")).writeAttribute('aria-invalid', 'true');
			}
		});
		
		// Initialisiere Kalendar-Funktionalitaeten.
		// Als Funktion gekapselt, damit sie sich bei Bedarf selber aufrufen kann.
		(function initializeCalendar() {
			if ($('calendar')) {
				$(document.body).insert("<div id='event-tooltip'></div>");
				var cal = $('calendar');
				var tt = $('event-tooltip');

				// Termin-Links durchgehen und mit Funktionalitaet belegen		
				cal.select('td a').each(function(link) {
					link.writeAttribute("title","");
					
					link.observe("mouseover", function(event) {
						event.stop();
						
						// wenn der content schon gecached wurde, nimm aus cache
						if (link.retrieve('content')) {
							tt.update(link.retrieve('content'));
							repositionTooltip();
						} else {
							new Ajax.Updater(tt, this.href.replace(/index.php|detail.php/, "ajax/termine.php"), {
								onSuccess: function(response) {
									// content cachen
									link.store("content", response.responseText);
									repositionTooltip();
								}
							});
						}

						Effect.Queues.get('endfade').invoke("cancel");
						
						tt.appear({
							duration:0.2,
							delay:0.3,
							queue: {
								scope: "startfade",
								limit:1
							}
						});
						
						// setzt den tooltip unterhalb des gehoverten termins
						function repositionTooltip() {
							tt.setStyle({
								left: (link.cumulativeOffset()[0] - 8 ) + "px",
								top: (link.cumulativeOffset()[1] + 26 ) + "px"
							});
							
							// sicher stellen, dass der tooltip nicht aus der seite ragt
							var dims = tt.getDimensions();
							var vport = document.viewport.getDimensions();
							while (parseInt(tt.getStyle("left"))+dims.width+2 > vport.width) {
								tt.setStyle({
									"left": (parseInt(tt.getStyle("left"))-2)+"px"
								});
							}
						}
						
					}.bindAsEventListener(link));
					
					// getriggert beim verlassen des Termin-Links
					link.observe("mouseout", function(event) {
						Effect.Queues.get('startfade').invoke("cancel");
						Effect.Queues.get('endfade').invoke("cancel");
						tt.fade({
							duration:0.2,
							delay: 0.2,
							queue: {
								scope: "endfade",
								limit:1
							}
						});
						
					}.bindAsEventListener(link));
				});
				
				// getriggert beim ueberfahren des tooltips
				tt.observe("mouseover", function(event) {
					Effect.Queues.get('endfade').invoke("cancel");
					tt.appear({
						duration:0.0,
						transition: Effect.Transitions.full,
						queue: {
							scope: "startfade",
							limit:1
						}
					});
				});
				
				// getriggert beim verlassen des tooltips
				tt.observe("mouseout", function(event) {
					Effect.Queues.get('endfade').invoke("cancel");
					tt.fade({
						duration:0.2,
						delay: 0.2,
						queue: {
							scope: "endfade",
							limit:1
						}
					});
				});
				
				
				// Monats-Paging per AJAX nachladen
				cal.select('.pager a').each(function(link) {
					link.observe("click", function(event) {
						event.stop();
						new Ajax.Updater(cal, this.href, {
							insertion: 'after',
							onComplete: function() {
								cal.select("a").invoke("stopObserving");
								cal.remove();
								initializeCalendar();
							}
						});
					}.bindAsEventListener(link));
				});
			}
		})();

		// dieses piece kuemmert sich um das Ausfahren der Passwort-Zeilen beim Bilderdownload
		if ($$('.passwordcontainer').length && $$('.passwordtrigger').length == $$('.passwordcontainer').length) {
			// geh durch die passwortcontainer auf der seite
			$$('.passwordcontainer').each(function(pwc){
				// bau dir die ID des passworttriggers aus der ID des pwasswortcontainers zusammen und cache das element
				var pwc = pwc;
				var pwt = $(pwc.identify().split('passwordcontainer')[0] + "passwordtrigger");
				
				if (pwc && pwt) {
					if (pwc.hasClassName("pwerror")) {
						pwt.hide();	
					} else {
						pwc.hide();
						
						pwt.observe("click", function(event){
							event.stop();
							pwc.appear();
							pwt.fade();
						});
					}
				}
			});
		}
		
		
		// ersetzen der Channel-Links im Presseverteiler durch Radio-Buttons
		var links = [$('info-email'), $('info-fax'), $('info-post')];
		links.each(function(link) {
			if (link) {
				var value = link.id.replace('info-', '');
				var selected = "";
				
				if ($F('hidden-channel') == value) {
					selected = "checked='checked'";
				}
				
				link.insert({
					before: '<input type="radio" name="channel" value="'+value.escapeSpecialChars()+'" id="'+link.id+'-input" '+selected+' /> <label class="channel" for="'+link.id+'-input">' + link.innerHTML + '</label>'
				});
				link.remove();
				
				var input = $(link.id+'-input');
				input.observe("change", function(event) {
					
					if ($('errorblock')) {
						$('errorblock').remove();
					}
					$$('label.error').each(function(label) {
						label.innerHTML = label.innerHTML.replace(/<strong.*?<\/strong>&nbsp;/, "");
						label.removeClassName("error");
					});
					$$('input[aria-invalid="true"]').invoke("writeAttribute", "aria-invalid", "false");
										
					if (input.value == "email") {
						$('strasse').writeAttribute("aria-required", "false");
						$$('label[for="strasse"]')[0].innerHTML = $$('label[for="strasse"]')[0].innerHTML.replace(" *", "");
						
						$('plz').writeAttribute("aria-required", "false");
						$$('label[for="plz"]')[0].innerHTML = $$('label[for="plz"]')[0].innerHTML.replace(" *", "");
						
						$('ort').writeAttribute("aria-required", "false");
						$$('label[for="ort"]')[0].innerHTML = $$('label[for="ort"]')[0].innerHTML.replace(" *", "");
						
						$('fax').writeAttribute("aria-required", "false");
						$$('label[for="fax"]')[0].innerHTML = $$('label[for="fax"]')[0].innerHTML.replace(" *", "");
					} else
					if (input.value == "fax") {
						$('strasse').writeAttribute('aria-required', "false");
						$$('label[for="strasse"]')[0].innerHTML = $$('label[for="strasse"]')[0].innerHTML.replace(" *", "");
						
						$('plz').writeAttribute("aria-required", "false");
						$$('label[for="plz"]')[0].innerHTML = $$('label[for="plz"]')[0].innerHTML.replace(" *", "");
						
						$('ort').writeAttribute("aria-required", "false");
						$$('label[for="ort"]')[0].innerHTML = $$('label[for="ort"]')[0].innerHTML.replace(" *", "");
						
						$('fax').writeAttribute("aria-required", "true");
						$$('label[for="fax"]')[0].innerHTML += " *";
					} else
					if (input.value == "post") {
						$('strasse').writeAttribute('aria-required', "true");
						$$('label[for="strasse"]')[0].innerHTML += " *";
						
						$('plz').writeAttribute("aria-required", "true");
						$$('label[for="plz"]')[0].innerHTML += " *";
						
						$('ort').writeAttribute("aria-required", "true");
						$$('label[for="ort"]')[0].innerHTML += " *";
						
						$('fax').writeAttribute("aria-required", "false");
						$$('label[for="fax"]')[0].innerHTML = $$('label[for="fax"]')[0].innerHTML.replace(" *", "");
					}
				});
			}
		})
		if ($('hidden-channel')) {
			$('hidden-channel').remove();
		}
		
		
	}
	// wenn es der IE6 ist, mach nur das noetigste
	else {
		
		// nur das erste Bild jeder Slideshow anzeigen
		$$('.slideshow').each(function(elm){
			elm.down("li").setStyle("display:block;");
		});
		
		// das Overlay so groß wie die Seite machen
		if ($('overlay')) {
			if ($('overlay').visible()) {
				$('overlay').setStyle({
					height: (Math.max($(document.viewport).getHeight(), $(document.body).getHeight()) - parseInt($('overlay').getStyle("top")))+"px"
				});				
			}
		}		
	}	
});


var Accordion = Class.create({
	initialize: function(elm) {
		var maxHeight = 0;
		var maxWidth = 0;
		this.element = elm;
		this.headlines = this.element.select('li > h2');
		this.contents = this.element.select('div.content').invoke("hide");
		this.element.select('h2').each(function(elm) {
			maxWidth = Math.max(elm.getWidth(), maxWidth);
		});
		this.entries = this.element.select('li').invoke("setStyle", "width:"+maxWidth+"px; ");
		this.active = null;
		this.animating = false;
		
		
		
		this.headlines.each(function(h2) {
			var index = this.entries.length - h2.up('li').nextSiblings().length - 1;
			
			h2.down("a").observe("click", function(event){
				event.stop();
				this.goToPage(index);
			}.bindAsEventListener(this));
			
		}.bind(this));
		
		this.goToPage(0);
	},
	goToPage: function(page) {
		if (this.active != page && !this.animating) {
			this.animating = true;
			var effects = [];
			var targetWidth;
			var fxParams = {
				sync: true
			};
			
			if (this.active != null) {
				targetWidth = this.headlines[page].show().getWidth();
				this.headlines[this.active].hide();
				effects.push(new Effect.Appear(this.headlines[this.active], fxParams));
				effects.push(new Effect.Fade(this.contents[this.active], fxParams));
				effects.push(new Effect.Morph(this.entries[this.active], {
					style: "width:"+targetWidth+"px",
					sync: true
				}));
			}
			
			targetWidth = this.contents[page].show().getWidth();
			this.contents[page].hide();
			effects.push(new Effect.Fade(this.headlines[page], fxParams));
			effects.push(new Effect.Appear(this.contents[page], fxParams));
			effects.push(new Effect.Morph(this.entries[page], {
				style: "width:"+targetWidth+"px",
				sync: true
			}));
			
			new Effect.Parallel(effects, {
				duration: 0.6,
				afterFinish: function() {
					this.active = page;
					this.animating = false;
				}.bindAsEventListener(this)
			});
			
		}
	}
});

var Overlay = Class.create({
	initialize: function(elm) {
		this.element = $(elm).hide();
		this.open = false;
		this.content = null;
		this.lastContent = null;
		
		this.element.observe('click', function(event) {
			event.stop();
			this.hide();
		}.bind(this));
	},
	show: function(content) {
		this.content = content;
		
		if (!this.open && this.content) {
			
			this.element.setStyle({
				height: (Math.max($(document.viewport).getHeight(), $(document.body).getHeight()) - $('topbar').getHeight())+"px"
			});
			
			this.element.appear({
				duration: 0.4,
				to:0.8,
				afterFinish: function() {
					this.open = true;
					document.fire("overlay:opened");
					
					if (this.content) {
						this.content.appear({duration:0.4});
					}
					
				}.bind(this)
			});
			
			this.lastContent = this.content;
			return true;
		}
		else if(this.content && this.content != this.lastContent) {
			this.lastContent.fade({duration:0.4});
			this.content.appear({duration:0.4});
			this.lastContent = this.content;
			return true;
		}
		else {
			return false;
		}
	},
	hide: function() {
		if (isIE6OrLess()) {
			return true;
		}
		
		if (this.open) {
			if (this.content) {
				this.content.fade({duration:0.4});
				this.content = null;
			}
			
			this.element.fade({
				duration: 0.4,
				afterFinish: function() {
					this.open = false;
					document.fire("overlay:closed");
				}.bind(this)
			});
			return true;
		}
		else {
			return false;
		}		
	},
	isOpen: function() {
		return this.open;
	}
});



var InitLink = Class.create({
	// als elm erwartet wird ein objekt mit den folgenden eigenschaften:
	/*
	{
		id: 'init-biene',
		url: "snippets/get.php?key=biene",
		activeImg: "img/content/logo-biene-active.png",
		inactiveImg: "img/content/logo-biene-inactive.png"
	}
	*/
	initialize: function(elm, root) {
		
		lg("start initializing InitLink");
		
		// setze defaultwerte
		root = root || $(document.body);			// höchste Initalisierungsebene (im Normalfall <body>)
		this.content = null;						// cache-variable für ajax-inhalt
		this.elements = root.select("."+elm.id);	// elements beinhaltet alle relevanten Links

		// wenn elements leer ist, brich die ganze Initialiserung ab
		if (!this.elements[0]) {
			lg("no link in DOM, aborted initializing InitLink");
			return;
		} 

		this.url = elm.url;
		this.activeImg = elm.activeImg;
		this.inactiveImg = elm.inactiveImg;
		
		// hol dir das derzeitige Bild, das den Link in der oberen Box repräsentiert
		this.domimg = $$("."+elm.id).find(function(link){
			if (link.down("img") && link.down("img").hasClassName('stickylink'))
				return link.down("img");
		});
		if (this.domimg) {
			this.domimg = this.domimg.down("img");
			this.defaultImg = this.domimg.src;
		}
		
		// in welchem Container befinden wir uns? muss später animiert werden
		this.expandable = this.elements[0].up(".elementcontainer").down(".subelement").identify();
		
		// setze EventListener auf alle meine Links
		this.elements.each(function(link){
			link.observe("click", this.click.bindAsEventListener(this));
		}.bind(this));
		
		// listen auf diese Events
		document.observe("initlinks:activate", this.setActive.bind(this));
		document.observe("initlinks:deactivate", this.setInactive.bind(this));
		document.observe("initlinks:reset", this.setDefault.bind(this));
		
		this.boundLoadAjax = this.loadAjax.bind(this);
		lg("finished initializing InitLink");
	},
	click: function(event) {
		event.stop();
		
		
		// aktiviere dieses Linkbild (if) bzw. setze alle Linkbilder zurück (else) 
		if (this.domimg) {
			// deaktiviere alle Links
			document.fire("initlinks:deactivate");
			lg("active set");
			this.domimg.src = this.activeImg;
		} else {
			document.fire("initlinks:reset");
		}
		
		// sollte der container offen sein, blende den
		// Inhalt aus und lade danach den neuen Inhalt
		if ($(this.expandable).hasClassName("active")) {
			new Effect.Morph($("init-contentcontainer"), {
				duration: 0.4,
				style: "opacity:0",
				afterFinish: this.boundLoadAjax,
				queue: {
					scope: $("init-contentcontainer").identify(),
					limit: 1
				}
			});
		}
		// sonst lade einfach direkt den neuen Inhalt
		else {
			this.loadAjax();
		}
	},
	loadAjax: function() {
		lg("loadAjax()");
		
		// nimm den content aus dem cache, wenn er schon vorhanden sein sollte
		if (this.content) {
			lg("Content taken from cache.");
			$('init-contentcontainer').update(this.content);
			this.initializeDynamicContent();
			this.reopenContainer();
		}
		// lade den content per ajax, da er noch nicht im cache war
		else {
			lg("Content not in cache.");
			new Ajax.Request(this.url, {
				onSuccess: function(transport) {
					lg("Ajax success.");
					this.content = transport.responseText;
					$('init-contentcontainer').update(this.content);
					this.initializeDynamicContent();
					this.reopenContainer();
				}.bind(this)
			});
		}
	},
	initializeDynamicContent: function() {
		// initialisiere die Links in dem neuen Inhalt
		// (wenn keine vorhanden sein sollten, kümmert sich die Klasse automatisch darum)
		if (config.get("init-links")) {
			$(config.get("init-links")).each(function(elm) {
				new InitLink(elm, $('init-contentcontainer'));
			});
		}
					
		// Initialisiere die Slideshows (falls welche drin sein sollten)
		$('init-contentcontainer').select('.slideshow').each(function(elm){
			new Pager(elm, { showCount: 1 });
		});
		
		document.fire("expandable-"+this.expandable+":resize");
	},
	reopenContainer: function() {
		lg("reopenContainer()");

		// wenn der container offen ist, lass den inhalt einfaden
		if ($(this.expandable).hasClassName("active")) {
			this.containerFadeIn();
		}
		// ist der container geschlossen gewesen, sende das signal, ihn zu öffnen
		else {
			document.fire("expandable-"+this.expandable+":open");
			lg("fired: expandable-"+this.expandable+":open");
		}
	},
	containerFadeIn: function() {
		// definiere gebundene Funktion
		this.boundFunc = function() {
			new Effect.Morph($("init-contentcontainer"), {
				duration: 0.4,
				style: "opacity:1",
				queue: {
					scope: $("init-contentcontainer").identify(),
					limit: 1
				}
			});
			document.stopObserving("expandable-"+this.expandable+":finishedResizing", this.boundFunc);
		}.bind(this);
		
		// observe ob der container fertig ist mit resizen, ruf dann die gebundene funktion auf (s.o.)
		document.observe("expandable-"+this.expandable+":finishedResizing", this.boundFunc);
		// gib dem container den befehl, zu resizen
		document.fire("expandable-"+this.expandable+":resize");

	},
	// die folgenden drei Funktionen setzen den Aktiv-Zustand des Link-Bildes (sofern vorhanden)
	setInactive: function() {
		lg("setInactive");
		if (this.domimg){
			this.domimg.src = this.inactiveImg;
		} 
	},
	setActive: function() {
		lg("setActive");
		if (this.domimg){
			this.domimg.src = this.activeImg;
		}
	},
	setDefault: function() {
		lg("setDefault");
		if (this.domimg){
			this.domimg.src = this.defaultImg;
		}
	}
});

var Pulldown = Class.create({
	initialize: function(elm) {
		lg("start initializing Pulldown");
		this.element = elm;
		this.trigger = this.element.down(".pdhandler");
		this.content = this.element.down('.pdflesh');
		this.closeBtn = this.element.down(".pdclose") || null;
		this.opened = false;
		
		this.setLinkTabIndex(-1);

		var bordertop = 0;
		var borderbottom = 0;
		// Mindestbreite auf die Breite des Trigger setzen
		if (this.content.getWidth() < this.trigger.getWidth()) {
			this.content.setStyle({
				width: (this.trigger.getWidth() - parseInt(this.trigger.getStyle("borderLeftWidth")) - parseInt(this.trigger.getStyle("borderRightWidth")) ) + "px"
			});
		}

		this.trigger.writeAttribute('aria-controls', this.content.identify());
		this.trigger.writeAttribute('aria-expanded', 'false');

		this.boundBodyClicked = this.bodyClicked.bindAsEventListener(this);

		this.trigger.observe("click", this.click.bindAsEventListener(this));

		// wenn ein CloseButton angegeben wurde (optional), dann mit Schließmechanik versehen.
		if (this.closeBtn) {
			this.closeBtn.observe("click", this.hide.bindAsEventListener(this));
		}
		
		// wenn schon mit Klasse "active" versehen, dann soll das Pulldown initial geöffnet sein
		if (this.element.hasClassName("active")) {
			this.show();
		}
		lg("end initializing Pulldown");
		
		return this;
	},
	setLinkTabIndex: function(tabindex){
		var links = this.content.select('a');
		links.each(function(link){
			link.writeAttribute('tabindex', tabindex);
		});
	},
	click: function(event) {
		event.stop();
		if (this.opened) {
			this.hide();
		} else {
			this.show();
		}
	},
	show: function() {
		if (!this.opened) {
			this.content.setStyle({position:"relative",left:"0px"});
			this.content.writeAttribute('aria-hidden', 'false');
			this.trigger.writeAttribute('aria-expanded', 'true');
			this.setLinkTabIndex(0);
			this.opened = true;
			this.element.addClassName("active");

			// this checks if tooltip would be outside of the document and moves it to the left until it fits in
			var dims = this.content.getDimensions();
			var vport = document.viewport.getDimensions();
			
			while (parseInt(this.content.viewportOffset().left)+dims.width+2 > vport.width) {
				this.content.setStyle({
					left: (parseInt(this.content.getStyle("left"))-2)+"px"
				});
			}

			var that = this;
			var temp = function() {
				document.observe("mousedown", that.boundBodyClicked);
			}.delay(0.2);
			
			
		}
	},
	hide: function() {
		if (this.opened) {
			this.content.setStyle({position:"absolute",left:"-10000px"});
			this.content.writeAttribute('aria-hidden', 'true');
			this.trigger.writeAttribute('aria-expanded', 'false');
			this.setLinkTabIndex(-1);
			this.opened = false;
			this.element.removeClassName("active");

			document.stopObserving("click", this.boundBodyClicked);
		}
	},
	bodyClicked: function(event) {
		var sOffset = document.viewport.getScrollOffsets();
		var pos = {
			x: event.pointer().x + sOffset[0],
			y: event.pointer().y + sOffset[1]
		};
		if (!isInElement(pos, this.content)) {
			this.hide();
			document.stopObserving("mousedown", this.boundBodyClicked)
		}
	}
});

var Filterpulldown =  Class.create(Pulldown, {
	initialize: function($super, ancestor) {
		this.ancestor = ancestor;
		this.textLength = 15;
			
		this.createFakePulldown();
		
		$super($(this.ancestor.identify()+'-mirror'));
		
		
		this.content.select("a.option").each(function(link){
			link.observe("click", this.itemChanged.bindAsEventListener(this, link))
		}.bind(this));
	},
	createFakePulldown: function() {
		var activeText = this.ancestor.select("option").find(function(option) {
			return option.selected
		}).innerHTML;
		
		var flesh = '<div class="pdflesh noprint" aria-hidden="true"><div class="pdtop"></div><ul class="pdcontent">';
		this.ancestor.select('option').each(function(option) {
			flesh += '<li><a href="#" class="option">' + option.innerHTML + '</a></li>';
		});
		flesh += '</ul><div class="pdbottom"></div></div>';
		
		this.ancestor.insert({
			before: '<div class="pulldown" id="'+this.ancestor.identify()+'-mirror"><a href="#" class="pdhandler" title="'+activeText+'">'+activeText.truncate(this.textLength, "...")+'</a>'+flesh+'</div>'
		});
		
		this.ancestor.hide();	
	},
	itemChanged: function(event, link) {
		event.stop();
		if (!this.ancestor.options[link.up("li").previousSiblings().length].selected) {
			this.ancestor.options[link.up("li").previousSiblings().length].selected = true;
			this.trigger.update(link.innerHTML.truncate(this.textLength, "..."));
			this.trigger.writeAttribute("title", link.innerHTML);
			if (this.ancestor.up("form")) {
				this.ancestor.up("form").submit();
			}
		}
		this.hide();
	},
	show: function($super) {
		$super();
		
		if (this.opened) {
			this.content.setStyle("position:absolute; left:inherit;")
		}
	}
});

var Datefilterpulldown =  Class.create(Filterpulldown, {
	initialize: function($super, ancestor){
		this.defaultDate = "TT.MM.JJJJ";
		
		$super(ancestor);
		
		this.content.down(".btn-apply").observe("click", this.applyDate.bindAsEventListener(this));
	},
	createFakePulldown: function($super) {
		$super();
		
		this.ancestor.insert(this.fakeElm = new Element("option", {value:"", selected:"selected"}));
		
		var fromdate = this.defaultDate;
		var todate =this.defaultDate;
		
		if ($('fromdate')) {
			fromdate = $F('fromdate') || this.defaultDate;
			$('fromdate').remove();
		}
		if ($('todate')) {
			todate = $F('todate') || this.defaultDate;
			$('todate').remove();
		}
		
		if (fromdate != this.defaultDate && todate != this.defaultDate) {
			$(this.ancestor.identify() + '-mirror').down(".pdhandler").update("Zeitrahmen").title = "Zeitrahmen";
			this.ancestor.down("option[value='default']").value = "";
			this.fakeElm.selected = true;
		}
				
		var datefilter = '<label for="'+this.ancestor.identify()+'-l1'+'">von</label><input type="text" name="fromdate" value="'+fromdate.escapeSpecialChars() +'" maxlength="10" id="'+this.ancestor.identify()+'-l1'+'" />';
		datefilter += '<label for="'+this.ancestor.identify()+'-l2'+'">bis</label><input type="text" name="todate" value="'+todate.escapeSpecialChars()+'" maxlength="10" id="'+this.ancestor.identify()+'-l2'+'" />';
		datefilter += '<a class="btn-apply" href="#">Anwenden</a>';
		
		$(this.ancestor.identify()+'-mirror').down("ul").insert({
			bottom: "<li class='datefilter'>" + datefilter + "</li>"
		});
		
		$$('#' + this.ancestor.identify()+'-l1, #' + this.ancestor.identify()+'-l2').each(function(input) {
			input.observe("focus", function(event) {
				if (input.value == this.defaultDate) {
					input.value= "";
				}
			}.bindAsEventListener(this));
			
			input.observe("blur", function(event) {
				if (input.value == "") {
					input.value= this.defaultDate;
				}
			}.bindAsEventListener(this));
		}.bind(this));
	},
	applyDate: function(event) {
		event.stop();
		
		if ($F(this.ancestor.identify()+'-l2').match(/\d{2}\.\d{2}\.\d{4}$/) && $F(this.ancestor.identify()+'-l1').match(/\d{2}\.\d{2}\.\d{4}$/)) {
			this.trigger.update("Zeitrahmen");
			this.content.select('p.error').invoke("remove");
			
			this.fakeElm.selected = true;
			
			if (this.ancestor.up("form")) {
				this.ancestor.up("form").submit();
			}

			this.hide();
		} else {
			if (this.content.down('li.datefilter p.error')) {
				this.content.down('li.datefilter p.error').highlight({duration:2, endcolor:"#c9e4fa"});
			} else {
				this.content.down('li.datefilter').insert({
					top: "<p class='error'>Bitte Zeitangaben &uuml;berpr&uuml;fen</p>"
				});
			}
		}
	},
	itemChanged: function($super, event, link) {
		this.content.select('p.error').invoke("remove");
		$(this.ancestor.identify()+'-l2').value = this.defaultDate;
		$(this.ancestor.identify()+'-l1').value = this.defaultDate;
		
		$super(event, link);
	}
});

var Pager =  Class.create({
	initialize: function(elm, params) {
		lg("start initializing Pager");
		
		params = params || {};
		this.element = elm;
		this.entries = this.element.select("li");
		this.next = this.element.down('.next');
		this.prev = this.element.down('.prev');
		this.showCount = params.showCount || 2;
		this.pageCount = this.entries.eachSlice(this.showCount).length;
		
		this.activePage = 1;
		if (this.element.down("li.active")) {
			this.activePage = Math.ceil((this.element.down("li.active").previousSiblings().length+1) / this.showCount);
		}
		this.pagenum = this.element.down('.pagenum');
		
		this.createPaging();
		
		// initialen Inhalt anzeigen
		this.showPage(this.activePage);
		
		this.next.observe("click", this.showNext.bindAsEventListener(this));
		this.prev.observe("click", this.showPrev.bindAsEventListener(this));
		
		lg("end initializing Pager");
	},
	createPaging: function() {
		lg("createPaging");
		// wenn mehr als eine Seite vorhanden ist, müssen die Statuspunkte generiert und
		// mit der Klickmechanik versehen werden
		if (this.pageCount > 1) {
			var dot;
			for (i = 0; i < this.pageCount; i++) {
				this.pagenum.insert(dot = new Element("div", {
					className: "dot"
				}));
				dot.observe("click", this.showPage.bind(this, i + 1));
			}
			var width = ((this.pageCount) * this.pagenum.down('.dot').getWidth()) || this.pageCount * 9;
			this.pagenum.setStyle({
				width: width + "px"
			});
		} else {
			this.next.hide();
			this.prev.hide();
		}		
	},
	showNext: function(event) {
		event.stop();
		lg("showNext");
		
		if (this.activePage < this.pageCount) {
			this.showPage(this.activePage+1);
		} else {
			this.showPage(1);
		}
		
	},
	showPrev: function(event) {
		event.stop();
		lg("showPrev");
		
		if (this.activePage > 1) {
			this.showPage(this.activePage-1);
		} else {
			this.showPage(this.pageCount);
		}
	},
	showPage: function(page) {
		lg("showPage("+page+")");
		this.activePage = page;		
		
		// verstecke nicht benötigte und zeige geforderte Seiten
		this.entries.eachSlice(this.showCount).each(function(group, index) {
			if (page != index+1 ) {
				group.invoke("hide");
			} else {
				group.invoke("show");
			}
		});
		
		// CSS noch anpassen an neuen internen Status
		if (this.pagenum.down('.active'))
			this.pagenum.down('.active').removeClassName("active");
		this.pagenum.select('div')[page-1].addClassName("active");
	}
});

// erbt das meiste von Pager, nur initialize() und showPage() muessen ueberschrieben werden
var Feedpager =  Class.create(Pager, {
	initialize: function($super, elm, params) {
		//$super(elm, params);
		lg("start initializing Feedpager");
		
		params = params || {};
		this.element = elm;
		this.entries = this.element.select("li");
		this.next = this.element.down('.next');
		this.prev = this.element.down('.prev');
		this.activePage = 1;

		this.next.observe("click", this.showNext.bindAsEventListener(this));
		this.prev.observe("click", this.showPrev.bindAsEventListener(this));
		
		// groups speichert die anzahl der jeweiligen posts pro seite,
		// also z.B. [1, 2, 1, 1, 2]
		this.groups = [];
		var classPrefix = "news-1of";
		var elmcount;
		for (var i = 0; i < this.entries.length;) {
			
			// hol dir die Klassennamen des Listenelements und die Position
			// unserer Spezialklasse, die wir in classPrefix zwischengespeichert haben
			var classes = this.entries[i].classNames().toString();
			var pos = this.entries[i].classNames().toString().indexOf(classPrefix);
			
			// wenn wir einen validen Klassennamen haben, zieh dir die Anzahl
			// der Elemente in der Gruppe aus dem Namen
			if (pos > -1) {
				elmcount = classes.substr(pos + classPrefix.length, 1);
				elmcount = parseInt(elmcount);
			}
			// ist der Klassenname versehentlicherweise nicht korrekt,
			// setze den elmcount-Wert auf ganz hoch, was zu einem eleganten
			// Abbruch fuehrt
			else {
				elmcount = this.entries.length+1;
			}
			
			// falls versehentlich dem letzten element der newsliste die falsche
			// klasse (z.B. 1of2) mitgegeben wurde, obwohl es alleine ist			
			if (i+elmcount >= this.entries.length ) {
				elmcount = this.entries.length - i;
			}
			
			// fuege die anzahl der posts auf dieser seite den groups hinzu
			this.groups.push(elmcount);
			this.entries[i].addClassName("nodivider");
			// erhoehe die schleifenvariable um den wert der posts, um erst bei den
			// elementen der naechsten seite weiterzumachen und keine doppelt zu zaehlen
			i += elmcount;
			
		}
		
		this.pageCount = this.groups.length;
		this.pagenum = this.element.down('.pagenum');
		
		this.createPaging();

		// initialen Inhalt anzeigen
		this.showPage(this.activePage);

		
		lg("end initializing Feedpager");
		
	},
	showPage: function(page) {
		lg("showPage("+page+")");
		this.activePage = page;
		
		// CSS der Paging-Punkte anpassen an neuen internen Status
		if (this.pagenum.down('.active'))
			this.pagenum.down('.active').removeClassName("active");
		this.pagenum.select('div')[this.activePage-1].addClassName("active");
		
		// verstecke nicht benötigte und zeige geforderte Seiten
		var current = 0;
		for (var i = 0; i < this.groups.length; i++) {
			if (i == this.activePage-1) {
				for (var j = 0; j < this.groups[i]; j++) {
					if (this.entries.length >= current + j) {
						this.entries[current + j].show();
//						lg("show Feedentry:" + (current + j));
					}
				}
			} else {
				for (var j = 0; j < this.groups[i]; j++) {
					if (this.entries.length >= current + j) {
						this.entries[current + j].hide();
//						lg("hide Feedentry:" + (current + j));
					}
				}
			}
			current += this.groups[i];
		}
		
		lg("end showPage");
	}
});


var Expandable = Class.create({
	initialize: function(elm, params) {
		lg("start initialize Expandable");
		this.handler = elm;
		this.element = this.handler.up(".subelement");
		this.content = this.element.down(".shadowcontent");
		this.active = false;
		this.height = this.content.getHeight();
		this.element.identify();  // versieht das Element mit einer ID, falls noch keine vorhanden ist
		
		if (this.element.up('.elementcontainer') && this.element.up('.elementcontainer').down('.secondaryopenhandler')) {
			this.secondaryHandler = this.element.up('.elementcontainer').down('.secondaryopenhandler');
		}
		
		// content initial verstecken, falls nicht eingeblendet
		if (this.content.readAttribute('aria-hidden')=='false') {
			// eingeblendet
			this.content.setStyle({
				overflow:"hidden"
			});
			this.element.addClassName("active");
			this.active = true;
			this.handler.writeAttribute('aria-expanded', 'true');
		} else {
			// ausgeblendet
			this.content.setStyle({
				height:"0px",
				overflow:"hidden",
				display:"none"
			});
			this.element.removeClassName("active");
			this.handler.writeAttribute('aria-expanded', 'false');
		}
		
		this.handler.writeAttribute('aria-controls', this.element.identify());
		
		// öffnen-funktionalität
		this.handler.observe("click", this.click.bindAsEventListener(this));
		if (this.secondaryHandler) {
			this.secondaryHandler.observe("click", this.clickSecondary.bindAsEventListener(this));
		}
		
		// listener definieren
		document.observe("expandable-"+this.element.identify()+":toggle", this.click.bindAsEventListener(this));
		document.observe("expandable-"+this.element.identify()+":open", this.open.bind(this));
		document.observe("expandable-"+this.element.identify()+":close", this.close.bind(this));
		document.observe("expandable-all:close", this.close.bind(this));
		document.observe("expandable-"+this.element.identify()+":resize", this.resize.bind(this));
		
		lg("finished initializing Expandable");		
	},	
	updateTitles: function(){
		var from 	= this.active ? 'ausblenden' : 'anzeigen';
		var to 		= this.active ? 'anzeigen' : 'ausblenden';		
		
		this.handler.writeAttribute('title', this.handler.readAttribute('title').split(from).join(to));
		this.handler.update(this.handler.innerHTML.split(from).join(to));
		if (this.secondaryHandler) {
			this.secondaryHandler.writeAttribute('title', this.secondaryHandler.readAttribute('title').split(from).join(to));
		}		
	},
	click: function(event) {
		lg("click");
		event.stop();
		
		// halte alle effekte an
		Effect.Queues.get(this.element.identify()).each(function(effect) { effect.cancel(); });
		
		if (this.active) {
			this.updateTitles();
			this.close();
		}
		else {
			this.updateTitles();
			this.open();
		}
	},
	clickSecondary: function(event) {
		lg("clickSecondary");
		event.stop();
		
		// halte alle effekte an
		Effect.Queues.get(this.element.identify()).each(function(effect) { effect.cancel(); });
		
		if (!this.active) {
			this.updateTitles();
			this.open();
		}
	},	
	open: function() {
		if (!this.active) {
			lg("start opening");
			
			document.fire("expandable-all:close");
			
			// vorbereiten der neuen höhe
			this.content.setStyle({
				display:"block",
				height:"auto"
			});
			// hol die neue hoehe
			this.height = this.content.getHeight();
			
			this.content.setStyle({
				height:"0px"
			});

			// versteck den hilfs-oeeffner
			if (this.secondaryHandler) {
				this.secondaryHandler.hide();
			}
			
			// morphe zu neuer Höhe
			this.element.addClassName("active");
			this.element.up(".elementcontainer").addClassName("active");
			this.active = true;
			new Effect.Morph(this.content, {
				duration: 1,
				style: "height:" + this.height + "px; padding-bottom:4px;",
				afterFinish: this.endOpen.bind(this),
				queue: {
					scope: this.element.identify(),
					limit: 1
				}
			});
		}	
	},
	close: function() {
		if (this.active) {
			lg("start closing");
			this.element.removeClassName("active");
			this.element.up(".elementcontainer").removeClassName("active");
			this.active = false;
			new Effect.Morph(this.content, {
				duration: 1,
				style: "height:0px; padding-bottom:0px;",
				afterFinish: this.endClose.bind(this),
				queue: {
					scope: this.element.identify(),
					limit: 1
				}
			});
		}
	},
	// funktion, die von höhe 1 zu höhe 2 resized
	resize: function() {
		// cache alte höhe
		var tempHeight = this.content.getHeight();
		// hole neue höhe
		this.content.setStyle({
			height:"auto"
		});
		var newHeight = this.content.getHeight();
		// setze wieder auf alte höhe
		this.content.setStyle({
			height:tempHeight+"px"
		});
		
		// morphe zu neuer höhe und feure den dazugehörigen event ab
		new Effect.Morph(this.content, {
			duration: 0.4,
			style: "height:"+newHeight+"px;",
			afterFinish: function() {
				document.fire("expandable-"+this.element.identify()+":finishedResizing");
			}.bind(this),
			queue: {
				scope: this.element.identify(),
				limit: 1
			}
		});
	},
	endOpen: function() {
		lg("end opening");
		document.fire("expandable-"+this.element.identify()+":finishedOpening");
		this.content.writeAttribute('aria-hidden', 'false');
		this.handler.writeAttribute('aria-expanded', 'true');
	},
	endClose: function() {
		lg("end closing");
		// zeig den hilfs-oeeffner
		if (this.secondaryHandler) {
			this.secondaryHandler.show();
		}
		this.content.setStyle({
			display:"none"
		});
		document.fire("expandable-"+this.element.identify()+":finishedClosing");
		this.content.writeAttribute('aria-hidden', 'true');
		this.handler.writeAttribute('aria-expanded', 'false');
	}
});



/*
 * Suchfunktionalitaeten
 */

function setSearchLocation(params) {
	if ($('searchcontainer') && $('searchid') && $('searchlocation') && params && params.caption && params.value) {
		$('searchid').update(params.caption);
		$('searchlocation').writeAttribute({value: params.value});
//		$('searchcontainer').removeClassName('active');
		$$('#searchcontainer #scope a').invoke('removeClassName', 'active');
		$(params.element).addClassName('active');
		toggleSearchContainer();
		return true;
	} else {
		return false;
	}
}

boundSearchFunction = function(event){
    if (!isInElement(Event.pointer(event), $('searchcontainer'))) {
        toggleSearchContainer();
    }
}

function toggleSearchContainer () {
	if ($('searchcontainer').hasClassName('active')) {
		document.stopObserving("click", boundSearchFunction);
		$('searchid').writeAttribute("aria-expanded", "false");
		$('scope').writeAttribute("aria-hidden", "true");
	} else {
		document.observe("click", boundSearchFunction);
		$('searchid').writeAttribute("aria-expanded", "true");
		$('scope').writeAttribute("aria-hidden", "false");
	}
	$('searchcontainer').toggleClassName('active');
}



var ChronikSlider = Class.create({
	initialize: function(params){
		this.build();
		this.observePaging();
	},
	build: function() {
		// falls es schon einen slider gibt, eventListener und slider selbst loeschen
		if (this.slider && this.slider.options && this.slider.options.onChange) {
			this.slider.options.onChange = null;
			this.slider = null;
		}
		
		// hol dir die anzahl der jahre
		this.valueElms = $('timelineslider').up().down(".timeline").childElements();

		// berechne den pixel-abstand zwischen den jahren und positioniere die jahre
		var width = Math.floor(($('timelineslider').getWidth() - this.valueElms[0].getWidth()) / (this.valueElms.length-1));
		this.widthVals = [];
		this.valueElms.each(function(li, index) {
			li.setStyle({
				left:Math.floor(index*width - li.getWidth()/2) + "px"
			});
			this.widthVals.push(Math.floor(index*width - li.getWidth()/2));
		}.bind(this));

		// wenn es noch kein aktuelles jahr gibt, hol es dir aus der timeline-beschriftung
		if (!this.currentYear)
			this.currentYear = parseInt(this.valueElms[0].up().down(".active").down().innerHTML);
		
		// wenn es noch kein naechstes jahr gibt, hol es dir aus der timeline-beschriftung.
		// wenn dort keins mehr ist (weil wir im letzten jahr des aktuellen timeframe sind),
		// dann hol es dir aus der URL des von PHP generierten "Next"-Link
		if (!this.nextYear) {
			if (this.valueElms[0].up().down(".active").nextSiblings().length) {
				this.nextYear = parseInt(this.valueElms[0].up().down(".active").nextSiblings()[0].down().innerHTML);
			} else {
				this.nextYear = $('timelinepaging').down('.next').href.toQueryParams()['year'] || 0;
			}
		}
		
		// wenn es noch kein vorheriges jahr gibt, hol es dir aus der timeline-beschriftung.
		// wenn dort keins mehr ist (weil wir im ersten jahr des aktuellen timeframe sind),
		// dann hol es dir aus der URL des von PHP generierten "Prev"-Link
		if (!this.prevYear) {
			if (this.valueElms[0].up().down(".active").previousSiblings().length) {
				this.prevYear = parseInt(this.valueElms[0].up().down(".active").previousSiblings()[0].down().innerHTML);
			} else {
				this.prevYear = $('timelinepaging').down('.prev').href.toQueryParams()['year'] || 0;
			}
		}

		// wenn es noch keinen aktuellen timeframe gibt, hol ihn dir aus der zeitabschnitt-liste
		// anhand der klasse des aktiven timeframes
		if (typeof(this.timeframe) == "undefined") {
			this.timeframe = $('timeframeselector').down('a.active').up('li').previousSiblings().length;
		}
		
		// erstelle den slider
		this.slider = new Control.Slider('timelinehandler', 'timelineslider', {
			minimum: 0,
			maximum: $('timelineslider').getWidth(),
			range: $R(0, this.widthVals[this.widthVals.length-1] + parseInt($('timelinehandler').getStyle("margin-left"))),
			onChange: this.onChange.bindAsEventListener(this),
			values: this.widthVals,
			sliderValue: this.getPositionFromYear(this.currentYear)
		});
		
	},
	observePaging: function() {
		// belege den next-link mit einem eventListener
		if ($('timelinepaging').down('.next')) {
			$('timelinepaging').down('.next').observe("click", this.goToNextYear.bindAsEventListener(this));
		}
		
		// belege den prev-link mit einem eventListener
		if ($('timelinepaging').down('.prev')) {
			$('timelinepaging').down('.prev').observe("click", this.goToPrevYear.bindAsEventListener(this));
		}
		
		// belege die timeframe-links mit einem eventListener
		$('timeframeselector').select('a').each(function(link, index){
			link.observe("click", this.goToTimeframe.bindAsEventListener(this, index));
		}.bind(this));
		
		this.managePagingVisibility();
	},
	// managePagingVisibility sorgt dafuer, dass immer nur die next/previous-Links
	// zu sehen sind, die auch Sinn machen und kuemmert sich um die korrekte
	// auszeichnung des aktiven timeframes
	managePagingVisibility: function() {
		if (this.nextYear) {
			$('timelinepaging').down('.next').show();
			$('timelinepaging').down('.next').update("Weiter zu " + this.nextYear);
		} else {
			$('timelinepaging').down('.next').hide();
		}
		
		if (this.prevYear) {
			$('timelinepaging').down('.prev').show();
			$('timelinepaging').down('.prev').update("Zur&uuml;ck zu " + this.prevYear);
		} else {
			$('timelinepaging').down('.prev').hide();
		}
		
		$('timeframeselector').down("a.active").removeClassName("active");
		$('timeframeselector').select("li")[this.timeframe].down("a").addClassName("active");
	},
	onChange: function(value) {
		// wenn jemand am slider rumzieht, hol dir das neue jahr
		if (this.valueElms[this.getIndexFromPosition(value)].down()) {
			var year = this.valueElms[this.getIndexFromPosition(value)].down().innerHTML;
			this.goToYear(year);
		}
	},
	goToYear: function(year) {
		// AJAX-request, wenn das jahr gewechselt wird (ueber slider oder prev/next-links)
		new Ajax.Request('?', {
			parameters: {
				year: year,
				lastYear: this.currentYear,
				ajax: true
			},
			onSuccess: this.ajaxSuccess.bindAsEventListener(this)
		});
	},
	goToTimeframe: function(event, timeframe) {
		// AJAX-request, wenn der timeframe gewechselt wird
		// (ueber klicks auf die timeframe-links)
		event.stop();
		this.timeframe = timeframe;
		
		new Ajax.Request('?', {
			parameters: {
				timeframe: this.timeframe,
				lastYear: this.currentYear,
				ajax: true
			},
			onSuccess: this.ajaxSuccess.bindAsEventListener(this)
		});
	},
	goToNextYear: function(event) {
		event.stop();
		this.goToYear(this.nextYear);
	},
	goToPrevYear: function(event) {
		event.stop();
		this.goToYear(this.prevYear);
	},
	getIndexFromPosition: function(pixels) {
		var vindex; 
		this.widthVals.each(function(val, index) {
			if (val == pixels) {
				vindex = index;
			}
		});	
		return vindex;
	},
	getIndexFromYear: function(year) {
		var vindex;
		this.valueElms.each(function(elm, index) {
			if (elm.down().innerHTML == year) {
				vindex = index;
			}
		});		
		return vindex;
	},
	getPositionFromYear: function(year) {
		var vposition;
		this.widthVals.each(function(position, index) {
			if (this.valueElms[index].down().innerHTML == year) {
				vposition = position;
			}
		}.bind(this));
		return vposition;
	},
	ajaxSuccess: function(request) {
		// wird ausgefuehrt, wenn das mit dem AJAX-request geklappt hat
		
		// setze die neue umgebung
		this.timeframe = request.responseJSON.timeframe;
		this.currentYear = request.responseJSON.currentYear;
		this.nextYear = request.responseJSON.nextYear;
		this.prevYear = request.responseJSON.prevYear;
		
		if (request.responseJSON.type == "simple") {
			// wenn es ein simpler request war (kein timeframe-wechsel)
			$('yeardetails').update(request.responseJSON.response);
			
			this.valueElms[this.getIndexFromYear(this.currentYear)].up().down(".active").removeClassName("active");
			this.valueElms[this.getIndexFromYear(this.currentYear)].addClassName("active");
			$('timelinehandler').setStyle({ left: this.getPositionFromYear(this.currentYear) + "px" });
			
		} else if (request.responseJSON.type == "complex") {
			// wenn es ein komplexer request war (neues jahr hat anderen timeframe als vorheriges)
			$('timelinecontainer').update(request.responseJSON.timelinecontent);
			this.build();
		}
		
		// aktualisiere noch die anzeige der prev/next/timeframe-links
		this.managePagingVisibility();
	}
});



/**
 * Prueft, ob point innerhalb der Grenzen von elm liegt. Gibt true oder false zurueck.
 * @param {x:integer, y:integer} point
 * @param {Object} elm
 * @return boolean true, wenn point innerhalb von elm liegt, sonst false
 */
function isInElement(point, elm) {
	var x = point.x;
	var y = point.y;
	var elm = elm;

	 var dOffset = document.viewport.getScrollOffsets();

	if ((x > elm.viewportOffset()[0]+elm.cumulativeScrollOffset()[0]+dOffset[0]+elm.getWidth() || x < elm.viewportOffset()[0]+elm.cumulativeScrollOffset()[0]+dOffset[0])
	|| (y > elm.viewportOffset()[1]+elm.cumulativeScrollOffset()[1]+dOffset[1]+elm.getHeight() || y < elm.viewportOffset()[1]+elm.cumulativeScrollOffset()[1]+dOffset[1])) {
		return false;
	} else {
		return true;
	}
}


/**
 * Prueft, ob der verwendete Browser Internet Explorer 6 oder aelter ist.
 * @return boolean true, wenn User Agent IE6 oder aelter ist, sonst false
 */
function isIE6OrLess(){
	var agt=navigator.userAgent.toLowerCase();
	var is_major = parseInt(navigator.appVersion);
	var is_minor = parseFloat(navigator.appVersion);
	var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	return (is_ie && (is_major == 4) && (agt.search(/msie [56]\./)!=-1) );
}


/**
 * Stellt Debug-Messages für Firefox, IE8, Opera, Safari, Chrome (Konsole) und IE<8 (alert) zur Verfügung.
 * @param string text
 * @return void
 */
function lg(text) {
	if (false)
	{
		if (typeof(opera) != "undefined" && opera != null) {
			opera.postError(text);
			return;
		}
		else 
			if (typeof(console) != "undefined" && console != null) {
				console.log(text);
				return;
			}
//			else {
//				alert(text);
//			}
	}
}
