if (!("console" in window) || !("firebug" in console)) {
	var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
	"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

	window.console = {};
	for (var i = 0; i < names.length; ++i)
		window.console[names[i]] = function() {}
}




// ******************************************************************************
// Global Constants and Variables
// ******************************************************************************

var baseURL = document.getElementsByTagName('base')[0].href;



// ******************************************************************************
// Main Classes
// ******************************************************************************
var GeoSearch = Class.create();
GeoSearch.prototype = {
	// ******************************************************************************
	// Constants
	// ******************************************************************************
	Version : '0.8',
	listContainer : 'ajaxContainer',

	mapCenterLatDefault : 51.06901665960392,
	mapCenterLngDefault : 10.37109375,
	mapZoomDefault : 5,

	minZoom : 5,
	maxZoom : 19,
	zoomMap : new Array(null,6,7,10,10,14,15,15,15, 15),

	resultListSorting : 'postcode',
	resultListOffset : 0,

	imagePath : baseURL + 'fileadmin/template/main/pix/map/',

	errorMsg : {
		wrongAddress : new Template('<h2>Unbekannte Adresse</h2><p>Ihre Suche nach "#{sword}" ergab keine geografische Übereinstimmung.</p><br><p>Vorschläge:</p><br><ul><li>Überprüfen Sie die Schreibweise.</li><li>Probieren Sie andere Suchbegriffe aus.</li><li>Probieren Sie allgemeinere Begriffe aus.</li></ul>'),
		suggest : new Template('<h2>Meinten Sie</h2><div style="overflow:auto">#{list}</div>')
	},

	knotWidth : 9,
	sliderBackOffset : -28,

	// dom ids
	searchFormId : 'geoSearchForm',

	resultListSearchFormId : 'searchForm',
	resultListContainerId : 'resultListContainer',
	resultListLoadingId : 'gs_loading_resultList',
	resultListLoadingWrapId : 'gs_loadingWrap_resultList',

	notifyId : 'gs_notify',

	modalBlockerId : 'gs_blocker',
	modalDialogId : 'gs_modal',
	modalDialogContentId : 'gs_modal_content',
	modalDialogCloseId : 'gs_modal_close',

	modalLoadingId : 'gs_loading',

	toolbarMapSwitchType1 : 'gc_option_0',
	toolbarMapSwitchType2 : 'gc_option_1',
	toolbarDragzoom : 'gc_dragzoom',
	toolbarZoomplus : 'gc_zoomplus',
	toolbarZoomminus : 'gc_zoomminus',
	toolbarReset : 'gc_reset',

	toolbarSliderId : 'gc_zoomslider',
	toolbarSliderRailId : 'gc_zoomsliderrail',
	toolbarSliderKnobId : 'gc_zoomsliderknob',

	map : null,
	mapCenterLat : null,
	mapCenterLng : null,
	mapZoom : null,
	mapRestore : false,

	immoBubble : null,
	clusterBubble : null,
	clusterer : null,
	geocoder : null,
	icons : {},
	activeSearchPoint : null,
	activeSearchString : null,
	activeMarker : null,
	nza : {
		buero : 0,
		praxisraeume : 0,
		handel : 0,
		gastronomie : 0,
		produktion : 0,
		werkstatt : 0,
		lager_innen : 0,
		freiflaechen : 0,
		labor : 0,
		callcenter : 0,
		bildungseinrichtungen : 0,
		wohnen : 0
	},
	duplicateAddressMap : [],

	// dom Elements
	form : null,
	searchForm : null,
	filterForm : null,
	resultListContainer : null,

	resultListParam : '',
	sword : '',

	// ******************************************************************************
	// Constructor
	// ******************************************************************************
	initialize: function(options) {
		if((typeof Prototype=='undefined') ||
		(typeof Element == 'undefined') ||
			(typeof Element.Methods=='undefined') ||
			parseFloat(Prototype.Version.split(".")[0] + "." +
					Prototype.Version.split(".")[1]) < 1.5)
				throw('Die Google Maps Immobiliensuche benötigt das Prototype JavaScript framework >= 1.5.0');

		if (GBrowserIsCompatible() == false) {
			throw('Die Google Maps Immobiliensuche');
		}

		this.options = {
			duration: .50,
			opacity: 0.75,
			overlayHTML: '<div id="#{overlayObjId}" class="#{overlayClass}" style="display:none"></div>',
			autoDestroy: true
		};
		Object.extend(this, options);

		document.observe("dom:loaded",
			this.pageLoadHandler.bindAsEventListener(this)
		);
		//Event.onReady(this.pageLoadHandler.bindAsEventListener(this));
	},


	pageLoadHandler: function() {
		that = this;

		// init Map
		this.map = new GMap2(document.getElementById('gs_map_canvas'));
		//this.map.addControl(new GLargeMapControl());
		//this.map.addControl(new GOverviewMapControl());
		//this.map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(5, 5)));

		if(this.mapRestore == false) {
			this.mapCenterLat = this.mapCenterLatDefault;
			this.mapCenterLng = this.mapCenterLngDefault;
			this.mapZoom = this.mapZoomDefault;
			this.map.setCenter(new GLatLng(this.mapCenterLat, this.mapCenterLng) , this.mapZoom);

		} else {
			this.map.setCenter(new GLatLng(this.mapCenterLat, this.mapCenterLng) , this.mapZoom);
		}
		// init geocoder

		var sw = new GLatLng(47.33882269482199, 5.6689453125);
		var ne = new GLatLng(54.876606654108684, 15.5126953125);

		var bounds = new GLatLngBounds(sw, ne);

		this.geocoder = new GClientGeocoder();
		this.geocoder.setBaseCountryCode('de');
		this.geocoder.setViewport(bounds);


		// init icons
		icon1 = new GIcon();
		icon1.image = this.imagePath  + 'icon_map_single.png';
		icon1.iconSize = new GSize(20, 20);
		icon1.iconAnchor = new GPoint(8, 7);
		icon1.infoWindowAnchor = new GPoint(18, 27);
		//icon1.shadow = this.imagePath  + 'shadowImmo.png';
		//icon1.shadowSize = new GSize(22, 15);
		this.icons.immo = icon1;

		icon2 = new GIcon();
		icon2.image = this.imagePath  + 'icon_map_multi.png';
		icon2.iconSize = new GSize(28, 27);
		icon2.iconAnchor = new GPoint(10, 10);
		icon2.infoWindowAnchor = new GPoint(8, 8);
		//icon2.shadow = this.imagePath  + 'shadowCluster.png';
		//icon2.shadowSize = new GSize(26, 20);
		this.icons.immoCluster = icon2;


		icon3 = new GIcon();
		icon3.image = this.imagePath + 'pin.gif';
		icon3.iconSize = new GSize(46, 48);
		icon3.iconAnchor = new GPoint(9, 47);
		//icon3.infoWindowAnchor = new GPoint( 11, 11);
		//icon3.shadow = this.imagePath  + 'shadowPin.png';
		//icon3.shadowSize = new GSize(46, 48);
		this.icons.center = icon3;
		this.clusterBubble = new EBubble(this.map, new GSize(320,170), new GPoint(50,220));
		this.immoBubble = new EBubble(this.map, new GSize(300,130), new GPoint(52,180));

		this.clusterer = new Clusterer(this.map, this.icons.immoCluster, this.clusterBubble, {
			maxVisibleMarkers : 10,
			gridSize : 10,
			minMarkersPerClusterer : 3,
			maxLinesPerInfoBox : 6
		});

		this.resultListContainer = $(this.resultListContainerId);

		// ******************************************************************************
		// events
		// ******************************************************************************

		// mapTypeSwitch
		Event.observe(this.toolbarMapSwitchType1, 'click', this.switchMapType.bindAsEventListener(this, 0), false);
		Event.observe(this.toolbarMapSwitchType2, 'click', this.switchMapType.bindAsEventListener(this, 1), false);
		// Reset
		Event.observe(this.toolbarReset, 'click', this.reset.bindAsEventListener(this), false);
		// zoom
		Event.observe(this.toolbarZoomplus, 'click', this.zoom.bindAsEventListener(this, 1), false);
		Event.observe(this.toolbarZoomminus, 'click', this.zoom.bindAsEventListener(this, -1), false);

		// zoomSlider
		Event.observe(this.toolbarSliderId, 'click', this.toolbarSliderOnClick.bindAsEventListener(this), false);
		this.slide = new GDraggableObject($(this.toolbarSliderKnobId), {container: $(this.toolbarSliderRailId)});
		GEvent.addListener(this.slide, 'drag', this.toolbarSliderOnDrag.bind(this));
		GEvent.addListener(this.slide, 'dragend', this.toolbarSliderOnDragend.bind(this));
		GEvent.addListener(this.map, 'zoomend', this.toolbarSliderOnUpdate.bind(this));

		// Search und filter form
		this.searchForm = $(this.searchFormId);
		Event.observe(this.searchForm,'submit', this.submitHandler.bindAsEventListener(this), false);

		$$('#geoFilterForm input').each(function(elm){
			Event.observe(elm, 'click', that.changeFilterHandler.bindAsEventListener(that), false);
		});
		// load wes
		new Ajax.Request(baseURL + 'fileadmin/template/main/json/objectData.js?cache=0', {onSuccess: this.loadWes.bind(this), method: 'get'});
	},


	loadWes : function(transport, json)	{


	var json = transport.responseText.evalJSON(true);
	this.wes = json.wes.we;

	// wegen firefox muss nochmal geprüft werden welche checkboxen nach dem RELOAD aktiv sind
	that = this;
	$$('#geoFilterForm input').each( function(elm){
			that.nza[elm.value] = elm.checked;
	});

		this.wes.each(this.addMarker.bind(this));

		GEvent.addListener(this.map, "moveend", this.drawResultListStartTimmer.bind(this));

		$(this.modalBlockerId).hide();
		$(this.modalLoadingId).hide();

		if(this.mapRestore == true) {
			//this.drawResultList();
			this.resultListSetPage();
			this.toolbarSliderOnUpdate(this.mapCenterLatDefault,  this.mapZoom);
		}

		// externe suche von dti_www
		if(this.searchForm.extern.value == 'true'){
			this.submitHandler(false);
			this.changeFilterHandler(false);
		}

	},

	onMapLoad : function()
	{
		$('gs_blocker').hide();
	},



	switchMapType : function(ev, type)
	{
		Event.stop(ev);
		if(type == 0){

			this.map.setMapType(G_NORMAL_MAP);

			$(this.toolbarMapSwitchType1).addClassName('gc_textbutton-active');
			$(this.toolbarMapSwitchType2).removeClassName('gc_textbutton-active');

		} else if (type == 1){

			this.map.setMapType(G_HYBRID_MAP);

			$(this.toolbarMapSwitchType2).addClassName('gc_textbutton-active');
			$(this.toolbarMapSwitchType1).removeClassName('gc_textbutton-active');
		} else{

			this.map.setMapType(G_PHYSICAL_MAP);

			$(this.toolbarMapSwitchType1).addClassName('gc_textbutton-active');
			$(this.toolbarMapSwitchType2).removeClassName('gc_textbutton-active');
		}
	},

	dragZoom : function(ev)
	{
		Event.stop(ev);
	},

		zoom : function(ev, value)
	{
		Event.stop(ev);

		zoom = this.map.getZoom() + value;

		if(zoom < this.minZoom) zoom = this.minZoom;
		if(zoom > this.maxZoom) zoom = this.maxZoom;

		if(zoom != this.map.getZoom()){
			this.map.setZoom(zoom);
		}
	},

	// ***********************************************************************************************
	// slider functionen
	// ***********************************************************************************************
	toolbarSliderOnDrag : function()
	{
		this.sliderDragFlag = true;

		sliderLength = $(this.toolbarSliderRailId).getDimensions().width - this.knotWidth;

		sliderLeft = sliderLength - parseInt($(this.toolbarSliderKnobId).positionedOffset()[0]);

		// slider Back Pos
		$(this.toolbarSliderId).style.backgroundPosition = (this.sliderBackOffset - sliderLeft) + 'px';
	},

	toolbarSliderOnDragend : function()
	{
		sliderLength = $(this.toolbarSliderRailId).getDimensions().width - this.knotWidth;
		sliderLeft = sliderLength - parseInt($(this.toolbarSliderKnobId).positionedOffset()[0]);

		// slider Back Pos
		var z = this.minZoom + Math.round(sliderLeft * (this.maxZoom-this.minZoom) / sliderLength);

		that = this;
		window.setTimeout( function(){that.sliderDragFlag = false}, 1000 )

		this.map.setZoom(z);
	},

	toolbarSliderOnUpdate : function(oldLevel,  newLevel)
	{
		if (newLevel > this.maxZoom) {
			z = this.maxZoom;
		} else if(newLevel < this.minZoom){
			z = this.minZoom;
		} else {
			z = this.map.getZoom();
		}
		sliderLength = $(this.toolbarSliderRailId).getDimensions().width - this.knotWidth;

		var sliderLeft = Math.round((sliderLength) / (this.maxZoom-this.minZoom) * (z-this.minZoom));

		point = new GPoint($(this.toolbarSliderKnobId).style.left = (sliderLength-sliderLeft), 0);
		this.slide.moveTo(point)

		// slider Back Pos
		$(this.toolbarSliderId).style.backgroundPosition = (this.sliderBackOffset - sliderLeft) + 'px';
	},

	toolbarSliderOnClick : function(ev)
	{
		ev.stop();

		if(this.sliderDragFlag == true) return;

		sliderLength = $(this.toolbarSliderRailId).getDimensions().width - this.knotWidth;
		sliderLeft = sliderLength - (ev.pointerX() - ev.element().cumulativeOffset()[0]);
		var z = this.minZoom + Math.round(sliderLeft * (this.maxZoom-this.minZoom) / sliderLength);

		this.map.setZoom(z);

	},

	reset : function(ev)
	{
		ev.stop();

		this.searchForm.search.value = '';
		this.sword = '';

		// entfernen des activen distans kreis.
		if(this.activeMarker != null){
			this.map.removeOverlay(this.activeMarker);
		}
		this.activeSearchPoint = null;

		this.map.setCenter(new GLatLng(this.mapCenterLatDefault, this.mapCenterLngDefault), this.mapZoomDefault);
	},


	submitHandler : function(ev)
	{
		if(ev) ev.stop();

		address = this.searchForm.search.value;
		if(address != '')
		{
			this.sword = address;

			// test für Postleitzahlen bereich
			var res = address.match(/^[0-9]{1,4}$/);
			if(res){
				this.postcodecoder(address);
			} else {
				// Adress optimierung
				address = address.replace(/ ?deutschland ?| ?germany ?/gi, '') + ', Germany';
				this.geocoder.getLocations(address, this.getLocations.bind(this));
			}
		}
	},

	changeFilterHandler : function(ev)
	{
		that = this;
		$$('#geoFilterForm input').each( function(elm){
			that.nza[elm.value] = elm.checked;
		});
		this.duplicateAddressMap = new Array();
		this.clusterer.clearClusters();
		this.wes.each(this.addMarker.bind(this));

		this.drawResultListStartTimmer();
	},

	getLocations : function(response)
	{
		console.info(response);
		statusCode = response.Status.code;
		if(statusCode == 200){
			placemarks = response.Placemark;
			var temp_placemarks = new Array();
			for (var i = 0; i < placemarks.length; i++) {
				try {
					if (placemarks[i].AddressDetails.Country.CountryNameCode == 'DE') {
						temp_placemarks.push(placemarks[i]);
					}
				} catch(e) {
					temp_placemarks.push(placemarks[i]);
				}
			}
			this.placemarks = temp_placemarks;

			if (this.placemarks.length == 0) {
				var content = this.errorMsg.wrongAddress.evaluate({sword : this.searchForm.search.value});
				this.modalDialog(content);
			} else {
				if (this.placemarks.length > 1) {
					var list = '';
					for (var i = 0; i < this.placemarks.length; i++) {
						l = this.placemarks[i].address.replace(/, Germany|, Bundesrepublik Deutschland|, Deutschland|Deutschland/, '')
						try {
							l += ', ' + this.placemarks[i].AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
						} catch(e) {}
						list += '<p><a href="#" onclick="myGeoSearch.showDialogLocation('+ i +');return false">' + l + '</a></p>';
					}
					var content = this.errorMsg.suggest.evaluate({list : list});
					this.modalDialog(content);
				} else {
					this.showPlacemark(this.placemarks[0]);
				}
			}
		} else {
			var content = this.errorMsg.wrongAddress.evaluate({sword : this.searchForm.search.value});
			this.modalDialog(content);
		}

	},

	notifyShow : function(content)
	{
		$(this.notifyId).update(content);
		new Effect.Appear(this.notifyId, {from:0.0, to:1, duration: 1, afterFinish: this.notifyTimer.bind(this)});
	},
	notifyTimer : function()
	{
		window.setTimeout(this.notifyFadeOut.bind(this), 4000);
	},
	notifyFadeOut : function()
	{
		new Effect.Fade(this.notifyId, { from:1, to:0.0, duration: 1, afterFinish: this.notifyHide.bind(this) });
	},
	notifyHide : function()
	{
		$(this.notifyId).hide();
	},

	modalDialog : function(content)
	{
		$(this.modalBlockerId).show();
		$(this.modalDialogId).show();
		$(this.modalDialogContentId).update(content);
		Event.observe(this.modalDialogCloseId, 'click', this.modalDialogClose.bindAsEventListener(this), false);
	},


	modalDialogClose : function(ev)
	{
		if(ev) Event.stop(ev);
		$(this.modalBlockerId).hide();
		$(this.modalDialogId).hide();

	},

	showDialogLocation : function(placemarkId)
	{
		this.modalDialogClose(false);
		this.showPlacemark(this.placemarks[placemarkId]);

	},


	showPlacemark : function(placemark)
	{
		var accuracy = parseInt(placemark.AddressDetails.Accuracy);
		var zoom = this.zoomMap[accuracy];

		point = new GLatLng(parseFloat(placemark.Point.coordinates[1]), parseFloat(placemark.Point.coordinates[0]));

		// ExtendedData -> LatLonBox
		try {
			var LatLonBox = placemark.ExtendedData.LatLonBox;

			var swLatLng = new GLatLng(LatLonBox.south, LatLonBox.west);
			var neLatLng = new GLatLng(LatLonBox.north, LatLonBox.east);
			var bounds = new GLatLngBounds(swLatLng, neLatLng);

			zoom = this.map.getBoundsZoomLevel(bounds);
		} catch(e) {}
		this.showLocation(point, zoom);
	},


	postcodecoder : function(postcode){
		new Ajax.Request(baseURL + '?eID=postcodeToBoundary&postcode=' + postcode, {onSuccess: this.onloadPostcodeArea.bind(this)});
	},
	onloadPostcodeArea : function(transport, json)
	{
		var json = transport.responseText.evalJSON(true);
		var swLatLng = new GLatLng(json.sw.lat, json.sw.lng)
		var neLatLng = new GLatLng(json.ne.lat, json.ne.lng)

		bounds = new GLatLngBounds(swLatLng,  neLatLng);

		var zoom = this.map.getBoundsZoomLevel(bounds);
		var point = bounds.getCenter();

		this.showLocation(point, zoom);
	},

	showLocation : function(point, zoom)
	{
		// entfernen des activen distans kreis.
		if(this.activeMarker != null){
			this.map.removeOverlay(this.activeMarker);
		}
		this.activeSearchPoint = point

		// ************************************************************************************************************
		// ermiteln ob um 10 objekte erweitert werden muss
		// ************************************************************************************************************

		// schrit 1: virtuellen GBound mit hilfe von umrechnung der LatLng in PX
		var proj = G_NORMAL_MAP.getProjection();
		var centerPt = proj.fromLatLngToPixel(this.activeSearchPoint, zoom);

		this.canvasHeight = 314;
		this.canvasWidth = 578;

		swPt = new GPoint();
		swPt.x = centerPt.x - (this.canvasWidth/2);
		swPt.y = centerPt.y + (this.canvasHeight/2);

		nePt = new GPoint();
		nePt.x = centerPt.x + (this.canvasWidth/2);
		nePt.y = centerPt.y - (this.canvasHeight/2);

		swLatLng = proj.fromPixelToLatLng(swPt,  zoom);
		neLatLng = proj.fromPixelToLatLng(nePt,  zoom);

		// ************************************************************************************************************
		// schritt 2: Prüfen welche marker in dem Boundary sind
		// ************************************************************************************************************
		bounds = new GLatLngBounds(swLatLng,  neLatLng);

		var res = false;
		var x = 0;
		for(i=0;i<this.wes.length-1;i++) {
			if(this.wes[i].active == true){
				if(bounds.containsLatLng(this.wes[i].point) == true) x++;
				if(x == 1) {
					res = true;
					break;
				}
			}
		}

		if(res == false){
			var content = 'Ihr Suchergebnis wurde auf mindestens 10 Objekte erweitert.';
			this.notifyShow(content);
			this.expandToTen(bounds);
		} else {
			this.map.setCenter(this.activeSearchPoint, zoom);
		}

		this.drawResultListStartTimmer();
		return false;
	},

	expandToTen : function(bounds)
	{
		that = this;

		// Distance von mapCenter zu jeder WE berechnen
		for(var i=0; i<this.wes.length; i++) {
			we = this.wes[i];
			xx = new GLatLng(we.lat, we.lng)
			we.distance = this.activeSearchPoint.distanceFrom(xx);
		}

		// WES nach distance sortieren
		this.wesSorted = this.wes.sortBy(function(s) { return s.distance; })

		var count = 1;
		for(var i=0; i<this.wesSorted.length; i++) {
			if(count > 10) break;
			we = this.wesSorted[i];
			if(we.active == true){
				bounds.extend(we.point);
				count++;
			}

		}

		this.map.setCenter(this.activeSearchPoint, this.map.getBoundsZoomLevel(bounds));
		this.activeMarker = new GMarker(this.activeSearchPoint, {icon : this.icons.center, zIndexProcess : function(marker,b){
			z = GOverlay.getZIndex(marker.getPoint().lat()) - 10000;
			return z;
		}});

		this.map.addOverlay(this.activeMarker);
	},

	zoomToWe : function(weId, accuracy)
	{
		myGeoSearch.clusterer.PopDown();
		this.immoBubble.hide();

		this.map.setCenter(this.wes[weId].point, this.zoomMap[accuracy]);
	},

	zoomToCluster : function(weIdcvs)
	{
		myGeoSearch.clusterer.PopDown();
		this.immoBubble.hide();

		// Rahmen erstellen
		var bounds = new GLatLngBounds();
		var weIds = weIdcvs.split(',');

		for(var i=0; i < weIds.length; i++) {
			we = this.wes[weIds[i]];
			if(we.active == true) {
				bounds.extend(we.point);
			}
		}
		this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));
	},



	drawCircle : function(center, radiusPoint, color, thickness, opacity) {
		var proj = G_NORMAL_MAP.getProjection();
		var centerPt = proj.fromLatLngToPixel(center, this.map.getZoom());
		var radiusPt = proj.fromLatLngToPixel(radiusPoint, this.map.getZoom());

		//Function created by Chris Haas
		var circleQuality = 5;			//1 is best but more points, 5 looks pretty good, too
		var M = Math.PI / 180;			//Create Radian conversion constant
		var points = [];							//Init Point Array
		//Loop through all degrees from 0 to 360
		for(var i=0; i<360; i+=circleQuality){

			var radius = Math.floor(Math.sqrt(Math.pow((centerPt.x-radiusPt.x),2) + Math.pow((centerPt.y-radiusPt.y),2)));
			var P = new GPoint(
				centerPt.x + (radius * Math.sin(i * M)),
				centerPt.y + (radius * Math.cos(i * M))
			);
			points.push(proj.fromPixelToLatLng(P, this.map.getZoom()));
		}
		points.push(points[0]);	// close the circle
		circle  = new GPolygon(points, '#000000', 1, 0.2, '#000000', 0.1);
		this.map.addOverlay(circle);

		return circle;
	},


	addMarker : function(we, id)
	{
		that = this;
		alloff = $H(this.nza).all(function(n){
			if(n.value == 0) return true;
		});

		if(alloff == true){
			we.active = true;
		} else {
			we.active = $H(this.nza).any(function(n){
				if(n.value == 0) return false;
				return n.value == we.nza[n.key];
			});
		}

		if(we.active == true) {
			// obtain the attribues of each marker
			if(!we.marker){
				we.point = new GLatLng(parseFloat(we.lat), parseFloat(we.lng));

				var marker = new GMarker(we.point, this.icons.immo);
				marker.isExpand = false;
				marker.weId = id;

				thumb = we.pic;


				nzaArr = new Array();
				if(we.nza.buero == "1") {
					nzaArr.push('Büro')
				}
				if(we.nza.praxisraeume == "1") {
					nzaArr.push('Praxis')
				}
				if(we.nza.handel == "1") {
					nzaArr.push('Handel')
				}
				if(we.nza.gastronomie == "1") {
					nzaArr.push('Gastronomie')
				}
				if(we.nza.produktion == "1") {
					nzaArr.push('Produktion')
				}
				if(we.nza.werkstatt == "1") {
					nzaArr.push('Werkstatt')
				}
				if(we.nza.lager_innen == "1") {
					nzaArr.push('Lager')
				}
				if(we.nza.freiflaechen == "1") {
					nzaArr.push('Freilager')
				}
				if(we.nza.labor == "1") {
					nzaArr.push('Labor')
				}
				if(we.nza.callcenter == "1") {
					nzaArr.push('Call Center')
				}
				if(we.nza.bildungseinrichtungen == "1") {
					nzaArr.push('Bildung')
				}
				if(nzaArr.length > 3){
					nzaArr = nzaArr.slice(0,3)
					nzaText = nzaArr.join(', ')
					nzaText += ' ...';
				} else {
					nzaText = nzaArr.join(', ')
				}

				var template = new Template('<div class="gs_bubbleContent_top css-round clearfix"><div class="thumb"><img src="'+thumb+'" /></div><div class="right"><p>#{plz} #{ort}</p><p>#{str}</p><p>Gesamtfläche: <b>#{gf} m²</b></p><p>'+ nzaText +'</p></div></div><div class="gs_bubbleContent_bottom"><button class="inputSubmit" onclick="myGeoSearch.zoomToWe(' + id + ', 8);"><span><span>Ausschnitt zeigen</span></span></button></div>');

				GEvent.addListener(marker, "mouseover", function() {
					that.bubbleClearTimeout()
					that.clusterer.PopDown()
						that.immoBubble.openOnMarker(marker, template.evaluate(we));
					});
					GEvent.addListener(marker, "mouseout", function() {
						//that.immoBubble.hide();
						that.bubblePopUpTimeout()
					});
					GEvent.addListener(marker, "click", function() {
						that.immoBubble.hide();
						that.zoomToWe(id, 8);
					});
					this.immoBubble.setTimeoutFunc(this.bubblePopUpTimeout.bind(this, 10000))
					this.immoBubble.setTimeoutFunc2(this.bubblePopUpTimeout.bind(this, 1))

					GEvent.addListener(marker, "mouseover", function() {
						that.moveMarker(we, marker);
					});

				we.marker = marker;
			} else {
				//we.marker.onMap = false;
			}

			if(typeof this.duplicateAddressMap[we.lat+we.lng] == "undefined"){
				this.duplicateAddressMap[we.lat+we.lng] = new Array();
			}
			this.duplicateAddressMap[we.lat+we.lng].push(we.marker);

			this.clusterer.AddMarker(we.marker, '<a class="gs_bubble_immoListItem" href="#" onclick="myGeoSearch.zoomToWe(' + id + ', 8);return false">' + we.plz + ' ' + we.ort + ', ' + we.str + '</a>');
		} else {
			if(we.marker){
				this.clusterer.RemoveMarker(we.marker);
			}
		}
	},

	bubblePopUpTimeout : function(val){
		if(!val) val = 500;
		this.bubbleClearTimeout()
		this.timerHandler = window.setTimeout(this.hideImmoBubble.bind(this), val)
	},
	bubbleClearTimeout : function(){
		if(typeof this.timerHandler != "undefined")
			window.clearTimeout(this.timerHandler)
	},
	hideImmoBubble : function(){
		this.immoBubble.hide()
	},


	moveMarker : function(we, activemarker){
		markers = this.duplicateAddressMap[we.lat+we.lng];
		if(markers.length == 1 || this.map.getZoom() < 8) return;

		var proj = G_NORMAL_MAP.getProjection();
		var centerPt = proj.fromLatLngToPixel(activemarker.getLatLng(), this.map.getZoom());

		if(activemarker.isExpand == false){
			var radius = 20;
			var M = Math.PI / 180;
			//Loop through all markers
			for(var i=0; i<markers.length; i++){

				var marker = markers[i];
				marker.isExpand = true;
				var angle = 360/(markers.length)*i;
				var P = new GPoint(
					centerPt.x + (radius * Math.sin(angle * M)),
					centerPt.y + (radius * Math.cos(angle * M))
				);
				var newPoint = proj.fromPixelToLatLng(P, this.map.getZoom());
				marker.setLatLng(newPoint);

				marker.expandTimoutFunc = this.moveMarkerBack.bind(this, we, marker);
				marker.expandTimer = window.setTimeout(marker.expandTimoutFunc, 2000);
			}
		} else {
			for(var i=0; i<markers.length; i++){
				var marker = markers[i];
				window.clearTimeout(marker.expandTimer);
				marker.expandTimer = window.setTimeout(marker.expandTimoutFunc, 2000);
			}
		}
	},

	moveMarkerBack : function(we, marker){
		marker.setLatLng(we.point);
		marker.isExpand = false;
	},


	drawResultListStartTimmer : function()
	{
		window.clearTimeout(this.resultListTimer);
		this.resultListTimer = window.setTimeout(this.drawResultList.bind(this), 100);
	},


	drawResultList : function()
	{
		bounds = this.map.getBounds();
		wesInBound = new Array();
		var weCSV = '';
		var weIdArr = new Array();
		var x = 0;
		for(i=0;i<this.wes.length;i++){
			we = this.wes[i];
			if(we.active){
				if(bounds.containsLatLng(we.point) == true) {
					//console.info('test:' + i);
					weIdArr.push(we.uid);
				}
			}
		}
		weCSV = weIdArr.join(',');

		lat = this.map.getCenter().lat();
		lng = this.map.getCenter().lng();
		zoom = this.map.getZoom();
		param = 'send=true' +
				'&mapCenterLat=' + lat +
				'&mapCenterLng=' + lng +
				'&sword=' + this.sword +
				'&mapZoom=' + zoom +
				'&searchFormType=map';

		var nzaStr = '';
		for(n in this.nza) {
			if(this.nza[n])
				nzaStr += '&nza['+ n +']=' + this.nza[n];
		}

		param += '&wes=' + weCSV + nzaStr;


		if(this.activeSearchPoint != null){
			center = this.activeSearchPoint;
			lat = center.lat();
			lng = center.lng();

			param += '&centerLat=' + lat + '&centerLng=' + lng;
		}

		url = 'resultlist.html?' +
				'sorting=' + this.resultListSorting +
				'&offset=' + this.resultListOffset;

		if(this.resultListParam != param) {
			this.resultlistLoadingShow();

			// detach round corners and shadows for resultlist
			if(typeof pieDetach == "function") {
				pieDetach($(this.resultListContainerId));
			}

			new Ajax.Updater(
				this.resultListContainerId,
				url,
				{
					method : 'post',
					parameters : param,
					onComplete : this.drawResultListOnReady.bindAsEventListener(this),
					evalScripts : true
				}
			);
			this.resultListParam = param;
		}
	},

	drawResultListOnReady : function(ev){
		if($('resultListSortingSelect')){
			$(this.resultListContainerId).select('.resultListContainerAjax a').each(
				this.resultListBindLinks.bind(this)
			);
			Event.observe($(this.resultListSearchFormId), 'submit', this.resultListSubmitHandler.bindAsEventListener(this) , false);
			Event.observe($('resultListSortingSelect'), 'change', this.resultListChangeHandler.bindAsEventListener(this) , false);
		}
		// round corners and shadows for resultlist
		if(typeof pieAttach == "function") {
			pieAttach($(this.resultListContainerId));
		}
		this.resultlistLoadingHide();
	},

	resultListChangeHandler : function(ev){
		$(this.resultListSearchFormId).sortierungsFlag.value = true;
		this.resultListSubmitHandler(ev);

	},

	resultListSubmitHandler : function(ev)
	{
		ev.stop();
		param =  $(this.resultListSearchFormId).serialize();

		url = $(this.resultListSearchFormId).action + '?type=2';
		this.resultlistLoadingShow();
		new Ajax.Updater(
			this.resultListContainerId,
			url, {
				parameters : param,
				method : 'post',
				onComplete : this.drawResultListOnReady.bindAsEventListener(this),
				evalScripts : true
			}
		);
	},

	resultListBindLinks : function(elm)
	{
		Event.observe(elm, 'click', this.resultListLinkClickHandler.bindAsEventListener(this), false);
	},

	resultListLinkClickHandler : function(ev)
	{
		ev.stop();
		var elm = ev.element();

		url = elm.href + '&type=2';

		this.resultlistLoadingShow();
		new Ajax.Updater(this.resultListContainerId, url, {method : 'get', onComplete : this.drawResultListOnReady.bindAsEventListener(this), evalScripts : true });
	},

	resultListSetPage : function()
	{
		url = 'angebote/suchergebnisse.html?type=2';
		this.resultlistLoadingShow();
		new Ajax.Updater(this.resultListContainerId, url, {method : 'get', onComplete : this.drawResultListOnReady.bindAsEventListener(this), evalScripts : true });
	},


	resultlistLoadingShow : function(){

		h = $(this.resultListContainerId).getHeight();
		$(this.resultListLoadingWrapId).setStyle({height : h + 'px'});

		$(this.resultListLoadingWrapId).show();
		$(this.resultListLoadingId).show();

		if($('resultListSortingSelect')) $('resultListSortingSelect').hide();
	},
	resultlistLoadingHide : function(){
		$(this.resultListLoadingWrapId).hide();
		$(this.resultListLoadingId).hide();

		if($('resultListSortingSelect')) $('resultListSortingSelect').show();
	},


	// ***********************************************************************************************
	// Ajax Response Handler
	// ***********************************************************************************************
	onCreate: function(){
		Element.show(this.ajaxLoadingIconObj);
	},
	onComplete: function() {
			Element.hide(this.ajaxLoadingIconObj);
			if(ajaxUpdaterFlag == false){

			ajaxUpdaterFlag = true;
		}
	}
};
