/**
 * @name bweb.js
 * @authors Inga Pohl, Christian Hansen, Robert Katzki
 * @copyright Copyright 2011 Bildungsweb Media GmbH
 *
 */


/*
 * Bildungsweb Namespace
 *
 *
 * Copyright Bildungsweb Media GmbH
 *
 */
this.bw = {};

bw = {
	//
	//  Globale Initialisierungen des Namespace.
	//
	init: function () {
		// Wenn man nach unten scrollt, dann soll ein Link eingeblendet werden, über den man wieder nach oben kommt
		$(window).scroll(function() {
			bw.zeug.nachObenLinkAkt();
		});

		// Der nach-oben-Link soll die Seite nach ganz oben scrollen.
		$('#nachOben').click(function() {
			$(window.opera?'html':'html, body').animate({scrollTop: '0'}, '500');
			return false;
		});
	}, // Ende bw.init

	//
	// zuletzt besuchte Seiten
	//
	besuchteSeiten: {
		init: function() {
		var that = $('#zuletztAngesehen');
		$.ajax({
				url: '/typo3conf/ext/bweb_fe/Resources/Public/Ajax/besuchteSeiten.php',
				data: 'portal=' + that.data('portal') + '&bereich=' + that.data('bereich') +
						'&profiltyp=' + that.data('profiltyp') + '&pid=' + that.data('pid'),
				type: 'POST',
				cache: false,
				error: function(XHR, status) {
					$(that).prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
				},
				success: function(data) {
					if(data != '') {
						$('#zuletztAngesehen').html(data);
						$('#besuchteSeitenTabs').show();
					}
				}
			})
		}
	}, // Ende bw.besuchteSeiten

	//
	//  Die Aktionen, die mit den Bildern zusammenhängen
	//
	bilder: {
		initProfilAnbieter: function() {
			// Im Anbieterprofil gibt es eine kleine Vorschaubilderliste, die bei einem Klick zur Bildergalerie fahren soll und das geklickte Bild öffnen soll.
			$('.profil .links .vorschauBilder img').unbind('click').click(function () {
				$(window.opera?'html':'html, body').delay(30).animate({scrollTop: $('#bildergalerie').offset().top},500);
				$('#' + $(this).data('name') ).trigger('click');
			});
		}, // Ende bw.bilder.initProfilAnbieter
		initProfilProgramm: function() {
			// Die Bilder im Premiumprofil
			if ($('.profilBild').length) {
				if ($('.profilBild img').data('bilder').length > 1) {
					$('.profilBild .blaettern').removeClass('versteckt').unbind('click').click(function() {
						var bild = $(this).parent().find('img');
						var daten = bild.data();
						var anz = daten.bilder.length - 1; // Beginnt mit 0 zu zählen

						var neu = 0;
						// Wenn es nach vorne gehen soll
						if ( $(this).hasClass('vor') ) {
							neu = daten.aktuell + 1;
						// Sonst geht es zurück
						} else {
							neu = daten.aktuell - 1;
						}
						// Wenn das Ende oder der Anfang über- bzw. unterschritten werden, dann am anderen Ende weitermachen
						if (neu > anz) neu = 0;
						if (neu < 0) neu = anz;

						// Das aktuelle Bild setzen
						// Höhe setzen, damit beim laden die Box nicht kleiner wird
						bild.parent().css('height', bild.parent().height());
						// Ladebild an den Container anhängen
						bw.zeug.ladeBild(bild.parent());
						// Bild ausfaden
						bild.fadeOut(200, function() {
							// Nummer setzen, damit wir wissen, welches Bild angezeigt wird
							bild.data('aktuell', neu);
							// Src setzen und dann fertig-geladen-event zuweisen
							$(this).attr('src', daten.url + daten.bilder[neu].name).one('load', function(){
								// Wenn kein link gesetzt wurde, soll auch kein <a>Tag gesetzt werden
								if(daten.bilder[neu].link === undefined) {
									$('.text', bild.parent()).html('<b>'+daten.bilder[neu].text+'</b>');
								} else {
									$('.text', bild.parent()).html('<a href="'+daten.bilder[neu].link+'"><b>'+daten.bilder[neu].text+'</b></a>');
								}

								// Einblenden, Höhe automatisch setzen (neues Bild) und Ladebild entfernen
								$(this).fadeIn(200);
								$(this).parent().css('height', 'auto');
								bw.zeug.ladeBildEntfernen(bild.parent());
							// IE braucht noch Extrabehandlung
							}).each(function() {
								if (this.complete && ($.browser.opera || $.browser.msie)) {
									$(this).trigger("load");
								}
							});
						});
						return false;
					});
				}
			}
		}, // Ende bw.bilder.initProfilProgramm
		initVorschauKlick: function(selektor) {
			$(selektor + ' img').unbind('click').click(function () {
				var bildSrc = $(this).data('bild');
				var bild = $(selektor).parent().find('.bild img');

				// Nur laden, wenn ein neues Bild geklickt wurde.
				if (bild.attr('src') !== bildSrc) {
					// Ladebild an den Container anhängen
					bw.zeug.ladeBild(bild.parent());
					// Bild ausfaden
					bild.fadeOut(200, function() {
						// Src setzen und dann fertig-geladen-event zuweisen
						$(this).attr('src', bildSrc).bind('load', function(){
							if(this.complete || (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) == 6)) {
								// Einblenden und Ladebild entfernen
								bild.fadeIn(200);
								bw.zeug.ladeBildEntfernen(bild.parent());
							}
						});
					});
				}
			});
			// Doppeltes Klicken, weil der IE sonst rumzickt
			$(selektor + ' img:first').trigger('click').trigger('click');
		}, // Ende bw.bilder.initVorschauKlick
		initVorschauScroll: function(selektor) {
			// Die Breite vom Div und von den Bildern wird benötigt
			// vB = voschauBilder
			var vB = $(selektor);
			var vBInhalt = vB.children('.vorschauBilderInhalt');

			// Bilder sind inklusive Border und Margin 65px breit minus 5 px für das letzte Margin
			var vBInhaltBreite = (vBInhalt.find('img').length * 65) - 5;
			vBInhalt.css('width', vBInhaltBreite + 'px');

			// Etwas Platz, das Scrollen fängt nicht direkt an der Kante an
			var extra = 20;
			// Die Breite des Containers
			var vBBreite = vB.width();
			// Ganz nach Links scrollen für den Anfang
			vBInhalt.css('margin-left', 0);

			var scrollbar = false;

			if (vBBreite < vBInhaltBreite) {
				scrollbar = true;
				vB.addClass('scrollNachRechts');
			}

			// Mausbewegung über den VorschauBildern
			if (scrollbar === true) {
				vB.unbind('mousemove').bind('mousemove', function(e) {
					var breite = vBBreite - extra;
					var left = ((e.pageX - vBInhalt.offset().left) * ((vBInhaltBreite-breite)) / breite) - extra;

					if (left > 0) {
						vB.addClass('scrollNachLinks');
					} else {
						left = 0;
						vB.removeClass('scrollNachLinks');
					}

					if (left < (vBInhaltBreite - breite)) {
						vB.addClass('scrollNachRechts');
					} else {
						left = vBInhaltBreite - breite;
						vB.removeClass('scrollNachRechts');
					}

					vBInhalt.css('margin-left', -left);
				});
			}
		}  // Ende bw.bilder.initVorschauScroll
	}, // Ende bw.bilder


	//
	//  DropdownBoxen (kleine Boxen, die auf und zu sliden)
	//
	dropdownBox: {
		init: function () {
			$('.dropdownBoxLink').unbind('click').click(function () {
				var box = $( $(this).attr('href') );
				if ( box.is(':visible') ) {
					box.slideUp();
				} else {
					box.slideDown();

					// Box verstecken, wenn sich die Maus wegbewegt
					box.hover(
						// Mouseover-Event deletes timer
						function() {
							try{
								clearTimeout(hover_intent);
							} catch(e) { }
							// Give class for hover
							box.addClass('hover');
						},
						// Mouseout-Event sets Timer and removes hover-class
						function() {
							hover_intent = setTimeout( function() {
								if (!box.hasClass('hover')) {box.slideUp();}
							} , 1000 );
							box.removeClass('hover');
						}
					);

					// Bei Klick auf den Hintergrund wird die Box versteckt
					$(document).click(function(event) {
						if(!($(event.target).parents().andSelf().is('.dropdownBox'))){
							box.slideUp();
							$(document).unbind('click');
						}
					});
				}
				return false;
			});
		} // Ende bw.dropdownBox.init
	},


	//
	//  Infos Anfordern
	//
	infosAnfordern: {
		init: function () {
			bw.infosAnfordern.initHighlightInBox();

			// Bei Aufruf wird per ajax SeitenId in session gespeichert
			$('a.infosAnfordernButton').unbind('click').click(function(){
				$.ajax({
					data: 'type=789458&ajax=true&'+$(this).parents('form').serialize(),
					type: 'POST',
					dataType: 'json',
					cache: false,
					beforeSend: function(element) {
						return function() {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen(document);
							// Blende die Ladegrafiken ein
							bw.zeug.ladeBild( element.parents('.anfordernFormular') );
						};
					}( $(this) ),
					// Fehlerbehandlung: gib das geklickte Element mit
					error: function(element) {
						return function(XHR, status, error) {
							element.after('<div class="error">Fehler! ('+status+', '+error+')</div>');
						};
					}( $(this) ),
					// Erfolg!: gib das geklickte Element mit
					success: function(element) {
						return function (data) {
							// Enthält den Inhalt des Formulars
							element.parents('.formular').html(data.html);

							// Wenn das versenden geklappt hat und wir auf einer Profilseite sind, dann wird das Overlay ausgeblendet
							if (data.status === 'ok') {
								bw.zeug.entferneHighlight();
							}
						};
					}( $(this) ),
					complete: function() {
						// Ladebilder wieder entfernen
						bw.zeug.ladeBildEntfernen(document);
					}
				});
				return false;
			});
		}, // Ende bw.infosAnfordern.init
		initHighlight: function () {
			$('.infosAnfordernHighlight').unbind('click').click(function () {
				bw.zeug.setzeHighlight( 'div.inhaltSchmal div.anfordernFormular' );

				$('.overlay').unbind('click').click(function () {
					bw.zeug.entferneHighlight(  );
				});

				return false;
			});
		}, // Ende bw.infosAnfordern.initHighlight
		initHighlightInBox: function () {
			// Wenn im Profil in der Seite auf die Box geklickt wird, dann soll die Box hervorgehoben werden.
			// Genauso wie beim Klick auf den Highlightbutton.
			$(document).click(function(event) {
				// Wenn irgendwo in der Box geklickt wird.
				if ($(event.target).parents().andSelf().is('.inhaltSchmal .anfordernFormular')) {
					bw.zeug.setzeHighlight( 'div.inhaltSchmal div.anfordernFormular' );
					$(document).unbind('click');
					$('.overlay').unbind('click').click(function () {
						bw.zeug.entferneHighlight(  );
						bw.infosAnfordern.initHighlightInBox();
					});
				}
			});
		} // Ende bw.infosAnfordern.initHighlightInBox
	}, // Ende bw.infosAnfordern


	//
	//  Die Karte (Google Maps)
	//
	karte: {
		initGross: function (karteID) {
			// Initialisiert eine ausführlichere Karte mit einem MarkerArray
			var karteData = $('#'+karteID).data();
			var lat = karteData.lat;
			var lng = karteData.lng || karteData.lon;
			var latLng = new google.maps.LatLng(lat, lng); // Koordinaten kommen aus dem Kartenelement
			var zoom = parseInt(karteData.zoom, 10) || 7;
			var markerIcon = 'http://bwebstatic.de/pix/design/markerNormal.png';
			var markerIconPremium = 'http://bwebstatic.de/pix/design/markerPremium.png';
			var optionen = {
				backgroundColor: '#fff',
				zoom: zoom,
				center: latLng,
				mapTypeId: google.maps.MapTypeId.ROADMAP,
				mapTypeControl: false,
				scrollwheel: false,
				streetViewControl: false
			};
			// Karte erzeugen
			var karte = new google.maps.Map(document.getElementById(karteID), optionen);

			var markers = karteData.markers;
			if (markers.length !== 0) {
				var bounds = new google.maps.LatLngBounds(); // Um die Karte um die Marker herum zu zentrieren
				var mArr = []; // Array mit den Markern

				// Custom, style-bare InfoBox, die sich wie die InfoWindows verhalten
				var ibOptionen = {
					alignBottom: true, // Untere linke Ecke wird an dem Marker ausgerichtet
					pixelOffset: new google.maps.Size(-28, -48), // Abstand von der Markerposition
					closeBoxMargin: "-9px -9px 0 0",
					infoBoxClearance: new google.maps.Size(80, 55) // Abstand der Infobox zum Rand der Karte nach dem AutoPan
				};
				var ib = new InfoBox(ibOptionen);

				// Jeder Marker bekommt einen eigenen InfoWindow-Inhalt
				jQuery.each(markers, function(i, wert) {
					var lat = wert.latitude || wert.lat;
					var lng = wert.longitude || wert.lon;

					// Nur zur Karte hinzufügen, wenn überhaupt ein Wert gesetzt ist.
					if (lat !== undefined && lng !== undefined) {
						var latlng = new google.maps.LatLng(lat, lng);
						var marker = new google.maps.Marker({position: latlng});
						if (wert.premium) {
							marker.setIcon(markerIconPremium);
						} else {
							marker.setIcon(markerIcon);
						}
						google.maps.event.addListener(marker, 'click', function(e) {
							ib.setOptions({alignBottom: true});
							if (wert.premium == '1' || wert.premium === true) {
								ib.setOptions({closeBoxURL: "http://bwebstatic.de/pix/design/schliessen-orange.png"});
							} else {
								ib.setOptions({closeBoxURL: "http://bwebstatic.de/pix/design/schliessen-blau.png"});
							}
							var ladeInhalt = Mustache.to_html($('#'+karteID+'InfoboxTemplate').html(), wert);
							ib.setContent(ladeInhalt);
							ib.open(karte, marker);

							var pid = wert.auid || wert.pid;
							var bereich = wert.kategorie || wert.bereich;

							// Ajax-Request abschicken
							$.ajax({
								// Url ist die Suchseite + die jVal, welche kodiert wurden, damit man sie nicht einfach erkennt
								url:location.pathname,
								data:"eID=infoboxInhalt&aname="+pid+'&kategorie='+bereich,
								dataType: "json",
								type: "POST",
								cache: false,
								// complete: function() {
								//	// Ladebilder wieder entfernen
								//	$("div.infoBox div.ladeBild").remove();
								// },
								error: function(XHR, status) {
									ib.setContent('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
								},
								success: function(d){
									ib.setContent(d.inhalt);
									bw.merkzettel.initMerken();
								}
							});

						});
						mArr.push(marker);
						bounds.extend(latlng);
					}
				});

				// Style der MarkerClusterer. Ist mehrmals da, weil man verschiedene Größen für die unterschiedlichen Anzahl an Markern in einem Cluster definieren kann.
				var styles = [[{
						url: 'http://bwebstatic.de/pix/design/markerCluster.png',
						height: 44,
						width: 44,
						opt_textColor: '#ffffff'
					}, {
						url: 'http://bwebstatic.de/pix/design/markerCluster.png',
						height: 44,
						width: 44,
						opt_textColor: '#ffffff'
					}, {
						url: 'http://bwebstatic.de/pix/design/markerCluster.png',
						height: 44,
						width: 44,
						opt_textColor: '#ffffff'
					}, {
						url: 'http://bwebstatic.de/pix/design/markerCluster.png',
						height: 44,
						width: 44,
						opt_textColor: '#ffffff'
					}, {
						url: 'http://bwebstatic.de/pix/design/markerCluster.png',
						height: 44,
						width: 44,
						opt_textColor: '#ffffff'
					}]];

				var mcOptionen = {gridSize: 45, maxZoom: 11, styles: styles[0]};
				var markerCluster = new MarkerClusterer(karte, mArr, mcOptionen);
				// Setzt die Karte so, dass alle Marker zu sehen sind.
				karte.fitBounds(bounds);
				zoomChangeBoundsListener = google.maps.event.addListener(karte, 'bounds_changed', function(event) {
					if (this.getZoom() > 14) // Change max/min zoom here
						this.setZoom(14);
					google.maps.event.removeListener(zoomChangeBoundsListener);
				});
			}
		}, // Ende bw.karte.initGross

		initMinimal: function (lat, lng, karteID) {
			// Initialisiert eine kleine Karte mit minimalen Steuer-Elementen
			var latLng = new google.maps.LatLng(lat, lng);
			var markerIcon = 'http://bwebstatic.de/pix/design/markerNormal.png';
			var optionen = {
				backgroundColor: '#fff',
				zoom: 13,
				center: latLng,
				mapTypeId: google.maps.MapTypeId.ROADMAP,
				mapTypeControl: false,
				scrollwheel: false,
				streetViewControl: false
			};
			var karte = new google.maps.Map(document.getElementById(karteID), optionen);
			var marker = new google.maps.Marker({position: latLng, map: karte, icon: markerIcon, clickable: false});
		},  // Ende bw.karte.initMinimal

		initStatisch: function (karteID) {
			$('#'+karteID).html('<img src="http://bwebstatic.de/maps/deutschland-640x60.png" class="statisch" alt="">');
		} // Ende bw.karte.initGross
	}, // Ende bw.karte


	//
	//  Die Listen mit Alternativen Programmen usw.
	//
	liste: {
		init: function () {
			bw.paginierung.init(); // Die Paginierung
			bw.popup.init(); // Die Popups starten
			bw.scrollLink.init(); // Die ScrollLinks starten
			bw.tabs.init(); // Die Tabs zum wechseln der Liste (Programm / Anbieter)
			bw.tabs.klick( $('#listeAlternativen ul.tabs a:first') ); // Die Tabs zum wechseln der Liste (Programm / Anbieter)
			bw.merkzettel.initMerken(); // Das Merken initialisieren
			bw.toggle.init(); // Das ein- und ausklappen starten
			bw.toggle.karte.init("alternativenKarte"); // Das ein- und ausklappen der Karte starten

			$(document).ready(function() {
				// Die kleine oder große Karte starten, je nach Kategorie.
				// Ist im document ready, weil es von der GoogleMaps Api abhängt und diese erst geladen werden muss.
				var karteID = 'alternativenKarte';
				var karte = $('#'+karteID);
				var link = $('a.toggleKarte');
				if ( karte.data('start') === 'gross' ) {
					bw.toggle.karte.gross(link, karte, karteID);
				} else {
					bw.toggle.karte.statisch(link, karte, karteID);
					bw.toggle.aktLink(link);
				}
			});
		} // Ende bw.liste.init
	}, // Ende bw.liste


	//
	//  Login Funktion
	//
	login: {
		init: function() {
			// Loginbox einfahren, wenn auf "Anbieter-Login"-Button geklickt.
			$('#loginButton').unbind('click').click(function(e) {
				e.preventDefault();
				$('.registrierenBox:visible').slideUp();
				$('#loginBox:hidden').slideDown();
			});

			// wenn nur die Fehlerbox angezeigt wird warte ein paar Sekunden dann slideup die Fehlerbox und geh auf die Startseite
			if ($('#loginBox').length === 0) {
				$('.formularBox div#fehlerMeldung').css('margin-bottom','15px');
				$('.login img.beenden').addClass('versteckt');
			}

			//
			$('.login .beenden').unbind('click').click(function(e) {
				e.preventDefault();
				if($('#fehlerMeldung:hidden').length) {
					$('.registrierenBox:hidden').slideDown();
				}
				$('#loginBox:visible').slideUp(function() {
					$('.registrierenBox:hidden').slideDown();
					$('.formularBox:visible').slideUp(function() {
						$('img.beenden, .titelH2', '#loginBox').removeClass('versteckt');
						$('#fehlerMeldung').parent().addClass('versteckt');
					});
				});
			});

			// zeige die Fehlermeldung in der LoginBox
			if ($('#fehlerMeldung .seitenListe div:empty').length === 1) {
				$('#fehlerMeldung .seitenListe').addClass('versteckt');
			} else {
				$('img.beenden, .titelH2', '#loginBox').addClass('versteckt');
				$('#fehlerMeldung').parent().removeClass('versteckt');
				$('#loginButton').trigger('click');
			}

			// logoutButton klicken um sich auszuloggen
			$('#logoutBox').unbind('click').click(function(e) {
				e.preventDefault();
				$('#logout').submit();
			});

			//tabs funktionen initialisieren
			bw.tabs.init();
			bw.tabs.initTabLink();
			bw.tabs.klick( $('#fuerAnbieter ul.tabs a:first') );
			bw.bilder.initProfilProgramm();
		} // Ende bw.login.init
	}, // Ende bw.login


	//
	//  Die Merkzettelseite und die Funktion zum Merken
	//
	merkzettel: {
		init: function () {
			bw.tabs.init();
			bw.tabs.klick($('#merkzettelContainer ul.tabs a:first'));
			bw.popup.init();
			bw.merkzettel.initLoeschen();
			bw.merkzettel.initSenden();
			bw.infosAnfordern.init();

			// Zeige das Formular zum Versenden des Merkzettels, wenn auf den Link geklickt wurde.
			$('a.merkzettelSenden').unbind('click').click(function () {
				bw.zeug.setzeHighlight( '.merkzettelFormularBox' );
				return false;
			});

			// Zeige das Formular zum Infos anfordern, wenn auf den Link geklickt wurde.
			$('a.informationenAnfordernButton').unbind('click').click(function () {
				if ($('#merkzettelContainer div.listenZeile input:checked').length !== 0) {
					$('.infosAnfordernLeerError').slideUp();

					bw.zeug.setzeHighlight( '.infosFormularBox' );

					var anfordernElemente = [];
					$('#merkzettelContainer div.listenZeile input:checked').each(function(){
						anfordernElemente.push($(this).val());
					});
					$('form#infosAnfordern input[name="tx_bwebmerkzettel_pi1[angeforderteID]"]').val($.toJSON(anfordernElemente));
				} else {
					$('.infosAnfordernLeerError').slideDown();
				}
				return false;
			});
		},  // Ende bw.merkzettel.init

		initMerken: function () {
		// Bei Klick wird per ajax SeitenId in session gespeichert
			$('a.merkenLink').unbind('click').click(function() {
				link = $(this);
				$.ajax({
					data: 'type=789456&seite='+link.data('id'),
					cache: false,
					success: function(data) {
						// Setze nicht nur den Link, der geklickt wurde, sondern alle, die die gleiche id als Klasse haben
						$('.merkenText.'+link.data('id')).html(data);
						// Anzahl gemerkter Seiten aktualiesieren
						var anzahl = parseInt($('.anzahlGemerkteSeiten').html(), 10);
						if(data == "Merken") {
							$('.anzahlGemerkteSeiten').html(anzahl-1);
						} else {
							$('.anzahlGemerkteSeiten').html(anzahl+1);
						}
					}
				});
				return false;
			});
		}, // Ende bw.merkzettel.initMerken

		initLoeschen: function () {
			// Bei Aufruf wird per Ajax die gemerkte Seite entmerkt und dann aus der Liste gelöscht
			$('a.loeschenLink').unbind('click').click(function(){
				// Der geklickte Link
				var link = $(this);
				$.ajax({
					// type ist der PageType der Merken-Ajax-Serverseite
					data: 'type=789456&seite='+$(this).data('id'),
					cache: false,
					success: function(data) {
						// Blende die entmerkte Zeile aus
						link.parents('.listenZeile').slideUp('400', function(){
							// Die aktuelle Liste zwischenmerken
							var liste = $(this).parent('.liste');

							// Entferne die entmerkte Zeile aus dem DOM
							$(this).remove();

							// Wenn eine H2-Überschrift in der Liste keine ListenZeile als Nachfolger hat,
							// dann sind alle gemerkten Seiten der Kategorie gelöscht worden. Die Überschrift kann
							// deshalb auch aus dem DOM entfernt werden.
							$( 'h2.titelH2', liste ).not( $('h2.titelH2').next('.listenZeile').prev() ).slideUp('200', function(){
								$(this).remove();
							});
						});

						// In der Merkzettelbox im Header wird die Anzahl der gemerkten Seiten aktualisiert.
						var anzahl = parseInt($('.anzahlGemerkteSeiten').html(), 10);
						$('.anzahlGemerkteSeiten').html(anzahl-1);

						// Wenn der Merkzettel leer ist, dann wird die Seite neu geladen, damit die Meldung des leeren Merkzettels erscheint.
						if((anzahl-1) == '0'){
							location.reload(true);
						}

						// Aktualisiere die Anzahl der gemerkten Einträge im Tab.
						var tab = $('.merkzettelTabs a[href*="'+link.parents('.liste').attr('id')+'"]' );
						var anzahlTab = $('span', tab).html();
						$('span', tab).html(anzahlTab - 1);

						// Wenn im aktuellen Tab / Liste keine gemerkten Seiten mehr sind, dann lade die Seite neu.
						if((anzahlTab-1) == '0'){
							location.reload(true);
						}
					}
				});
				return false;
			});
		}, // Ende bw.merkzettel.initLoeschen

		initSenden: function () {
			// Bei Aufruf werden per ajax Formulardaten verschickt
			$('.merkzettelFormularBox').delegate('a#merkzettelSenden', 'click', function () {
				$.ajax({
					// nzm: Ladegrafik setzen
					data: 'type=789457&'+$('form#merkzettel').serialize(),
					cache: false,
					beforeSend: function() {
						// Ladebilder entfernen
						bw.zeug.ladeBildEntfernen('.merkzettelFormularBox .inhalt');

						// Blende die Ladegrafiken ein
						bw.zeug.ladeBild( $('.merkzettelFormularBox .inhalt') );
					},
					error: function(XHR, status) {
						// Ladebilder entfernen
						bw.zeug.ladeBildEntfernen('.merkzettelFormularBox .inhalt');
						$(".merkzettelFormularBox .inhalt .formularZeile:last").prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
					},
					success: function(data) {
						$('.merkzettelFormularBox .inhalt').html(data);
					}
				});
				return false;
			});
		} // Ende bw.merkzettel.initSenden
	}, // Ende bw.merkzettel




	//
	//  Die Merkzettelseite und die Funktion zum Merken
	//
	newsletter: {
		init: function () {
			bw.newsletter.initSenden();
		}, // Ende bw.newsletter.initMerken

		initSenden: function (bereich) {
			// Bei Aufruf werden per ajax Formulardaten verschickt
			$('.newsletterFormularBox').delegate('a#newsletterSenden', 'click', function () {
				var email = $('input[name="tx_bwebnewsletter_newsletterabonnieren[newAbonnent][email]"]');
				// var checkbox = $('#newsletter input[type=checkbox]');
				// var emailValidate = email.val();
				// var checkboxValidate = checkbox.is(':checked');

					$.ajax({
						// nzm: Ladegrafik setzen
						data: 'type=789463&'+$('form#newsletter').serialize()+'&tx_bwebnewsletter_newsletterabonnieren[action]='+bereich,
						type: 'POST',
						cache: false,
						beforeSend: function() {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen('.newsletterFormularBox .inhalt');

							// Blende die Ladegrafiken ein
							bw.zeug.ladeBild( $('.newsletterFormularBox .inhalt') );
						},
						error: function(XHR, status) {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen('.newsletterFormularBox .inhalt');

							$(".newsletterFormularBox .inhalt .formularZeile:last").prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
						},
						success: function(data) {
							$('.newsletterFormularBox').html(data);

						}
					});

				return false;
			});
		}, // Ende bw.newsletter.initSenden

		initLink: function () {
			$('#newsletterAbonnieren').unbind('click').click( function() {


					$.ajax({
						data: 'type=789463',
						type: 'POST',
						cache: false,

						error: function(XHR, status) {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen('.newsletterFormularBox .inhalt');

							$(".newsletterFormularBox .inhalt .formularZeile:last").prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
						},
						success: function(data) {
							// Wenn der Newsletter schonmal aufgerufen wurde, ersetze den Inhalt. Sonst erstelle ihn neu.
							if($('.newsletterFormularBox').length) {
								$(this).html(data);
							} else {
								$('.inhaltBreit').append(data);
							}

							bw.zeug.setzeHighlight( '.newsletterFormularBox' );
						}

					});


				return false;
			});
		}
	}, // Ende bw.newsletter


	//
	//  Die Paginierung
	//
	paginierung: {
		init: function () {
			// Blättern in der Liste mit den Alternativen
			$('.liste .ajaxPaginierung').each(function () {
				// Daten der Paginierung
				var liste = $(this).parents('.liste');
				var anzErg = $('.listenZeile', liste).length;
				var anzProSeite = 8;

				var pDaten = {
					liste: liste,
					aktseite: 1,
					anzErg: anzErg,
					anzProSeite: anzProSeite,
					anzSeiten: Math.ceil(anzErg / anzProSeite) // aufgerundet die Anzahl der Seiten
				};

				// Speichere die Daten der Paginierung im Element
				$(this).data(pDaten);

				bw.paginierung.blaettern( $(this) );
			});
		}, // Ende bw.paginierung.init

		initKlick: function (suche) { // Parameter boolean für suche. Wenn nicht gesetzt, dann wird die Blätter-Funktion aufgerufen
			$('.liste .paginierung a').unbind('click').click(function () {
				var seiteGeklickt = $(this).attr('rel');
				var elem = $(this).parents('.paginierung');
				var aktseite = elem.data().aktseite;

				switch (seiteGeklickt) {
					case "naechste" :
						aktseite = (aktseite == elem.data().anzSeiten) ? aktseite : aktseite*1 + 1;
						break;
					case "vorherige" :
						aktseite = (aktseite == 1) ? 1 : aktseite*1 - 1;
						break;
					default:
						aktseite = parseInt(seiteGeklickt, 10);
						break;
				}

				// Nur Blättern falls es eine neue Seite ist und nicht die aktuelle
				if (elem.data().aktseite != aktseite) {
					elem.data().aktseite = aktseite;

					if (suche) {
						$('#suche').data().aktseite = aktseite;
						bw.suche.suchen(false, false);
					} else {
						bw.paginierung.blaettern( elem );
					}

					// Zum Anfang der Liste fahren.
					$(window.opera?'html':'html, body').delay(30).animate({scrollTop: elem.parents('.liste').offset().top - 40},500);
				}

				return false;
			});
		}, // Ende bw.paginierung.initKLick

		// Das eigentliche Blättern. Je nachdem welcher Button geklickt wurde.
		blaettern: function (elem) {
			bw.zeug.ladeBild(elem.data().liste);

			// Die Seiten in der Paginierung schreiben
			bw.paginierung.setSeiten(elem);

			bw.paginierung.initKlick();

			// Die Startzeile (-eintrag) ist die aktuelle Seite miuns 1 multipliziert mit der Anzahl der Ergebnisse pro Seite
			var startZeile = (elem.data().aktseite-1)*(elem.data().anzProSeite);
			// Die Endzeile ist die Startzeile plus die Anzahl der Ergebnisse minus eins
			var endZeile = parseInt(startZeile, 10)+parseInt(elem.data().anzProSeite, 10);
			// Wenn die Endzeile größer oder gleich der Anzahl der Ergebnisse ist, dann wird die Endzeile die Anzahl der Ergebnisse minus eins
			if (endZeile >= elem.data().anzErg) {endZeile = elem.data().anzErg;}

			// Die Anzeige der Listeneinträge
			$('div.listenZeile', elem.data().liste).hide();
			$('div.listenZeile:eq('+startZeile+')', elem.data().liste).show();
			$('div.listenZeile:gt('+startZeile+'):lt('+(elem.data().anzProSeite-1)+')', elem.data().liste).show();

			// Scroll-Event auslösen, falls sich die Länge der Seite geändert hat.
			bw.zeug.nachObenLinkAkt();

			// Das LadeBild wieder von der Liste entfernen
			window.setTimeout(function() {
				bw.zeug.ladeBildEntfernen(elem.data().liste);
			}, 300);
		}, // Ende bw.paginierung.blaettern

		// Die Paginierung (Die Seiten) schreiben
		setSeiten: function (elem) {
			// Hole die Klasse des Templates und den Json der Daten die in das Template sollen
			var container = elem.data().liste.parents('div.listeContainer').attr('id');

			// Erstelle das Objekt mit den Seiten.
			var seiten = [];
			for (var i=1; i <= elem.data().anzSeiten; i++) {
				// Es sollen nur die ersten drei und die letzten drei sowie je eine Seite davor und danach angezeigt werden
				if ((i < (elem.data().aktseite - 1) && i > 3) || (i > (elem.data().aktseite + 1) && i < (elem.data().anzSeiten - 2))) {
					// Ansonsten kommt ... (übergeben als false ans template), aber nur einmal.
					if (seiten[seiten.length - 1].seite) seiten.push({'seite': false});
				} else {
					// Die Seite hinzufügen und ihr die aktiv-Klasse geben, wenn es die aktuelle Seite ist.
					seiten.push({'seite': i, 'aktiv': (i == elem.data().aktseite) ? true : false});
				}
			}

			// Das Template wird mit den Daten gefüllt
			var templateHtml = Mustache.to_html($('#'+container+'PaginierungTemplate').html(), {'seiten': seiten});
			$('.paginierung .seiten', elem.data().liste).html(templateHtml);
		}
	}, // Ende bw.paginierung


	//
	//  Die Popups
	//
	popup: {
		init: function () {
			// Beim Klick wird ein Popup geöffnet
			$('a.popupLink').unbind('click').click(function() {
				bw.popup.oeffnen( $(this) ); // Übergeben wird das geklickte Element
				return false;
			});

			// Beim Mouseover soll sich auch ein Popup öffnen
			$('a.popupLink').unbind('hover').hover(
				// Mouseover-Event
				function() {
					// Gibt dem ganzen eine Klasse und dann wird nach einem Timeout das Klick-Event des fokussierten Links ausgeführt
					$(this).addClass('hatFokus');
					hover_intent = setTimeout( function() {
						$('a.popupLink.hatFokus').trigger('click');
					} , 500 );
				},
				// Mouseout-Event Löscht den Timer und entfernt die Klasse
				function() {
					try{
						clearTimeout(hover_intent);
					} catch(e) { }
					$(this).removeClass('hatFokus');
				}
			);
		}, // Ende bw.popup.init

		oeffnen: function (link) {
			// Nur anzeigen, wenn noch nicht offen
			if (!link.hasClass('popupOffen')) {
				// Das alte (ein eventuell angezeigtes Popup) soll weg, ebenso die Klasse auf dem Link
				$('.popup').remove();
				$('.popupOffen').removeClass('popupOffen');
				$(document).unbind('click');

				// Eine Klasse wird auf den Popup-Link gesetzt, dass dieser Link gerade ein Popup geöffnet hat.
				link.addClass('popupOffen');

				// Hole die Klasse des Templates und den Json der Daten die in das Template sollen
				var container = link.parents('div.listeContainer').attr('id');
				var template = link.data('template');
				var daten = link.data('daten');

				// Das Template wird mit den Daten gefüllt
				var templateHtml = Mustache.to_html($('#'+container+template+'Template').html(), daten);
				link.parents('div.listenZeile').children('.optionen').before(templateHtml);

				// Anzeigen der Karte
				if (template == 'karteAnzeigen') {
					bw.karte.initMinimal(daten.lat, daten.lng, "popupKarte");
				}

				// Bilder-Popup: Erstes Vorschaubild wird großes Bild und das Klick-Event für die Vorschaubilder wird initialisiert
				if (template == 'bilderAnzeigen') {
					bw.bilder.initVorschauScroll('.popup .vorschauBilder');
					bw.bilder.initVorschauKlick('.popup .vorschauBilder');
				}

				// Infos-Anfordern-Button aktivieren
				if (template == 'infosAnfordern') {
					bw.infosAnfordern.init();
				}

				var popup = $('.popup');

				// Der Pfeil des Popups wird aus der Breite und Position des Links heraus berechnet und entsprechend gesetzt
				// (linker Rand des Links - linker Rand des Popups + (Linkbreite - Breite Pfeil) / 2)
				$('.popupPfeil', popup).css('left', ( (link.offset().left - popup.offset().left) + ((link.width() - 10) / 2) ));

				// Einblenden des neuen Popups. Wird zuerst versteckt, damit es dann langsam erscheinen kann.
				popup.hide().fadeIn('200', function() {
					// Wenn man irgendwo, ausser im Popup selbst, klickt, dann wird das Popup geschlossen.
					$(document).click(function(event) {
						if(!($(event.target).parents().andSelf().is('.popup'))){
							bw.popup.schliessen();
							$(document).unbind('click');
						}
					});
				});

				// Rücke Ansicht zurecht, damit das Popup immer sichtbar ist.
				bw.zeug.ansichtAkt(popup, '400');
			}
		}, // Ende bw.popup.oeffnen

		schliessen: function() {
			$('.popup').fadeOut('200', function () {
				$(this).remove();
				$('.popupOffen').removeClass('popupOffen');
			});
		} // Ende bw.popup.schliessen
	}, // Ende bw.popup


	//
	//  Die Profile
	//
	profil: {
		init: function() {
			bw.popup.init(); // Die Popups starten
			bw.scrollLink.init(); // Die ScrollLinks starten
			bw.toggle.init(); // Das ein- und ausklappen starten
			bw.merkzettel.initMerken(); // Das Merken initialisieren
			bw.infosAnfordern.initHighlight(); // Hervorhebung der Box für Infos anfordern
			bw.bilder.initProfilAnbieter(); // Die Bildervorschauliste im Anbieterprofil
			bw.bilder.initProfilProgramm(); // Die BilderBox im Programmprofil
			bw.bilder.initVorschauKlick('#bildergalerie .vorschauBilder'); // Klick auf die Vorschaubilder in der Bildergalerie
			bw.bilder.initVorschauScroll('.profil .links .vorschauBilder'); // Hin- und herscrollen der VorschauBilder im Anbieterprofil oben starten

			// Klick auf den Kostenbemerkungenlink
			$('#kostenbemerkungen').unbind('click').click(function() {
				$('#kostenbemerkungenBox').fadeToggle(function() {
					$(document).unbind('click');
					if ($(this).is(':visible')) {
						// Wenn man irgendwo, ausser im Popup selbst, klickt, dann wird das Popup geschlossen.
						$(document).click(function(event) {
							if(!($(event.target).parents().andSelf().is('#kostenbemerkungenBox'))){
								$('#kostenbemerkungenBox').fadeOut();
								$(document).unbind('click');
							}
						});
					}
				});
				return false;
			});

			$(document).ready(function() {
				bw.karte.initMinimal($('#profilKarte').data('lat'), $('#profilKarte').data('lng'), "profilKarte"); // Die kleine Karte starten. Ist im document ready, weil es von der GoogleMaps Api anhängt und diese erst geladen werden muss.
			});
		} // Ende bw.profil.init
	}, // Ende bw.profil


	//
	//  Der Registrierungslink
	//
	registrierung: {
		initLink: function () {
			// Zeige das Formular zum Registrieren, wenn auf den Link geklickt wurde.
			$('.registrierenLink').unbind('click').click(function () {
				bw.registrierung.setzeBoxHoehe();
				$(window).resize(function() {
					bw.registrierung.setzeBoxHoehe();
				});

				bw.zeug.setzeHighlight( '.registrierenFormularBox' );
				return false;
			});
		}, // Ende bw.registrierung.initLink

		setzeBoxHoehe: function () {
			// Die Höhe muss per Javascript gesetzt werden, da der Firefox sonst nur die minimale Höhe anzeigt. Prozentuale Angaben mag er an der Stelle nicht.
			var hoehe =  $(window).height() * 0.75;
			hoehe = (hoehe > 570) ? 570 : hoehe;
			$('.registrierenFormularBox iframe').css('height', hoehe+'px');
		} // Ende bw.registrierung.setzeBoxHoehe
	}, // Ende bw.registrierung


	//
	//  Die Scrollbar
	//
	scrollBar: {
		init: function () {
			$('.scrollbarBox').each(function () {
				var scrollbarBox = this;
				var regler = $('.scrollbarRegler', scrollbarBox);

				regler.data('hoeheAussen', parseInt($(scrollbarBox).height(), 10) );
				regler.data('hoeheInnen', parseInt($('.boxInnen', scrollbarBox).height(), 10) );
				regler.data('hoeheScrollbar', parseInt($('.scrollbar', scrollbarBox).height(), 10) );

				// Verhaeltnis des Scrollbalkens im Zusammenhang mit der Inhaltgrösse
				regler.data('hoeheScrollbarRegler', Math.ceil(( regler.data('hoeheScrollbar') * regler.data('hoeheAussen') ) / regler.data('hoeheInnen') ) );
				regler.height( regler.data('hoeheScrollbarRegler') );

				// maximale Veränderung
				regler.data('maxScroll', regler.data('hoeheScrollbar')-regler.data('hoeheScrollbarRegler') );

				// Mausklick gedrückt
				regler.mousedown( function(eventDown) {
					$('body').css('cursor', 'pointer');

					scrollbarBox.onselectstart = function(){return false;};
					scrollbarBox.onmousedown=function(){return false;};
					scrollbarBox.unselectable = "on";
					scrollbarBox.style.MozUserSelect = "none";

					// hoehe wenn man die Maus drückt
					regler = $(this);
					regler.data('hoeheStart', parseInt(eventDown.pageY, 10));

					// Maus bewegt sich im browser
					$(document).mousemove( function(eventMove) {
						$('.scrollbar', scrollbarBox).css('cursor', 'pointer');
						var delta = parseInt(eventMove.pageY, 10)-regler.data('hoeheStart');
						regler.data('hoeheStart', parseInt(eventMove.pageY, 10));
						bw.scrollBar.bewege(scrollbarBox, delta);
					});
				});

				$(document).mouseup(function () {
					$('body').css('cursor', 'default');
					$(document).unbind('mousemove');
				});

				$(scrollbarBox).mousewheel(function(e, delta) {
					if (delta > 0) {
						bw.scrollBar.bewege(this, -10);
					} else if (delta < 0) {
						bw.scrollBar.bewege(this, 10);
					}
					return false; // prevent default
				});
			});
		}, // Ende bw.scrollBar.init

		bewege: function (scrollbarBox, scrollbarTopDelta) {
			var regler = $('.scrollbarRegler', scrollbarBox);
			var reglerTop = regler.css('top');

			var scrollbarTop = parseInt(reglerTop.substring(0, reglerTop.length-2), 10) + scrollbarTopDelta;
			// Die Höhe der Zahl die bei eventMove.pageY übergeben wird,
			// darf nicht die maximale Zahl überschreiten und nicht unter Null gehn

			if (scrollbarTop >= regler.data('maxScroll')) {
				scrollbarTop = regler.data('maxScroll');
			}
			if (scrollbarTop <= 0) {
				scrollbarTop = 0;
			}
			if (scrollbarTop <= regler.data('maxScroll')) {
				if (scrollbarTop >= 0) {
					regler.css('top', scrollbarTop);
				}
			}
			var inhaltTop = Math.ceil( (regler.data('hoeheAussen') - regler.data('hoeheInnen')) * (scrollbarTop / regler.data('maxScroll')));
			$('.boxInnen', scrollbarBox).css('top', (inhaltTop));
		} // Ende bw.scrollBar.bewege
	}, // Ende bw.scrollBar


	//
	// Die ScrollLinks
	//
	scrollLink: {
		// Smoothes Scrollen initialisieren.
		// Alle Links mit der Klasse scrollLink scrollen weich zu dem Element (ID!), welches im href angegeben ist.
		// Link-Beispiel: <a href="#listeProgramme" class="scrollLink">Liste der Programme</a>
		init: function() {
			$('a.scrollLink').unbind('click').click(function() {
				// Ziel ist das Element, welches als ID den Inhalt des Ankers hat
				$(window.opera?'html':'html, body').delay(30).animate({scrollTop: $($(this).attr('href')).offset().top},500);
				return false;
			});
		} // Ende bw.scrollLink.init
	}, // Ende bw.scrollLink


	seo: {
		init: function () {
			bw.bilder.initVorschauScroll('.vorschauBilder');
			bw.bilder.initVorschauKlick('.vorschauBilder');
			bw.toggle.init();
			$('.toggleUebersichtEinstieg').trigger('click');				
			bw.toggle.karte.init("einstiegsKarte");
			bw.karte.initGross("einstiegsKarte");
			
			$(document).ready(function() {
				// Die kleine oder große Karte starten, je nach Kategorie.
				// Ist im document ready, weil es von der GoogleMaps Api abhängt und diese erst geladen werden muss.
				var karteID = 'einstiegsKarte';
				var karte = $('#'+karteID);
				var link = $('a.toggleKarte');
				if ( karte.data('start') === 'gross' ) {
					bw.toggle.karte.gross(link, karte, karteID);
				} else {
					bw.toggle.karte.statisch(link, karte, karteID);
					bw.toggle.aktLink(link);
				}
			});
		}
	},



	//
	//  Slideshows
	//
	slideshow: {
		init: function () {
			$('.slideshow').each(function () {
				var slideshow = $(this);

				// Verstecke alle Slides, zeige nur die erste.
				$('.slide', slideshow).hide();
				$('.slide:first', slideshow).show();
				$('.slide', slideshow).removeClass('ausDemSichtbereich');

				// Paginierung generieren
				$('.slide', this).each(function (i) {
					$('ul.slidesPaginierung', slideshow).append('<li><a href="#" rel="'+i+'"></a></li>');
				});

				// Erste Paginierung wird aktiviert
				$('.slidesPaginierung li:first').addClass('aktiv');

				// Rotation starten. In Variable speichern, damit man es abbrechen kann.
				var play = bw.slideshow.play(slideshow);

				// Paginierungsklicks aktivieren
				$('.slidesPaginierung li a').unbind('click').click(function () {
					// Wenn nicht die schon aktive Slide gewählt wird
					if ( !$(this).parent().hasClass('aktiv') ) {
						// Lösche das timeout und pausiere. Lade die Slide und starte die Wiedergabe erneut, wenn die Box nicht gerade den Fokus (Hover) hat.
						clearInterval(play);
						bw.slideshow.ladeSlide( slideshow, $(this).attr('rel') );
						if (!slideshow.hasClass('hatFokus')) {
							play = bw.slideshow.play(slideshow);
						}
					}
					return false;
				});

				slideshow.unbind('hover').hover(function() {
					// Beim MouseOver die Wiedergabe stoppen
					clearInterval(play);
					$(this).addClass('hatFokus');
				}, function() {
					// Beim MouseOut die Wiedergabe fortsetzen
					play = bw.slideshow.play(slideshow);
					$(this).removeClass('hatFokus');
				});
			});
		},
		ladeSlide: function (slideshow, slideNr) {
			// Nth-child fängt bei eins an zu zählen
			slideNr++;

			// Blende die sichtbare Slide aus und die gewünschte ein.
			$('.slide:visible', slideshow).fadeOut(800, function () {
				$('.slide:nth-child('+slideNr+')', slideshow).fadeIn(800);

				// Aktualisiere die aktiv-Klasse in der Paginierung
				$('.slidesPaginierung li', slideshow).removeClass('aktiv');
				$('.slidesPaginierung li:nth-child('+slideNr+')').addClass('aktiv');
			});

		},
		play: function (slideshow) {
			// Timer auf 7 Sekunden setzen
			var play = setInterval(function() {
				// Nächste Slide laden. Die erste, wenn es keine mehr gibt.
				var nextSlide = $('.slidesPaginierung li.aktiv', slideshow).next();
				if ( nextSlide.length === 0) {
					nextSlide = $('.slidesPaginierung li:first', slideshow);
				}
				var slideNr = nextSlide.children('a').attr('rel');
				// Nächste Slide laden
				bw.slideshow.ladeSlide( slideshow, slideNr );
			}, 7000);

			// Internval zurückgeben, damit man es abbrechen kann
			return play;
		}
	},


	//
	//  Die Suche
	//
	suche: {
		init: function() {
			bw.dropdownBox.init();
			bw.popup.init();
			bw.toggle.init();
			bw.toggle.karte.init("suchergebnisKarte"); // Das ein- und ausklappen der Karte starten

			bw.suche.initKriterien();
			bw.suche.initSortierung();

			$(document).ready(function() {
				// Die kleine oder große Karte starten, je nach Kategorie.
				// Ist im document ready, weil es von der GoogleMaps Api abhängt und diese erst geladen werden muss.
				var karteID = 'suchergebnisKarte';
				var karte = $('#'+karteID);
				var link = $('a.toggleKarte');
				if ( karte.data('start') === 'gross' ) {
					bw.toggle.karte.gross(link, karte, karteID);
				} else {
					bw.toggle.karte.statisch(link, karte, karteID);
					bw.toggle.aktLink(link);
				}
				bw.suche.suchen(true, true, true); // ladeDatenVomHash, aktKriterium, aktFilter
			});
		}, // Ende bw.suche.init

		initSuchformular: function () {
			bw.toggle.suchformular();
			bw.suche.initKriterien();

			// Zuerst ganz weit ausserhalb, damit die Elemente problemlos initialisiert werden können
			$('#erweiterteSuchoptionen').addClass('versteckt').removeClass('ausDemSichtbereich');

			$('#suchen').unbind('click').click( function () {
				// Daten in JSON umwandeln
				var daten = $.toJSON($('#suche').data());

				// Ajax-Request abschicken
				$.ajax({
					url:location.pathname,
					data: "eID=hashID&kriterien="+daten,
					dataType: "json",
					type: "POST",
					cache: false,
					beforeSend: function() {
						// Ladebilder entfernen
						bw.zeug.ladeBildEntfernen(document);

						// Blende die Ladegrafiken ein
						bw.zeug.ladeBild( $('.suchkriterien') );
					},
					error: function(XHR, status) {
						// Ladebilder entfernen
						bw.zeug.ladeBildEntfernen(document);

						$(".suchformularBox .fussZeile").prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
					},
					success: function(d) {
						// Suche an die Sucheseite mit der ermittelten Hash-ID schicken
						window.location = $(".suchformularBox form").attr("action") + '#' + d.hashID;
					}
				});
				return false;
			});

			// $(document).ready(function() {
			//	$('.suchformular .model img').height( $('.suchformular').outerHeight() + 12 );
			// });
		}, // Ende bw.suche.initSuchformular

		initKriterien: function() {
			bw.suche.initBeginn();
			bw.suche.initDauer();
			bw.suche.initKosten();
			bw.suche.initMultiSelect();
			bw.suche.initOrt();
		}, // Ende bw.suche.initKriterien

		// Initialisieren der Beginn-Radio-Buttons
		initBeginn: function () {
			// Wenn Beginn angezeigt wird. Sonst wird direkt abgebrochen.
			if ( $('.beginn').length > 0 ) {
				// Datepicker von JQuery UI initialisieren. Nur, wenn vorhanden.
				$(document).ready(function () {
					var kalender = $('#beginnvon, #beginnbis').datepicker({
						dateFormat: 'dd.mm.yy',
						dayNamesMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
						firstDay: 1,
						maxDate: '+5y',
						minDate: '+0',
						monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'],
						nextText: '',
						prevText: '',
						showAnim: 'slideDown',
						onSelect: function( selectedDate ) {
							// Min bzw. MaxDatum vom jeweils anderen Kalender wird auf das ausgewählte gesetzt
							var option = this.id == "beginnvon" ? "minDate" : "maxDate",
								instance = $( this ).data( "datepicker" ),
								datum = $.datepicker.parseDate(
									instance.settings.dateFormat ||
									$.datepicker._defaults.dateFormat,
									selectedDate, instance.settings
								);
							kalender.not( this ).datepicker( "option", option, datum );

							// Datum wird in einen Timestamp umgewandelt
							// Unix Timestamp in seconds, Javascript timestamp in Milliseconds ( / 1000 )
							datum = $.datepicker.formatDate('@', datum);
							datum = datum / 1000;

							// Es wird Kalender als Datum ausgewählt und das gewählte Datum gespeichert
							var beginnKalender = $('#beginn--kalender');
							beginnKalender.prop('checked', true).data( $( this ).data('feld'), datum );
							$('#suche').data('beginn', {
								wert: beginnKalender.data('wert'),
								von: beginnKalender.data('von'),
								bis: beginnKalender.data('bis')
							});
							// Wenn auf der Sucheseite, dann wird gesucht.
							if ($('#suche').data('suchseite')) {
								bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
							}
						}
					});
				});

				// Setze das Klick-Event für die Radiobuttons
				$('.beginn input:radio').unbind('click').click(function() {
					// Mache nur etwas, wenn nicht der gleiche, schon gewählte Beginn nochmal geklickt wird.
					if ($(this).data('wert') != $('#suche').data('beginn').wert) {
						// Beginn auslesen und setzen
						$('#suche').data('beginn', {
							wert: $(this).data('wert'),
							von: $(this).data('von'),
							bis: $(this).data('bis')
						});
						bw.suche.setBeginn();
						// Wenn auf der Sucheseite, dann wird gesucht.
						if ($('#suche').data('suchseite')) {
							bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
						}
					}
				});

				// Setze den ersten Beginn, der gefunden wird.
				$('#suche').data('beginn', $('.beginn input:first').data());
				bw.suche.setBeginn();
			}
		}, // Ende bw.suche.initBeginn

		// Initialisieren des Dauer-Sliders
		initDauer: function () {
			if ( $('.dauer').length > 0 ) {
				$('#suche').data('dauer', $('#dauer').data());
				var dauer = $('#suche').data('dauer');

				dauer.von = dauer.minimum;
				dauer.bis = dauer.maximum;

				bw.suche.setDauer();
			}
		}, // Ende bw.suche.initDauer

		initFilter: function () {
			$('.filter input').unbind('click').click(function () {
				var filter = $(this).parents('.filter');
				var tmpArr = [];
				filter.find('input:checked').each(function () {
					tmpArr.push($(this).val());
				});

				$('#suche').data(filter.data('filter'), tmpArr);
				$('#suche').data('aktseite', 1);
				bw.suche.suchen(false, false, true); // ladeDatenVomHash, aktKriterium, aktFilter
			});
		}, // Ende bw.suche.initFilter

		// Initialisieren des Kosten-Sliders
		initKosten: function () {
			var elem = $('.kostenOption input:first');

			$('#suche').data('kosten', elem.data());
			var kosten = $('#suche').data('kosten');

			kosten.von = kosten.minimum;
			kosten.bis = kosten.maximum;

			$('.kostenOption input').unbind('click').click(function() {
				if ($(this).data('feld') != $('#suche').data('kosten').feld) {
					$('#suche').data('kosten', $(this).data());
					var kosten = $('#suche').data('kosten');

					kosten.von = kosten.minimum;
					kosten.bis = kosten.maximum;

					bw.suche.setKosten( $(this) );
					if ($('#suche').data('suchseite')) {
						bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
					}
				}
			});

			bw.suche.setKosten( elem );
		}, // Ende bw.suche.initKosten

		// Initialisieren der MultiSelects
		initMultiSelect: function () {
			// Alle Selects mit der Klasse multiSelect werden Selects mit einer Mehrfachauswahl
			$(".multiSelect").multiSelect({
				selectAll: true,
				selectAllText: 'alle auswählen',
				//oneOrMoreSelected: '% ausgewählt',
				oneOrMoreSelected: '*',
				noneSelected: '<span class="startText">Bitte auswählen</span>'
			}, function (elem) {
				// Callback function
				var krit = elem.parents('.suchkriterium');
				var tmpArr = [];
				krit.find('.multiSelectOptions label.checked:not(.selectAll) input').each(function () {
					tmpArr.push($(this).val());
				});

				$('#suche').data(krit.data('kriterium'), tmpArr);
				if ($('#suche').data('suchseite')) {
					bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
				}
			});
		}, // Ende bw.suche.initMultiSelect

		initOrt: function () {
			bw.suche.setOrt();
		}, // Ende bw.suche.initOrt

		// Sortierung initialisieren
		initSortierung: function () {
			// In der Suche die Sortierung speichern
			$('#suche').data('sortierungnach', $('.sortierungAktuell').data('sortierungnach'));
			$('#suche').data('sortierungrichtung', $('.sortierungAktuell').data('sortierungrichtung'));
			bw.suche.setSortierung();

			// Klick der Suche
			$('.sortierungLink a').unbind('click').click(function () {
				var daten = $(this).data();
				$('#suche').data(daten.sortierung, daten.wert);
				$('#suche').data('aktseite', 1);

				bw.suche.setSortierung();
				if ($('#suche').data('suchseite')) {
					bw.suche.suchen(false, false, false); // ladeDatenVomHash, aktKriterium, aktFilter
				}
				return false;
			});
		}, // Ende bw.suche.initSortierung

		// Wenn beim Ort etwas geändert / aktualisiert wurde
		aktOrt: function () {
			var tmpArr = [];
			var orteArr = $('#as-values-ortInput').val().split(",");
			$.each(orteArr, function(k, wert) {
				if (wert !== '') {
					var orte = wert.split("#");
					var ort = {};
					ort.name = orte[0];
					ort.element_von = orte[1];
					ort.typ = orte[2];
					ort.value = wert;
					tmpArr.push(ort);
				}
			});
			$('#suche').removeData('ort').data('ort', tmpArr);
			if ($('#suche').data('suchseite')) {
				bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
			}
		}, // Ende bw.suche.aktOrt

		// Setzen des Beginn-AuswahlRadio
		setBeginn: function () {
			if ( $('.beginn').length > 0 ) {
				$( '#beginn--' + $('#suche').data('beginn').wert ).prop("checked", true);

				// Datepicker setzen
				// Unix Timestamp in seconds, Javascript timestamp in Milliseconds ( * 1000 )
				if ($('#suche').data('beginn').von) {
					$('#beginn--kalender').data('von', $('#suche').data('beginn').von);
					var von = $.datepicker.parseDate('@', $('#suche').data('beginn').von+'000');
					$('#beginnvon').datepicker("setDate", von);
					$('#beginnbis').datepicker("option", "minDate", von);
				}
				if ($('#suche').data('beginn').bis) {
					$('#beginn--kalender').data('bis', $('#suche').data('beginn').bis);
					var bis = $.datepicker.parseDate('@', $('#suche').data('beginn').bis+'000');
					$('#beginnbis').datepicker("setDate", bis);
					$('#beginnvon').datepicker("option", "maxDate", bis);
				}
				// Verstecke das div. Aus irgendeinem Grund wird es sonst nach dem Footer angezeigt.
				$('#ui-datepicker-div').hide();
			}
		}, // Ende bw.suche.setBeginn

		// Setzen des Dauer-Sliders auf das übergebene Element
		setDauer: function () {
			if ( $('.dauer').length > 0 ) {
				var dauer = $('#suche').data('dauer');

				$("#dauerSlider").slider({
					range: true,
					min: parseInt(dauer.minimum, 10),
					max: parseInt(dauer.maximum, 10),
					values: [dauer.von, dauer.bis],
					// Wenn der Slider bewegt wird
					slide: function(e, ui) {
						$("#dauerWertAnzeige").empty().append(ui.values[0] + ' ' + dauer.lldauertyp + ' - ' + ui.values[1] + ' ' + dauer.lldauertyp);
					},
					// Wenn Silder losgelassen
					stop: function(e, ui) {
						dauer.von = ui.values[0];
						dauer.bis = ui.values[1];
						if ($('#suche').data('suchseite')) {
							bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
						}
					}
				});
				// Anfangstext der Anzeige
				$('#dauerWertAnzeige').empty().append($("#dauerSlider").slider("values", 0) + ' ' + dauer.lldauertyp + ' - ' + $("#dauerSlider").slider("values", 1) + ' ' + dauer.lldauertyp);
			}
		}, // Ende bw.suche.setDauer

		// Setzen des Kosten-Sliders auf das übergebene Element
		setKosten: function (elem) {
			elem.prop("checked", true);

			var kosten = $('#suche').data('kosten');
			kosten.minimum = elem.data('minimum');
			kosten.maximum = elem.data('maximum');

			// Slider neu initialisieren
			$("#kostenSlider").slider({
				//~ range: true,
				range: "min",
				min: kosten.minimum,
				max: kosten.maximum,
				step: 100,
				value: kosten.bis,
				// Wenn der Slider bewegt wird
				slide: function(e, ui) {
					$("#kostenWertAnzeige").empty().append(kosten.von + ' \u20ac - ' + ui.value + ' \u20ac');
				},
				// Wenn Silder losgelassen
				stop: function(e, ui) {
					kosten.bis = ui.value;
					if ($('#suche').data('suchseite')) {
						bw.suche.suchen(false, true, false); // ladeDatenVomHash, aktKriterium, aktFilter
					}
				}
			});
			// Anfangstext der Anzeige
			$("#kostenWertAnzeige").empty().append(kosten.von + ' \u20ac - ' + $("#kostenSlider").slider("value") + ' \u20ac');
		}, // Ende bw.suche.setKosten

		// MultiSelects Aktualisieren
		setMultiSelect: function () {
			$('.multiSelect').each(function () {
				// MultiSelects mit den Werten aus der Suche füllen
				$(this).multiSelectOptionsSetValues( $('#suche').data( $(this).parent('.suchkriterium').data('kriterium') ) );
			});
		}, // Ende bw.suche.setMultiSelect

		setOrt: function () {
			// Programmort wird erzeugt und mit werten gefüllt.
			// Erstellt eine Kopie, und löscht die alte, damit die preFill-Werte auch angezeigt werden.
			$("#ort").remove();
			$("#ortVorlage").clone().insertBefore("#ortVorlage").attr("id", "ort").show();
			$("#ortVorlage").hide();


			// Das Eingabefeld für das AutoSuggest mit dem Ort
			var startText = $('#ort input').data('starttext');
			var orte = $('#suche').data('ort');
			$('#ort input').autoSuggest(location.pathname, {
				extraParamsBefore: "eID=autocompleteOrt&",
				extraParams: "&portal="+$('#suche').data('portal')+"&kategorie="+$('#suche').data('kategorie'),
				asHtmlID: "ortInput",
				selectedItemProp: "name",
				preFill: orte,
				searchObjProps: "name",
				startText: startText,
				emptyText: "Keine Ergebnisse gefunden",
				limitText: "Es dürfen keine weiteren Orte mehr hinzugefügt werden",
				keyDelay: 200,
				selectionLimit: 10,
				selectionAdded: function(e) {
					$("#ortInput").css("width","75px");
					bw.suche.aktOrt();
				},
				selectionRemoved: function(e) {
					e.remove();
					if ($('#as-values-ortInput').val() === '') {$("#ortInput").css("width","220px");}
					bw.suche.aktOrt();
				},
				formatList: function(d, e) {
					var newE = e.html("<b>" + d.name + "</b> <span class='as-result-item-note'>" + d.element_von + "</span>");
					return newE;
				},
				resultGroups: true,
				resultGroupProp: "typ",
				matchFirst: true
			});
			if (orte.length > 0) {$("#ortInput").css("width","75px");}
		}, // Ende bw.suche.setOrt

		// Sortierung setzen
		setSortierung: function () {
			var sortierungnach = $('#suche').data('sortierungnach');
			var sortierungrichtung = $('#suche').data('sortierungrichtung');
			$('.sortierungAktuell .nach').html( $('.'+ sortierungnach +' a').html() );
			$('.sortierungAktuell .richtung').html( $('.'+ sortierungrichtung +' a').html() );
			$('.sortierungLink').removeClass('aktiv');
			$('.sortierungLink.nach.'+ sortierungnach +', .sortierungLink.richtung.'+ sortierungrichtung).addClass('aktiv');
		}, // Ende bw.suche.setSortierung

		// Die Anfrage an den Server
		suchen: function (ladeDatenVomHash, aktKriterium, aktFilter) {
			// Das Suche-Element
			var suche = $('#suche');
			// Speichere, was gesucht bzw. aktualisiert werden soll
			suche.data('ladeDatenVomHash', ladeDatenVomHash);
			suche.data('aktKriterium', aktKriterium);
			suche.data('aktFilter', aktFilter);

			// Übergib die hashID, damit überprüft werden kann, ob schon Daten existieren
			suche.data('hashID', window.location.hash.slice(1));

			// Aktuelle Seite setzen. Wenn noch nichts da ist, wird die erste aufgerufen
			if (!suche.data('aktseite')) {
				suche.data().aktseite = 1;
			}

			if (aktKriterium) {
				suche.data().aktseite = 1;
				suche.data('anbieter', []);
				suche.data('unterkategorien', []);
			}

			// Daten in JSON umwandeln
			var daten = $.toJSON(suche.data());

			// Ajax-Request abschicken
			$.ajax({
				url:location.pathname,
				data: "eID=sucheErgebnisse&kriterien="+daten,
				dataType: "json",
				type: "POST",
				cache: false,
				beforeSend: function() {
					// Ladebilder entfernen
					bw.zeug.ladeBildEntfernen(document);

					// Blende die Ladegrafiken ein
					bw.zeug.ladeBild( $('.suchseiteListe') );

					if (aktKriterium) {bw.zeug.ladeBild( $('.suchseiteFormular .filter') );}
				},
				complete: function() {
					// Ladebilder wieder entfernen
					bw.zeug.ladeBildEntfernen(document);
				},
				error: function(XHR, status) {
					$("#suchseiteErgebnisliste").empty().html('<div class="info error grid-12-12">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
				},
				success: function(d) {
					// Titel neu setzen
					document.title = d.titel;

					// Neuer Hash wird gesetzt
					if (window.location.hash != d.hashID) {
						$('#suche').data('hashID', d.hashID);
						window.location.hash = d.hashID;
						bw.zeug.setFavicon();
					}

					// Liste inklusive Überschrift neu setzen und Popups usw neu initialisieren
					$('.suchseiteListe h1').html( d.ueberschrift );
					$('#suchseiteErgebnisliste').html( d.liste );
					bw.merkzettel.initMerken();
					bw.popup.init();

					// Daten der Paginierung
					var paginierung = $('#suchseiteErgebnisse .paginierung');
					var liste = paginierung.parents('.liste');

					var pDaten = {
						liste: liste,
						aktseite: d.aktseite,
						anzErg: d.anzErg,
						anzProSeite: d.proSeite,
						anzSeiten: Math.ceil(d.anzErg / d.proSeite) // aufgerundet die Anzahl der Seiten
					};

					// Speichere die Daten der Paginierung im Element
					paginierung.data(pDaten);
					// Die Seiten in der Paginierung schreiben
					bw.paginierung.setSeiten( paginierung );
					bw.paginierung.initKlick( true ); // Übergebe true für suche=true

					// Angezeigte Seiten ausgeben
					$('.anzErg').html(d.anzErg);
					$('.ergVon').html(d.ergVon);
					$('.ergBis').html(d.ergBis);

					// Wenn ein Suchkriterium geändert wurde
					if (aktKriterium) {
						// Aktualisiere die Filter
						$('.suchseiteFormular .filter.anbieter').html(d.filterAnbieter);
						$('.suchseiteFormular .filter.unterkategorie').html(d.filterUnterkategorien);
						bw.suche.initFilter();
						bw.toggle.init();
					}

					if (aktKriterium || aktFilter) {
						// Marker für die Karte setzen
						$('#suchergebnisKarte').data('markers', d.markers);

						// Aktualisiere Karte, wenn die ausgeklappt ist
						if ( $('.kartenInhalt').hasClass('gross') ) {
							bw.karte.initGross( $('.kartenInhalt.gross').attr('id') );
						}
					}

					// Die Werte überschreiben, wenn sie aus der Datenbank geladen wurden
					if (ladeDatenVomHash) {
						var suche = $('#suche').data();
						suche.sortierungnach = d.sortierungnach;
						suche.sortierungrichtung = d.sortierungrichtung;
						suche.art = d.art;
						suche.unterkategorien = d.unterkategorien;
						suche.anbieter = d.anbieter;
						suche.typ = d.typ;
						suche.schwerpunkt = d.schwerpunkt;
						suche.ort = d.ort;
						suche.beginn = d.beginn;
						suche.form = d.form;
						suche.sprache = d.sprache;
						suche.kosten.typ = d.kosten.typ;
						suche.kosten.von = d.kosten.von;
						suche.kosten.bis = d.kosten.bis;
						suche.dauer.typ = d.dauer.typ;
						suche.dauer.von = d.dauer.von;
						suche.dauer.bis = d.dauer.bis;

						bw.suche.setSortierung();

						bw.suche.setBeginn();
						bw.suche.setDauer();
						bw.suche.setKosten( $('#kosten--'+suche.kosten.typ) );
						bw.suche.setMultiSelect();
						bw.suche.setOrt();
					}
				}
			});
		} // Ende bw.suche.suchen
	}, // Ende bw.suche


	//
	//  Die Suchkarte
	//
	suchkarte: {
		init: function () {
			// Toggle der Liste mit den verschiedenen Kategorien
			$('.suchkarte .filter .titel a').unbind('click').click(function () {
				$('.suchkarte .filter .optionen').slideToggle(400);
				$(this).toggleClass('runter');
				return false;
			});

			// Klick auf eine der Kategorien
			$('.suchkarte .filter .optionen input').unbind('click').click(function () {
				$('#suchkarte').data('kategorie', $(this).val());
				$('.suchkarte .filter .optionen').slideUp(400);
				$('.suchkarte .filter .titel a').addClass('runter').html( $(this).parent().children('label').html() );
				bw.suchkarte.setOrt();
				bw.suchkarte.getMarker();
			});

			// Die erste Kategorie wird als Default gesetzt
			// var ersteOption = $('.suchkarte .filter .optionen input:first');
			// $('#suchkarte').data('kategorie', ersteOption.val() );
			// ersteOption.prop('checked', true);

			bw.suchkarte.setOrt();
			bw.karte.initGross('suchkarte');
		}, // Ende bw.suchkarte.init

		// Sucht nach dem gewählten Ort und der gewählten Kategorie und liefert die Marker für die Suchkarte.
		getMarker: function () {
			// Ajax-Request abschicken
			$.ajax({
				url:location.pathname,
				data: "eID=anbieterAnOrt&ort="+$('#as-values-ortSuchkarteInput').val()+"&kategorie="+$('#suchkarte').data('kategorie'),
				dataType: "json",
				type: "POST",
				cache: false,
				beforeSend: function() {
					// Ladebilder entfernen
					bw.zeug.ladeBildEntfernen('#suchkarte');

					// Blende die Ladegrafiken ein
					bw.zeug.ladeBild( $('#suchkarte') );
				},
				error: function(XHR, status) {
					// Ladebilder entfernen
					bw.zeug.ladeBildEntfernen('#suchkarte');
					// $(".suchformularBox .fussZeile").prepend('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
				},
				success: function(d) {
					// Suche an die Sucheseite mit der ermittelten Hash-ID schicken
					var suchkarte = $('#suchkarte');
					suchkarte.data('markers', d.markers);
					if (d.ort) {
						suchkarte.data('lat', d.ort.latitude);
						suchkarte.data('lng', d.ort.longitude);
						suchkarte.data('zoom', d.ort.zoom);
					} else {
						suchkarte.data('lat', suchkarte.data('defaultlat'));
						suchkarte.data('lng', suchkarte.data('defaultlng'));
						suchkarte.data('zoom', suchkarte.data('defaultzoom'));
					}

					bw.karte.initGross('suchkarte');
				}
			});

		}, // Ende bw.suchkarte.getMarker

		setOrt: function () {
			// Programmort wird erzeugt und mit werten gefüllt.
			// Erstellt eine Kopie, und löscht die alte, damit die preFill-Werte auch angezeigt werden.
			$("#ortSuchkarte").remove();
			$("#ortSuchkarteVorlage").clone().insertBefore("#ortSuchkarteVorlage").attr("id", "ortSuchkarte").show();
			$("#ortSuchkarteVorlage").hide();

			var ort = $('#suchkarte').data('ort');
			$('#ortSuchkarte input').autoSuggest(location.pathname, {
				extraParamsBefore: "eID=autocompleteOrt&",
				extraParams: "&portal="+$('#suchkarte').data('portal')+"&kategorie="+$('#suchkarte').data('kategorie'),
				asHtmlID: "ortSuchkarteInput",
				selectedItemProp: "name",
				preFill: ort,
				searchObjProps: "name",
				startText: $('#ortSuchkarte input').data('starttext'),
				emptyText: "Keine Ergebnisse gefunden",
				limitText: "Es dürfen keine weiteren Orte mehr hinzugefügt werden",
				keyDelay: 200,
				selectionLimit: 1,
				resultClick: function(d) {
					$('#suchkarte').data('ort', new  Array(d.attributes) );
				},
				selectionAdded: function(e) {
					$("#ortSuchkarteInput").css("width","75px");
					if ($('#suchkarte').data('kategorie')) {
						$('.suchkarte .filter .optionen').slideUp(400);
						$('.suchkarte .filter .titel a').addClass('runter').html( $('.suchkarte .filter .optionen input:checked').parent().children('label').html() );
					}
					bw.suchkarte.getMarker();
				},
				selectionRemoved: function(e) {
					e.remove();
					$("#ortSuchkarteInput").css("width","220px");
					$('#suchkarte').data('ort', '');
					bw.suchkarte.getMarker();
				},
				formatList: function(d, e) {
					var newE = e.html("<b>" + d.name + "</b> <span class='as-result-item-note'>" + d.element_von + "</span>");
					return newE;
				},
				resultGroups: true,
				resultGroupProp: "typ",
				matchFirst: true
			});
			if (ort) {$("#ortSuchkarteInput").css("width","75px");}
		} // Ende bw.suchkarte.setOrt
	}, // Ende bw.suchkarte


	//
	// Die Tabs
	//
	tabs: {
		init: function () {
			$('ul.tabs a').unbind('click').click(function () {
				bw.tabs.klick( $(this) );
				return false;
			});
		}, // Ende bw.tabs.init

		klick: function (tab) {
			// Alle Tabs verlieren die Klasse aktiv, der übergebene bekommt die aktive Klasse
			tab.parents('.tabContainer').find('ul.tabs li').removeClass('aktiv');
			tab.parent('li').addClass('aktiv');
			// Alle Tab-Inhalte werden versteckt und nur der Inhalt des übergebenen Tabs wird eingeblendet
			var tabInhalt = tab.attr('href');
			$(tabInhalt).fadeIn(200);
			tab.parents('.tabContainer').find('.tabInhalt:not('+tabInhalt+')').hide();
		}, // Ende bw.tabs.klick

		initTabLink: function () {
			// Bei einem Klick auf einen Tab mit der Klasse tabLink wird ein Klick auf den angegebenen Tab ausgelöst und zum TabContainer gescrollt.
			$('.tabLink').unbind('click').click(function () {
				var tab = $( $(this).data('tab') );
				bw.tabs.klick( tab );
				$(window.opera?'html':'html, body').delay(30).animate({scrollTop: tab.parents('.tabContainer').offset().top - 20},500);
				return false;
			});
		}
	}, // Ende bw.tabs


	//
	//  Die Tippbox auf der Startseite
	//
	tippBox: {
		init: function () {
			// Scrollbars aktivieren
			bw.scrollBar.init();

			// Slideshow aktivieren
			bw.slideshow.init();
		}
	},


	//
	//  Toggle (ein- und ausklappen) von Elementen
	//
	toggle: {
		// Alle Links mit der Klasse toggle klappen die Elemente aus oder ein, welche im data-selektor angegeben sind.
		// Ist kein Selektor angegeben, wird das Element mit der Klasse toggleInhalt geklappt, welches im gleichen Elternelement steckt.
		// Link-Beispiel: <a href="" class="toggle" data-selektor='#listeProgramme .liste'></a>
		init: function() {
			$('a.toggle').unbind('click').click(function() {
				var elem = $(this);
				var selektor = (elem.data('selektor')) ? elem.data('selektor') : elem.parent().find('.toggleInhalt');
				$( selektor ).slideToggle('400', function() {
					// Den nach-oben-Link aktualisieren.
					bw.zeug.nachObenLinkAkt();

					var text = '';
					if ( $( selektor ).is(':visible') ) {
						text = elem.data('verstecke');
					} else {
						text = elem.data('zeige');
					}
					elem.find('.text').html( text );
				});
				bw.toggle.aktLink( elem );
				return false;
			});
		}, // Ende bw.toggle.init

		aktLink: function (elem) {
			// Die Pfeile bekommen entweder die Klasse hoch oder runter. Das Elternelement bekommt entweder die Klasse ausklappen oder einklappen.
			elem.toggleClass('hoch runter').parents('.toggleContainer').toggleClass('ausklappen einklappen');
		}, // Ende bw.toggle.aktLink

		karte: {
			init: function (karteID) {
				$('a.toggleKarte').parent().show();
				$('a.toggleKarte').unbind('click').click(function() {
					var link = $(this);
					var karte = $( link.data('selektor') );
					if ( karte.hasClass('gross') ) {
						// Karte zuklappen
						bw.toggle.karte.statisch(link, karte, karteID);
					} else {
						// Karte aufklappen
						bw.toggle.karte.gross(link, karte, karteID);
					}
					return false;
				});
			}, // Ende bw.toggle.karte.init

			gross: function (link, karte, karteID) {
				karte.animate({height: karte.data('hoehegross')}, function() {bw.karte.initGross(karteID);}).addClass('gross');
				bw.toggle.aktLink(link);
				link.find('.text').html( link.data('verstecke') );

				// Marker laden, wenn ein AJAX-Ziel gesetzt ist. Wenn diese geladen sind, die Karte nochmal initialisieren.
				if (karte.data('ziel') !== undefined) {
					// Ajax-Request abschicken
					$.ajax({
						url: karte.data('ziel'),
						data: karte.data('params'),
						dataType: "json",
						type: "GET",
						cache: false,
						beforeSend: function() {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen(karteID);

							// Blende die Ladegrafiken ein
							bw.zeug.ladeBild(karte);
						},
						error: function(XHR, status) {
							// Ladebilder entfernen
							bw.zeug.ladeBildEntfernen(karteID);
							// liste.html('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');
						},
						success: function(data) {
							// Karte aktualisieren
							karte.data('markers', data);
							bw.karte.initGross(karteID);
						}
					});
				}
			}, // Ende bw.toggle.karte.gross

			statisch: function (link, karte, karteID) {
				karte.animate({height: karte.data('hoehestatisch')}, function() {bw.karte.initStatisch(karteID);}).removeClass('gross');
				bw.toggle.aktLink(link);
				link.find('.text').html( link.data('zeige') );
			} // Ende bw.toggle.karte.statisch
		}, // Ende bw.toggle.karte

		suchformular: function () {
			$('a.toggleSuchformular').unbind('toggle').toggle(function() {
				// Suchformular ausklappen
				var suchformular = $(this).parents('.suchformular');
				// Suchformular bekommt eine fixe Höhe, damit sich die Box nicht mehr ändert.
				suchformular.css('height', suchformular.height()).find('.suchformularBox').css({'position': 'absolute', 'margin-top': '-13px'});
				// Alle anderen Elemente in der Hauptspalte werden etwas ausgeblendet
				suchformular.parent('.inhaltBreit').css('position', 'relative').prepend('<div class="ausblenden"></div>');
				$( $(this).data('selektor') ).slideDown(400);
				$(this).find('.text').html( $(this).data('verstecke') );
				return false;
			}, function() {
				// Suchformular wieder einklappen. Das ausgeblendete entfernen
				$( $(this).data('selektor') ).slideUp(400, function () {$('.ausblenden').remove();});
				$(this).find('.text').html( $(this).data('zeige') );
				return false;
			});
		} // Ende bw.toggle.suchformular
	}, // Ende bw.toggle

	//
	//  Volltextsuche
	//
	volltext: {
		init: function() {
			bw.merkzettel.initMerken(); // Das Merken initialisieren
			bw.popup.init();
			bw.toggle.karte.init('suchergebnisKarte'); // Das ein- und ausklappen der Karte starten

			var suche = $('#suche');
			var aktualisiere = false;
			var hashVars = bw.zeug.getHashVars();

			// Wenn im Hash eine andere Query gesetzt ist
			if (typeof(hashVars.q) === 'string' && hashVars.q !== suche.data('query')) {
				suche.data('query', hashVars.q);
				aktualisiere = true;
			}

			// Wenn im Hash eine andere Seite gesetzt ist
			if (typeof(hashVars.seite) === 'string' && hashVars.seite !== suche.data('seite')) {
				suche.data('seite', hashVars.seite);
				aktualisiere = true;
			}

			// Wenn etwas im Hash anders ist, dann aktualisiere die Ergebnisliste
			if (aktualisiere === true) {
				bw.volltext.aktListe();
			}

			$('.paginierung a').unbind('click').live('click', function(e) {
				e.preventDefault();

				// Seite setzen
				suche.data('seite', $(this).attr('rel'));
				bw.volltext.aktListe(function(err, suche) {
					if (!err) {
						// Nach oben scrollen
						$(window.opera?'html':'html, body').animate({scrollTop: suche.find('.liste').offset().top - 40},500);
					}
				});
			});
		}, // Ende bw.volltext.init

		aktListe: function(callback) {
			var suche = $('#suche');
			var listeSelektor = '#suche .liste';
			var liste = $(listeSelektor);

			// Ajax-Request abschicken
			$.ajax({
				url: suche.data('ziel'),
				data: "q="+suche.data('query')+"&seite="+suche.data('seite'),
				dataType: "json",
				type: "GET",
				cache: false,
				beforeSend: function() {
					// Ladebilder entfernen
					bw.zeug.ladeBildEntfernen(listeSelektor);

					// Blende die Ladegrafiken ein
					bw.zeug.ladeBild(liste);
				},
				error: function(XHR, status) {
					// Ladebilder entfernen
					bw.zeug.ladeBildEntfernen(listeSelektor);
					liste.html('<div class="info error">Error! Type: ' + status + '<br />HTTP status: ' + XHR.status + '</div>');

					if (typeof(callback) === 'function') {
						callback(status, null);
					}
				},
				success: function(data) {
					// Hash neu setzen
					bw.zeug.setHashVar('seite', suche.data('seite'));

					// Liste aktualisieren
					liste.html(data.liste);
					$('#suchfeld-volltext').val(data.query);
					suche.find('h1').html(data.sucheVolltextTitel);
					suche.find('.kopf .gezeigteErgebnisse').html(data.gezeigteErgebnisseInfo);

					if (typeof(callback) === 'function') {
						callback(null, suche);
					}
				}
			});
		} // Ende bw.volltext.aktListe
	},

	//
	//  Zeug. Krimskrams. Verschiedene Sachen.
	//
	zeug: {
		// Verschiebt das übergebene Element in sichtbaren Bereich ist, wenn nicht komplett sichtbar.
		// Gibt true oder false zurück. Je nachdem.
		ansichtAkt: function(elem, dauer) {
			// Top und Bottom des Fensters
			var docViewTop = $(window).scrollTop();
			var docViewBottom = docViewTop + $(window).height();
			// Top und Bottom des Elements
			var elemTop = $(elem).offset().top - 20;
			var elemBottom = elemTop + $(elem).height() + 40;
			// Muss die Ansicht aktualisiert werden?
			if ((elemBottom >= docViewTop) && (elemTop <= docViewBottom) && (elemBottom <= docViewBottom) &&  (elemTop >= docViewTop) ) {
				return false; // Das Element ist komplett sichtbar, die Ansicht muss nicht aktualisiert werden.
			} else {
				var topWert = elemTop; // Das Element schaut oben raus, muss etwas nach unten geschoben werden.
				if ((elemTop >= docViewTop)) {
					topWert = (elemBottom - $(window).height()); // Das Element schaut unten raus, muss etwas nach oben geschoben werden.
				}

				// Scrolle das Fenster an die richtige Position
				$(window.opera?'html':'html, body').animate({scrollTop: topWert}, dauer);
				return true;
			}
		}, // bw.zeug.ansichtAkt

		// Liefert alle Hash-Werte zurück
		getHashVars: function() {
			var vars = {}, hash;
			var hashes = window.location.hash.slice(1).split('&');
			for(var i = 0; i < hashes.length; i++) {
				hash = hashes[i].split('=');
				if (hash[0].length > 0) {
					vars[hash[0]] = hash[1];
				}
			}
			return vars;
		}, // bw.zeug.getUrlHashVars

		// Einen Wert aus dem Hash zurückgeben
		getHashVar: function(name) {
			return bw.zeug.getHashVars()[name];
		}, // bw.zeug.getUrlHashVar

		// Einen Wert in den Hash setzen. Die bestehenden bleiben erhalten
		setHashVar: function(name, wert) {
			var vars = bw.zeug.getHashVars(), hash, hashes = [];
			vars[name] = wert;
			$.each(vars, function(varName, varWert) {
				hash = varName+'='+varWert;
				hashes.push(hash);
			});
			window.location.hash = hashes.join('&');
		}, // bw.zeug.getUrlHashVar

		// Ein LadeBild, wenn irgendwas Passiert.
		ladeBild: function (elem) {
			elem.append('<div class="ladeBild"><img src="http://bwebstatic.de/pix/lightbox/lightbox-ico-loading.gif" /></div>');
		}, // Ende bw.zeug.ladeBild

		ladeBildEntfernen: function (elem) {
			$('.ladeBild', elem).remove();
		}, // Ende bw.zeug.ladeBildEntfernen

		nachObenLinkAkt: function () {
			if ($(window).scrollTop() > (400)) {
				// nOLink = nachObenLink
				var nOLink = $('#nachOben');
				// Der Link soll in der rechten Spalte mittig angezeigt werden. 345 ergibt sich aus: Inhalt.width / 2 - rechteSpalte.width / 2
				nOLink.not('.sichtbar').addClass('sichtbar').css('margin-left', (345 - (nOLink.width() / 2))).fadeIn('500');
				// Wenn man ganz unten ist, soll er über dem Footer erscheinen, anstatt ihn zu verdecken.
				var docBottom = ($(window).scrollTop()) + ($(window).height());
				var footerTop = $('.footer').offset().top;
				if (docBottom > footerTop) {nOLink.css('bottom', docBottom - footerTop);} else {nOLink.css('bottom', '0px');}
			} else {
				$('#nachOben.sichtbar').removeClass('sichtbar').fadeOut('500');
			}
		}, // Ende bw.zeug.nachObenLinkAkt

		// Setzt das Favicon neu
		setFavicon: function () {
			var link = $('link[rel="shortcut icon"]').remove().attr("href");
			$('<link href="'+ link +'" rel="shortcut icon" type="image/x-icon" />').appendTo('head');
		}, // Ende bw.zeug.setFavicon

		// Hebe ein Element als Box hervor. Blende im Hintergrund ein Overlay ein.
		setzeHighlight: function ( selektor ) {
			$(selektor).before('<div class="overlay" style="display: none;"></div>').addClass('boxHighlight');
			// IE kleiner 9 hat leider ein Problem mit dem faden von transparenten Ebenen.
			if ( $.browser.msie && (parseInt($.browser.version, 10) < 9) ) {
				$(selektor+', .overlay').show();
			} else {
				$(selektor+', .overlay').fadeIn('400');
			}

			$(selektor+', .overlay').mousewheel(function(e, delta) {
				if ( $(selektor).hasClass('versteckt') ) { return false; }
			});

			// Beim Klick auf den Schließen-Button wird die Box und das Overlay ausgeblendet.
			$(selektor).delegate('.beenden, .beendenButton', 'click', function () {
				bw.zeug.entferneHighlight();
				return false;
			});
		}, // Ende bw.zeug.setzeHighlight

		// Blende das Overlay und die Box aus.
		entferneHighlight: function () {
			$('.boxHighlight.versteckt:visible').fadeOut('400');
			$('.overlay').fadeOut('400', function () {
				$('.overlay').remove();
				$('.boxHighlight').removeClass('boxHighlight');
				$('.newsletterFormularBox').addClass('versteckt');
			});
		} // Ende bw.zeug.entferneHighlight
	} // Ende bw.zeug
};


 function log(message){
    if (console.log) {
		console.log(message);
    } else {
		alert(message);
   }
}

