function AktionenKarte() {
	this.map = null;
	/* MarkerManager macht Probleme, wenn man auf Marker zugreifen will, die gerade ausserhalb der Karte sind */
	this.geocoder = null;
	this.aktionenListe = null;
	this.aktionenListeHeader = null;
	
	this.aktionenToAdd = null;
	this.aktionenToAddContinueAt = 0;
	
	this.aktionenSuchresultate = null;
	this.aktionenSuchresultateIDs = null;
	
    google.load("maps", "2", {"locale" : "de_DE"});
    
    this.zoomPoints = getZoomPoints();
    this.geoIcon = null;
    
	this.aktionen = [];
	this.aktionenIds = {};
	this.spatialFilter = new SpatialFilter();
	
	this.currentHilightAktion = null;
	
	this.moveEndEvent = function() {};
	this.infoWindowShownEvent = function() {};
        this.aktionenListeHeight = 458;
	this.aktionenListeSichtbar = true;
	this.aktionenListeJemalsSichtbar = true;
}
AktionenKarte.prototype = {
        setAktionenListeHeight: function(height) {
            this.aktionenListeHeight = height;
            this.aktionenListe.style.height = height + 'px';
        },

	doLoadAktionen: function(aktionen) {
		this.spatialFilter.clear();
		this.aktionenToAdd = aktionen;
		this.aktionenToAddContinueAt = 0;
		this.doLoadAktionenCallback();
	},
	
	doLoadAktionenCallback: function() {
		var aktionen = this.aktionenToAdd;
		var end = Math.min(this.aktionenToAddContinueAt + 30, aktionen.length);
		for (var i = this.aktionenToAddContinueAt; i < end; i ++) {
			var a = new Aktion(aktionen[i], this);
			this.aktionen[i] = a;
			this.aktionenIds[a.id] = a;
			if (this.aktionenListeJemalsSichtbar)
				this.spatialFilter.addPoint(a);
			this.map.addOverlay(a.getMarker());
                        if (this.aktionenSuchresultateIDs != null) {
                            if (this.aktionenSuchresultateIDs[a.id] == null) {
                                    a.hideMarker();
                            } else if (this.aktionenSuchresultateIDs[a.id] == 1) {
                                    this.aktionenSuchresultate.push(a);
                                    this.aktionenSuchresultateIDs[a.id] = 2;
                            }
                        }

		}
		this.aktionenToAddContinueAt = i;
		this.updateAktionenListe();
		
		if (end < aktionen.length) {
			var lthis = this;
			window.setTimeout(function() { lthis.doLoadAktionenCallback();}, 10);
		} else {
			this.doLoadAktionenListe = null;
			this.doLoadAktionenListeContinueAt = 0;
		}
	},
	
	setupIcons: function() {
	    this.geoIcon = new GIcon(G_DEFAULT_ICON);
	    this.geoIcon.image = '/imgs/geomarker.png';
		this.geoIcon.iconSize = new GSize(25,53);
		this.geoIcon.iconAnchor = new GPoint(12, 51);
		this.geoIcon.infoWindowAnchor = new GPoint(12, 12);
		this.geoIcon.shadow = '/imgs/geomarkershadow.png';
		this.geoIcon.shadowSize = new GSize(39, 44);
	},
	
	registerCallbacks: function() {
		var lthis = this;
		window.onunload = function() {
			lthis.savePositionInCookie();
			google.maps.Unload();
		}
		
		this.initMap();
		this.findElements();
		
	    this.setupIcons();
	},
	
	initMap: function() {
		var lthis = this;
		
		var mapWindow = document.getElementById('mapWindow');
	    this.map = new google.maps.Map2(mapWindow);
	    this.setPositionFromCookie();
	    this.map.addControl(new google.maps.LargeMapControl());
	    this.map.addControl(new google.maps.MapTypeControl());
		google.maps.Event.addListener(this.map, 'moveend',
					function () { lthis.moveEndEvent(); lthis.updateAktionenListe(); });
					
	    this.geocoder = new google.maps.ClientGeocoder();
	},
	
	findElements: function() {
		var lthis = this;
		
		this.aktionenListe = document.getElementById('aktionenListe');
		this.aktionenListeHeader = document.getElementById('aktionenListeHeader');
		
		this.initZoomButtons(document.getElementById('zoomButtons'));
	},
	
	initZoomButtons: function(container) {
		var lthis = this;
		var select = document.createElement('select');
		for (var id in this.zoomPoints) {
			var button = document.createElement('option');
			button.appendChild(document.createTextNode(id));
			select.appendChild(button);
		}
		container.appendChild(select);
		select.onchange = function() { lthis.zoomTo(this.value || this.options[this.options.selectedIndex].text); return false; };
	},

    zoomTo: function(where) {
        var pos = this.zoomPoints[where];
        if (pos != null)
            this.map.setCenter(new google.maps.LatLng(pos[0], pos[1]), pos[2]);
    },
	
	zeigeAktionenSucheResultate: function(request, success) {
		if (!success) {
			alert("Fehler.");
			return;
		}
		var list = request.responseXML.getElementsByTagName('list')[0];
		if (list == null) {
			alert("Fehler.");
			return;
		}
		
		this.map.closeInfoWindow();
		
		var ids = list.getAttribute('ids').split(',');
		this.aktionenSuchresultate = [];
        this.aktionenSuchresultateIDs = {};
		var i;
		for (i = 0; i < ids.length; i ++) {
			this.aktionenSuchresultateIDs[ids[i]] = 1;
		}
		var aktion;
		for (i = 0; i < this.aktionen.length; i ++) {
			aktion = this.aktionen[i]
			if (this.aktionenSuchresultateIDs[aktion.id] == null) {
				aktion.hideMarker();
			} else {
				aktion.showMarker();
				this.aktionenSuchresultate.push(aktion);
			    this.aktionenSuchresultateIDs[aktion.id] = 2;
			}
		}
		
		this.updateAktionenListe();
	},
	
	zoomToAktionenSuchResultate: function() {
		var aktion;
		if (this.aktionenSuchresultate.length == 0) return;
		
		var bounds = new google.maps.LatLngBounds;
		for (var i = 0; i < this.aktionenSuchresultate.length; i ++) {
			bounds.extend(this.aktionenSuchresultate[i].point);
		}
		var zoom = this.map.getBoundsZoomLevel(bounds);
		if (zoom > 7) zoom = 7;
		this.map.setCenter(bounds.getCenter(), zoom);
	},
	
	loescheSuchresultate: function() {
	    this.aktionenSuchresultate = null;
            this.aktionenSuchresultateIDs = null;

		var i;
		for (i = 0; i < this.aktionen.length; i ++) {
			this.aktionen[i].showMarker();
		}
		this.updateAktionenListe();
	},
	
	setLoading: function() {
		this.aktionenListe.style.display = 'none';
		document.getElementById('listLoading').style.display = 'block';		
	},
	
	updateAktionenListe: function() {
		if (!this.aktionenListeJemalsSichtbar) return;
		
		this.unhilightAktion(this.currentHilightAktion);
		
		this.aktionenListe.style.display = 'none';
		if (this.aktionenListeSichtbar)
			document.getElementById('listLoading').style.display = 'block';
		
		var lthis = this;
		window.setTimeout(function() {
		var aktionen, evenMore;
		
		if (lthis.aktionenSuchresultate != null) {
			aktionen = lthis.aktionenSuchresultate;
		} else {
			aktionen = lthis.spatialFilter.filter(lthis.map.getBounds());
		}
		
		clearNode(lthis.aktionenListe);
		
		for (var i = 0; i < aktionen.length; i ++) {
			lthis.aktionenListe.appendChild(aktionen[i].getAktionenListeContent());
		}
		
		if (aktionen.length == 0) {
			if (lthis.aktionenSuchresultate == null) {
				lthis.aktionenListe.appendChild(
						document.createTextNode('Im aktuellen Kartenausschnitt befinden sich keine Aktionen.'));
			} else {
				lthis.aktionenListe.appendChild(
						document.createTextNode('Die Suche ergab keine Resultate.'));
			}
		}
		
		document.getElementById('listLoading').style.display = 'none';
		if (lthis.aktionenListeSichtbar)
			lthis.aktionenListe.style.display = 'block';
		
		}, 10);
	},
	
	setPositionFromCookie: function() {
		/* can only be called right after map costruction */
		var pos = readCookie('mapPosition');
		if (pos == null) {
			this.map.setCenter(new google.maps.LatLng(51.5, 10.5), 6);
		} else {
			pos = pos.split('_');
			var center = new google.maps.LatLng(pos[0] - 0, pos[1] - 0);
			var zoom = pos[2] - 0;
			this.map.setCenter(center, zoom);
		}
	},
	
	savePositionInCookie: function() {
		var center = this.map.getCenter();
		var zoom = this.map.getZoom();
		document.cookie = 'mapPosition=' + center.lat() + '_' +
										center.lng() + '_' + zoom + '; path=/';		
	},
	
	hilightAktion: function(aktion, scrollIntoView) {
		if (this.aktionenIds[aktion.id] == null) return;
		this.unhilightAktion(this.currentHilightAktion);
		this.currentHilightAktion = aktion;
		aktion.hilight(scrollIntoView);
	},
	
	unhilightAktion: function(aktion) {
		if (aktion != this.currentHilightAktion || aktion == null) return;
		this.currentHilightAktion.unhilight();
		this.currentHilightAktion = null;
	},
	
	setAktionenListeHeader: function(text) {
		clearNode(this.aktionenListeHeader);
		this.aktionenListeHeader.appendChild(document.createTextNode(text));
	}
}

