
var map = null; // Map-Objekt

var efid = false;

var efidPreselectionDone = false;

var partnerArray = new Array(new Array("0", "STVAS"), new Array("1", "LVM")); // alle
																				// Partner
var getGeoUrl = '/ajax/getGeo';														// mit
																				// zugehörigen
																				// 'internen'
																				// IDs
																				// (für
																				// dieses
																				// Javascript)

var fixedMarkers = new Array(); // Array aller fixedMarkers

var temporaryMarkers = new Array(); // Array aller temporaryMarkers

var temporaryIcons = new Object(); // Array aller temporaryMarkers

var highlightCircle; // Das HighlichtCircle-Objekt

var highlightMarkerId; // ID des aktuelle gehighlighteten Markers

var highlightMarker; // Aktuell gehighlighteter Marker

var currentMarker; //

var doHighlightNearestBranch = false; // set if the klicked marker should be
										// highlighted in ads

var loading; // Ladeanzeige auf der Map

var currentZoom = false;

// Debug Modus
var debugMode = false;
var debugDiv = $('debug');
var debugTempStr = "";

// Marker-Icons für die LVM
var smallLvmIcon = "/images/gmaps/p_uid1_small.png";
var smallLvmIconLeft = "/images/gmaps/p_uid1_small_l.png";
var smallLvmIconRight = "/images/gmaps/p_uid1_small_r.png";
var largeLvmIcon = "/images/gmaps/p_uid1.png";
var largeLvmIconLeft = "/images/gmaps/p_uid1_l.png";
var largeLvmIconRight = "/images/gmaps/p_uid1_r.png";

var mapx,mapy = false;



function mapContaintsSTVAs(top,right,bott,left)
{
 dd("map? top: "+top+", right:"+right+", bott:"+bottom+", left:"+left+",\n, stvas: "+stvas.length);
var stvasLen =  stvas.length;
if(stvas.length>0)
{
    for(var k =0;k<stvasLen ;k++)
    {
    if(!containsLatLng(top,right,bottom,left,stvas[k][1],stvas[k][2]))
    	return false;
    }
return true;
}
}
function mapContaintsSTVAs(top,right,bott,left)
{
 dd("map? top: "+top+", right:"+right+", bott:"+bottom+", left:"+left+",\n, stvas: "+stvas.length);
var stvasLen =  stvas.length;
if(stvas.length>0)
{
    for(var k =0;k<stvasLen ;k++)
    {
    if(!containsLatLng(top,right,bottom,left,stvas[k][1],stvas[k][2]))
    	return false;
    }
return true;
}
}


function containsLatLng(top,right,bottom,left,newLat,newLng)
{
 dd("top: "+top+", right:"+right+", bott:"+bottom+", left:"+left+",\n newLat: "+newLat+", newLong: "+newLng);
if(newLat>bottom&& newLat < top)
{ if(newLng>left&& newLng < right)
 	{return true;}// else alert("check for left/right false");
}  //else alert("check for top bottom false");
 return false;
// top: 52.26479561297205, right:9.5361328125,
// bott:51.723625515056554, left:8.27545166015625, newLat: 51.9362, newLong:
// 8.84787

}


/*
 * @
 */
function calculateAbsoluteCenterofStvas()
{
	var lat = 0,lon=0,minlat,maxlat,minlon,maxlon,templat,templon,avglat=0,avglon=0;

		for(var i=0;i<stvas.length;i++)
		{
		  avglat  +=  parseFloat(stvas[i][1]);
		  avglon  +=  parseFloat(stvas[i][2]);
		  templat  =  parseFloat(stvas[i][1]);
		  templon  =  parseFloat(stvas[i][2]);
		 if((typeof(minlat)=="undefined") || templat < minlat  )
      { minlat = templat;} //else alert("not min lat: "+templat);

		if((typeof(maxlat)=="undefined") || templat > maxlat  )
     { maxlat = templat; } //else alert("not max lat: "+maxlat);



		 if((typeof(minlon)=="undefined") || templon < minlon  )
      { minlon = templon;} //else alert("not min lon: "+templon);

		if((typeof(maxlon)=="undefined") || templon > maxlon  )
     { maxlon = templon;} //else alert("not max lon: "+maxlon);

		}
		avglat = avglat/stvas.length;
		avglon = avglon/stvas.length;

		 lat = (minlat+maxlat)/2;
		 lon = (minlon+maxlon)/2;

		  dd("minlat: "+minlat+", maxlat: "+maxlat+", minLong: "+minlon+", maxLong: "+maxlon+",, avglat: "+avglat+", avglon: "+avglon+" --> cLat: "+lat+", cLon: "+lon);
	 	return Array(lat,lon);
}

//function doesRequireWiderZoom()
// { var arr = stvas;
// for(var i=0;i<arr.length;i++)
// {
// if(map.getBounds().containsLatLng(parseFloat(arr[i][1]),parseFloat(arr[i][2])));
// return true;
// }
// return false;
// }

function loadMap(k, city,pDoStartRotation) {
	 dd(k+","+city+","+pDoStartRotation);
	if(typeof(city)=="object") // is array
	{  
		mapx = city[0];
		mapy = city[1];
	}

	if(typeof(pDoStartRotation)=="undefined")
		pDoStartRotation = true;
	 
	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById("gmap"));
		map.addControl(new GSmallMapControl());
		map.addControl(new GHierarchicalMapTypeControl ());
		map.addMapType(G_PHYSICAL_MAP);
		map.enableContinuousZoom();
		// map.enableScrollWheelZoom();
 
		// Ladeanzeige erzeugen 51,994 , 8.907
		loading = new GScreenOverlay('/images/ajax-loader.gif',
			new GScreenPoint(235, 296, 'pixels', 'pixels'),  // screenXY
			new GScreenPoint(0, 0),  // overlayXY
			new GScreenSize(16,16)  // size on screen
		);
		loading.hide();
		map.addOverlay(loading);
		
		
		var lat; // the center
		var lng;
		var address = $('logo_stadt').innerHTML;
		 
		if (stvas.length > 0)
		{ dd("geo by stvas");
			var arith = calculateAbsoluteCenterofStvas();
			lat = arith[0];
			lng = arith[1];

			// var requireMoreZoom = doesRequireWiderZoom();
			var defaultZoom = 9; 

			map.setCenter(new GLatLng(lat,lng ),10, G_PHYSICAL_MAP);

			bounds = map.getBounds();

			for(var i=0;i<stvas.length;i++)
			{
				lat = parseFloat(stvas[i][1]);
				lng = parseFloat(stvas[i][2]);

				bounds.extend(new GLatLng(lat, lng));
			}
			map.setZoom(map.getBoundsZoomLevel(bounds));

			
			// alert(zoom);

		}
		else
		{
			
			// either we got a townname in "adress" or city is an array of lat lng
			
			if((mapx && mapy))
			{   dd("by mapx "+mapx+" mapy "+mapy);
				map.setCenter(new GLatLng(mapx,mapy), 10, G_PHYSICAL_MAP);
			}
			else
			{
				dd("by geo");
			var geocoder = new GClientGeocoder();

			geocoder.getLatLng(
				address,
					function(point) {
						if (!point) 
						{
							map.setCenter(new GLatLng(51.344339, 10.195313), 4, G_PHYSICAL_MAP);
							//alerdt(address + " not found");
						} else {  // geocoder failed
							map.setCenter(point, 10, G_PHYSICAL_MAP);
						}
					}
				);
			}
		}
	 
		GEvent.addListener(map, "zoomend", function() {
			if (highlightCircle) {
				map.removeOverlay(highlightCircle);
			}

			if (map.getZoom() < 9) {
				map.setZoom( 9);
			}


			 redrawMarkers(0);

			 reloadMap();
		});

		GEvent.addListener(map, "movestart", function() {
			// Ladeanzeige einblenden
			loading.show();
		});

		GEvent.addListener(map, "moveend", function() {
			// Anzeigen neuladen, sobald Bewegung beendet
			reloadMap();
		});
		
		 loading.hide();


 	    loadFixedMarkers();
 	   
 	     reloadMap();
 	    
 	    if(pDoStartRotation) { 
 	    	//alert("start rot  "+pDoStartRotation);
 	    //	startRotation();
 	    	}
 	    else  ; //alert("no rot");
 	    

	}
}

function redrawMarkers(deleteIt) {
	for(var i = 0; i < temporaryMarkers.length; i++)
	{
		if(temporaryMarkers[i]._options['flag'] == "p")
		{
			var image = updateMarkerImage(temporaryMarkers[i]._options['style'], map.getZoom());
			temporaryMarkers[i].setImage(image);
			if(deleteIt == 1) map.removeOverlay(temporaryMarkers[i]);
			if(deleteIt == 2) map.addOverlay(temporaryMarkers[i]);
		}
	}
}

function reloadMap() {

	// Ladeanzeige einblenden
	loading.show();

	// temporaryMarkers, die sich nicht auf der Map befinden, von dieser löschen
	deleteTemporaryMarkersNotOnMap();

	// temporaryMarkers neu laden
	loadTemporaryMarkers(k);

	if(debugMode)
	{
		var tempStr1 = "";
		for(var i = 0; i < fixedMarkers.length; i++)
		{
			tempStr1 += fixedMarkers[i]._options['explicitId']+", ";
		}

		var tempStr2 = "";
		for(var i = 0; i < temporaryMarkers.length; i++)
		{
			tempStr2 += temporaryMarkers[i]._options['explicitId']+", ";
		}
		
		if(debugDiv==null)
			debugDiv = $('debug');
		
		
		debugDiv.update(''); // clear
		debugDiv.update(fixedMarkers.length+" FixedMarkers: "+tempStr1+"<br />"+temporaryMarkers.length+" TempMarkers: "+tempStr2+"<br />");
	}
}

function loadFixedMarkers()
{
	var markerId;
	// Lade STVAS
	for(var i=0; i < stvas.length; i++)
	{
		markerId = "s_"+stvas[i][0];
		if(markerExists(markerId) == false)
		{
			newMarker = xmlToMarker(stvas[i][0], stvas[i][1], stvas[i][2], "s", stvas[i][3], stvas[i][4], true);
			if(newMarker != null)
			{
				fixedMarkers.push(newMarker);
			}
		}
	}

}

function loadTemporaryMarkers() {

	// Eingrenzen, dass temporaryMarkers nur ab einem bestimmten Zomlevel gesehen werden können
	if (  map.getZoom() < 9) {
		map.openInfoWindow(map.getCenter(), "Um mehr Details zu sehen,<br />müssen Sie den Kartenausschnitt<br />vergrößern!");
	}
	else
	{
		var bounds = map.getBounds();
		var top = bounds.getNorthEast().lat();
		var right = bounds.getNorthEast().lng();
		var bottom = bounds.getSouthWest().lat();
		var left = bounds.getSouthWest().lng();

		var url = getGeoUrl+'?exclude=' + k + '&top=' + top + '&left=' + left + '&bottom=' + bottom + '&right=' + right;
		// alert("get Geo called");
		GDownloadUrl(url, function(data){
			var xml = GXml.parse(data);

			var xmlResults;

			var newMarker;

			var markerId;

			var countNewAddedTemporaryMarkers = 0;

			// Lade STVAS
			if (xml.documentElement.getElementsByTagName("s") && xml.documentElement.getElementsByTagName("s")[0].hasChildNodes) {
				xmlResults = xml.documentElement.getElementsByTagName("s")[0].getElementsByTagName("e");
				for (var i = 0; i < xmlResults.length; i++) {
					id = xmlResults[i].getElementsByTagName("i")[0].firstChild.nodeValue;
					var title = xmlResults[i].getElementsByTagName("t")[0].firstChild.nodeValue;
					lat = xmlResults[i].getElementsByTagName("b")[0].firstChild.nodeValue;
					lng = xmlResults[i].getElementsByTagName("l")[0].firstChild.nodeValue;
					markerId = "s_"+id;
					if(markerExists(markerId) == false)
					{
						newMarker = xmlToMarker(id, lat, lng, "s", title, "", false);
						if(newMarker != null)
						{
							temporaryMarkers.push(newMarker);
						}
					}
				}
			}

			// Lade Partner
			if (xml.documentElement.getElementsByTagName("p")[0].hasChildNodes) {
				xmlResults = xml.documentElement.getElementsByTagName("p")[0].getElementsByTagName("e");
				for (var i = 0; i < xmlResults.length; i++) {
					uid = xmlResults[i].getAttribute('uid');

					id = xmlResults[i].getElementsByTagName("i")[0].firstChild.nodeValue;
					//
					var	title =  xmlResults[i].getElementsByTagName("t")[0].firstChild.nodeValue;

					lat = xmlResults[i].getElementsByTagName("b")[0].firstChild.nodeValue;
					lng = xmlResults[i].getElementsByTagName("l")[0].firstChild.nodeValue;
					markerId = "p_"+id;
					if(markerExists(markerId) == false)
					{
						newMarker = xmlToMarker(id, lat, lng, "p", title, "", false);
						if(newMarker != null)
						{
							temporaryMarkers.push(newMarker);
							countNewAddedTemporaryMarkers++;
						}
					}
				}
			}

			// externe Anzeigen laden
			var unsafeEfid = readCookie("efid");

			if(typeof(parseInt(unsafeEfid))=="number")
				efid = unsafeEfid;
			// alert("maybe will load by loc");
			// load new data if new markers or a specific is to be displayed
 			// load new data if an efid-ad has to be overwritten
			if( true ) // countNewAddedTemporaryMarkers > 0 ||  doHighlightNearestBranch
			{
				 loadAdsByLocation(map.getCenter().lat(),map.getCenter().lng(),efid);

			}
			// Ladeanzeige ausblenden
			loading.hide();
		});

		// Tooltip Position korrigieren
		//matchToolTipStyles();
	}
}



function markerExists(markerid)
{
	for(var i=0; i<this.temporaryMarkers.length; i++)
	{
		if(this.temporaryMarkers[i]._options['explicitId'] == markerid)
		{
			return true;
		}
	}

	return false;
}

function deleteTemporaryMarkersNotOnMap()
{
	/*
	// durchlaufe Array der temporären Marker
	var b = 0;
	while(b < temporaryMarkers.length)
	{
		// Testen, ob Marker im Kartenausschnitt
		if(map.getBounds().containsLatLng(temporaryMarkers[b].getLatLng()) == false)
		{
			// Marker befindet sich nicht im Kartenausschnitt, also entfernen

			// HighlightCircle löschen, wenn er angezeigt wird
			// if(temporaryMarkers[a][b].getUserData() == highlightMarkerId)
			// map.removeOverlay(highlightCircle);
			if(temporaryMarkers[b]._options['explicitId'] == highlightMarkerId) map.removeOverlay(highlightCircle);
			// Marker von Karte entfernen
			// temporaryMarkers[a][b].remove();
			// Marker aus Array entfernen
			temporaryMarkers.splice(b, 1);
		}
		else
		{
			// Marker befindet sich im Kartenausschnitt, alles ok, springe zu nächstem
			b++;
		}
	}
	*/
}


function xmlToMarker(id, lat, lng, flag, toolTipText, detailWinText, fixed)
{
	var marker;

	if(flag == "s")
	{
		var markericon = new GIcon();
		markericon.image = "/images/gmaps/s.png";
		markericon.iconSize = new GSize(52, 38);
		markericon.iconAnchor = new GPoint(20, 15);
		markericon.infoWindowAnchor = new GPoint(12, 12);
	}
	if(flag == "p")
	{
		var markericon = new GIcon();
		markericon.image = updateMarkerImage("middle", map.getZoom());
		// if(lvmIcon==smallLvmIcon)
			// markericon.iconSize = new GSize(25, 23);
		// else
			markericon.iconSize = new GSize(43, 34);
		markericon.iconAnchor = new GPoint(22, 22);
		markericon.infoWindowAnchor = new GPoint(12, 12);

		temporaryIcons[id] = markericon;




    var existingMarkerHere = checkExistingMarkersForThisLocation(lat, lng, flag);

    if(existingMarkerHere != null)
    {
      markericon.image = updateMarkerImage("right", map.getZoom());
      markericon.iconAnchor = new GPoint(0, 22);

      temporaryIcons[existingMarkerHere._options['id']].iconAnchor = new GPoint(43, 22);
      map.removeOverlay(existingMarkerHere);
      map.addOverlay(existingMarkerHere);
      existingMarkerHere._options['style'] = "left";
      existingMarkerHere.setImage(updateMarkerImage(existingMarkerHere._options['style'], map.getZoom()));
    }

	}


	if(debugMode)
		debugTempStr = "("+flag+id+")";

	/*
	* move same coordinates a bit from each other, other vice map.panTo won't
	* load new markers/ ads
	*/

	if(existingMarkerHere)
	{
		lng = parseFloat(lng)+0.0009;
		//dd("exists at "+toolTipText);
	}
	 

	
	
	
	marker = new GMarker(new GLatLng(lat, lng), {icon:markericon});
	// marker.setTooltip("<strong>"+toolTipText+"</strong><br />Klicken für mehr Infos "+debugTempStr);
	// marker.setUserData(flag+"_"+id);
	// marker.setOpacity(100);
	// marker.allowLeftTooltips(true);
	marker._options = new Object();
	marker._options['flag'] = flag;
	marker._options['id'] = id;
	marker._options['explicitId'] = flag+'_'+id;
	marker._options['style'] = "middle";
	if(existingMarkerHere != null)
	{
		marker._options['style'] = "right";
	}

	/*var toolTipHeader = document.createElement('strong');
	toolTipHeader.append(document.createTextNode(toolTipText));*/

	var toolTipContent = document.createElement('div');
	toolTipContent.innerHTML = "<strong>"+toolTipText+"</strong><br />Klicken für mehr Infos";
	/*toolTipContent.append(toolTipHeader);
	toolTipContent.append(document.createElement('br'));
	toolTipContent.append(document.createTextNode("Klicken für mehr Information"));*/

	var tooltip = new Tooltip(marker,toolTipContent,4);
	marker.tooltip = tooltip;

	if(flag == "s")
	{
		//marker.setDetailWinHTML(detailWinText);

		GEvent.addListener(marker, "click", function() {
			stopRotation();
			// pauseRotation(15000);

			//var tempmarker = map.getFirstMarker(); while (tempmarker != null) {
			//tempmarker.closeDetailWin(); tempmarker.hideTooltip(); tempmarker =
			//map.getNextMarker(); }
	        marker.openInfoWindowHtml("<div class='markerDetail'>"+detailWinText+"</div>");

			currentMarker = marker;
			dd(currentMarker._options);
		  	highlightMarker(currentMarker, flag);
			map.panTo(marker.getPoint());
			showOnlyInfoBox(id);
		});
	}
	else
	{
		GEvent.addListener(marker, "click", function()
		{
			stopRotation();
			/*var tempmarker = map.getFirstMarker();
			while (tempmarker != null)
			{
				tempmarker.closeDetailWin();
				tempmarker.hideTooltip();
				tempmarker = map.getNextMarker();
			}*/
		//	alert(id);
			currentMarker = marker;
			dd(currentMarker._options);
		  	highlightMarker(currentMarker, flag);
		  	doHighlightNearestBranch = true;
			map.panTo(marker.getPoint());
		});
	}

	GEvent.addListener(marker, "mouseover", function() {
		//marker.topMarkerZIndex(); // bring marker to top
		var links = map.fromLatLngToContainerPixel(marker.getLatLng()).x;
		var rechts = map.getSize().width - map.fromLatLngToContainerPixel(marker.getLatLng()).x;
		var oben = map.fromLatLngToContainerPixel(marker.getLatLng()).y;
		var unten = map.getSize().height - map.fromLatLngToContainerPixel(marker.getLatLng()).y;

		this.tooltip.show(links, rechts, oben, unten);
	});

	GEvent.addListener(marker, "mouseout", function() {
		//marker.restoreMarkerZIndex();
		this.tooltip.hide();
	});

	map.addOverlay(marker);
	map.addOverlay(tooltip);

	// Wieder den Marker markieren, der vorher markiert war
	if(highlightMarkerId != null)
	{
		if(flag+"_"+id == highlightMarkerId) highlightMarker(marker, flag);
	}

	return marker;
}


function removeHighlighting()
{
	if(highlightCircle)
		map.removeOverlay(highlightCircle);
}


function highlightFID(fid, doPan)
{
	//var didfound=false; // warum?
	temporaryMarkers.each(function(s) {
		if(s._options['id'] == fid)
		{
			if(doPan) map.panTo(s.getPoint());
			highlightMarker(s, "p");
			// didfound=true;
		}
	});
}

function highlightMarker(marker, flag)
{
	if(marker.getPoint)
	{
		var markerPoint = marker.getPoint();
		var polyPoints = Array();

		if (highlightCircle) {
			map.removeOverlay(highlightCircle);
			highlightMarkerId = "";
		}

		var mapNormalProj = G_NORMAL_MAP.getProjection();
		var mapZoom = map.getZoom();
		var clickedPixel = mapNormalProj.fromLatLngToPixel(markerPoint, mapZoom);

		var polySmallRadius = 40;

		var polyNumSides = 20;
		var polySideLength = 18;

		for (var a = 0; a<(polyNumSides+1); a++) {
			var aRad = polySideLength*a*(Math.PI/180);
			var polyRadius = polySmallRadius;
			    var pixelX = clickedPixel.x + polyRadius * Math.cos(aRad);
			var pixelY = clickedPixel.y + polyRadius * Math.sin(aRad);
			var polyPixel = new GPoint(pixelX,pixelY);
			var polyPoint = mapNormalProj.fromPixelToLatLng(polyPixel,mapZoom);
			polyPoints.push(polyPoint);
		}
		if(flag=="s") highlightCircle = new GPolygon(polyPoints,"#000000",2,0.0,"#FFE51F",0.5);
		if(flag=="p") highlightCircle = new GPolygon(polyPoints,"#000000",2,0.0,"#007A3E",0.5);
		if(highlightCircle != null)
		{
			map.addOverlay(highlightCircle);
			// highlightMarkerId = marker.getUserData();
			highlightMarkerId = marker._options['explicitId'];
		}
	}
	else
	{
		debugDiv.update('Highlighting auf nicht vorhandenen Marker schlug fehl! Marker ist '+marker);
	}
}

function matchToolTipStyles()
{
	var rand = 100;
	// durchlaufe Array der temporären Marker
	var a = 0;
	while(a < temporaryMarkers.length)
	{
		var b = 0;
		while(b < temporaryMarkers[a].length)
		{
			marker = temporaryMarkers[a][b];
			pos = map.fromLatLngToContainerPixel(marker.getLatLng());
			size = map.getSize();
			change = false;
			if(pos.x > size.width-rand)
			{
				change = true;
			}
			if(change == true)
			{
				marker.setTooltipClass("markerTooltipLeft");
			}
			b++;
		}
		a++;
	}
}

function checkExistingMarkersForThisLocation(lat, lng, flag)
{
	for(var i=0; i<temporaryMarkers.length; i++)
	{
		if(runden(temporaryMarkers[i].getLatLng().lat()) == runden(lat) && runden(temporaryMarkers[i].getLatLng().lng()) == runden(lng))
		{
			if(flag !== null)
			{
				if(flag == temporaryMarkers[i]._options["flag"])
				{
					return temporaryMarkers[i];
				}
			}
			else
			{
				return temporaryMarkers[i];
			}
		}
	}

	return null;
}

function runden(zahl)
{
	return Math.round(zahl * 100) / 100;
}

function updateMarkerImage(style, zoom)
{
	if (zoom < 12)
	{
		if(style == "middle") return smallLvmIcon;
		if(style == "left") return smallLvmIconLeft;
		if(style == "right") return smallLvmIconRight;
	}
	else
	{
		if(style == "middle") return largeLvmIcon;
		if(style == "left") return largeLvmIconLeft;
		if(style == "right") return largeLvmIconRight;
	}

}

/* Tooltip */

function Tooltip(marker, content, padding){
	this.marker = marker;
	this.content = content;
	this.padding = padding;
	this.div = null;
	this.map = null;
}

if (typeof(GOverlay)=="function") {
	Tooltip.prototype = new GOverlay();

	Tooltip.prototype.initialize = function(map){

		this.div = document.createElement("div");
		var innerContainer = this.div.cloneNode(false);
		this.div.appendChild(innerContainer);
		this.div.style.position = 'absolute';
		this.div.style.visibility = 'hidden';

		this.shadowQuadrants = [{}, {}, {}, {}];
		this.shadowQuadrants[0].div = document.createElement('div');
		this.shadowQuadrants[0].div.style.position = 'absolute';
		this.shadowQuadrants[0].div.style.overflow = 'hidden';
		this.shadowQuadrants[0].img = createPngElement('/images/1x2px.gif');
		this.shadowQuadrants[0].img.style.position = 'absolute';
		this.shadowQuadrants[0].div.appendChild(this.shadowQuadrants[0].img);
		this.shadowQuadrants[1].div = this.shadowQuadrants[0].div.cloneNode(false);
		this.shadowQuadrants[1].img = this.shadowQuadrants[0].img.cloneNode(true);
		this.shadowQuadrants[1].div.appendChild(this.shadowQuadrants[1].img);
		this.shadowQuadrants[2].div = this.shadowQuadrants[0].div.cloneNode(false);
		this.shadowQuadrants[2].img = this.shadowQuadrants[0].img.cloneNode(true);
		this.shadowQuadrants[2].div.appendChild(this.shadowQuadrants[2].img);
		this.shadowQuadrants[3].div = this.shadowQuadrants[0].div.cloneNode(false);
		this.shadowQuadrants[3].img = this.shadowQuadrants[0].img.cloneNode(true);
		this.shadowQuadrants[3].div.appendChild(this.shadowQuadrants[3].img);

		this.shadowQuadrants[0].div.style.right = '0px';
		this.shadowQuadrants[0].div.style.top = '0px';
		this.shadowQuadrants[0].img.style.top = '0px';
		this.shadowQuadrants[0].img.style.right = '0px';
		this.shadowQuadrants[1].div.style.left = '0px';
		this.shadowQuadrants[1].div.style.top = '0px';
		this.shadowQuadrants[1].img.style.top = '0px';
		this.shadowQuadrants[2].div.style.left = '0px';
		this.shadowQuadrants[2].div.style.bottom = '0px';
		this.shadowQuadrants[2].img.style.bottom = '0px';
		this.shadowQuadrants[2].img.style.left = '0px';
		this.shadowQuadrants[3].div.style.right = '0px';
		this.shadowQuadrants[3].div.style.bottom = '0px';
		this.shadowQuadrants[3].img.style.bottom = '0px';

		this.shadow = this.div.cloneNode(false);
		this.shadow.appendChild(this.shadowQuadrants[0].div);
		this.shadow.appendChild(this.shadowQuadrants[1].div);
		this.shadow.appendChild(this.shadowQuadrants[2].div);
		this.shadow.appendChild(this.shadowQuadrants[3].div);

		innerContainer.className = 'tooltip';

		var child = typeof this.content == 'string' ? document.createTextNode(this.content) : this.content;
		innerContainer.appendChild(child);
		map.getPane(G_MAP_FLOAT_PANE).appendChild(this.div);
		map.getPane(G_MAP_MARKER_SHADOW_PANE).appendChild(this.shadow);
		this.map = map;
	};
}

Tooltip.prototype.remove = function(){
	this.div.parentNode.removeChild(this.div);
};

Tooltip.prototype.copy = function(){
	var content = typeof this.content == 'string' ? this.content : this.content.cloneNode(true);
	return new Tooltip(this.marker,content,this.padding);
};

Tooltip.prototype.redraw = function(force){
	if (!force) return;

	//draw tooltip
	var markerPos = this.map.fromLatLngToDivPixel(this.marker.getPoint());
	var iconAnchor = this.marker.getIcon().iconAnchor;
	var xPos = Math.round(markerPos.x - this.div.clientWidth / 2);
	var yPos = markerPos.y - iconAnchor.y - this.div.clientHeight - this.padding;
	this.div.style.top = yPos + 'px';
	this.div.style.left = xPos + 'px';

	//draw shadow
	//calculate shadow location
	shadowAnchor = new GPoint(
		markerPos.x + Math.round((this.marker.getIcon().iconSize.height + this.padding) / 2) ,
		markerPos.y - Math.round((this.marker.getIcon().iconSize.height + this.padding) / 2) + 4);

	//calculate shadow dimenstions
	var shadowSize = new GSize(this.div.clientWidth + Math.round(this.div.clientHeight / 2) + 8,
		Math.round(this.div.clientHeight / 2) + 10);
	if(shadowSize.width % 2 == 1) shadowSize.width--;
	if(shadowSize.height % 2 == 1) shadowSize.height--;

	//apply shodaw location and dimensions
	this.shadow.style.left = (shadowAnchor.x - (shadowSize.width - shadowSize.height - 10 )/ 2) + 'px';
	this.shadow.style.top = (shadowAnchor.y - shadowSize.height) + 'px';
	this.shadow.style.width = (shadowSize.width) + 'px';
	this.shadow.style.height =  shadowSize.height + 'px';

	//get quadrant dimensions
	var qHeight = shadowSize.height / 2;
	var qOddWidth = shadowSize.height > shadowSize.width ?
		shadowSize.height / 2:
		(shadowSize.width) / 2;
	var qEvenWidth = shadowSize.width - qOddWidth;

	//apply quadrant dimensions, calculate and apply Q2 and Q4 image offsets
	this.shadowQuadrants[0].div.style.width = qOddWidth + 'px';
	this.shadowQuadrants[0].div.style.height = qHeight + 'px';

	this.shadowQuadrants[1].div.style.width = qEvenWidth + 'px';
	this.shadowQuadrants[1].div.style.height = qHeight + 'px';
	this.shadowQuadrants[1].img.style.left = -(160 - shadowSize.height) + 'px';

	this.shadowQuadrants[2].div.style.width = qOddWidth + 'px';
	this.shadowQuadrants[2].div.style.height = qHeight + 'px';

	this.shadowQuadrants[3].div.style.width = qEvenWidth + 'px';
	this.shadowQuadrants[3].div.style.height = qHeight + 'px';
	this.shadowQuadrants[3].img.style.right = -(160 - shadowSize.height) +'px';
};

Tooltip.prototype.show = function(links, rechts, oben, unten){
	this.div.style.visibility = 'visible';
	var toolTipWidth = 150;
	var abstandVomRand = 10;
	/* Horizontal */
	var marginLeft = "0px";
	if(links < toolTipWidth/2)
	{
		marginLeft = (toolTipWidth/2)-links+abstandVomRand+'px';
	}
	if(rechts < toolTipWidth/2)
	{
		marginLeft = '-'+((toolTipWidth/2)-rechts+abstandVomRand)+'px';
	}
	this.div.style.marginLeft = marginLeft;
	/* Vertikal */
	var marginTop = "0px";
	if(oben < 60)
	{
		marginTop = '80px';
	}
	this.div.style.marginTop = marginTop;
	this.shadow.style.visibility = 'visible';
};

Tooltip.prototype.hide = function(){
	this.div.style.visibility = 'hidden';
	this.shadow.style.visibility = 'hidden';
};

//utility function for png compatibility in IE6
var IS_IE = false;
var IS_LT_IE7;
//@cc_on IS_IE = true;
//@cc_on IS_LT_IE7 = @_jscript_version < 5.7;

function createPngElement(src){
	var img = document.createElement('img');
	img.setAttribute('src',src);
	if(IS_IE && IS_LT_IE7){
		img.style.visibility = 'hidden';
		var div = document.createElement('div');
		div.appendChild(img);
		div.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\',sizingMethod=\'crop\')';
		return div;
	}
	return img;
}