// PPM 2.0 - Performance Panning and Mapping
// (c) 2006 by klickTel AG, Essen.
// All rights reserved. Unauthorized duplication and use prohibited.

var TILESIZE = 256;
var EAGLEVIEW_TILESIZE = 512;

//Skip Zoomlevel 12 as long as the slider supports only 12 steps
var METER_PER_PIXEL = Array (0.25,0.5,1,2,4,8,16,32,64,128,256,1024, 2048, 4096);

var UNITS_PER_METER = 10;
var IRQ_FREQUENCY = 500;
var IE_MAX_DISPLAY_LEVEL = 5;
var BRAID_MAX_DISPLAY_LEVEL = 5;
var DIRECTIONS = Array ('s', 'w', 'n', 'e'); //Viewport directions as used by XML Server
var EVHIDE = Array ('poi', 'navigation', 'trafficjam');
var EVONLY  = Array ('eagleview');
var API_SERVER = "api.klicktel.de";
var NMAP_WORLD_X = 23592960;
var NMAP_WORLD_Z = 87162880;
var NMAP_WORLD_X2 = 86507520;
var NMAP_WORLD_Z2 = 24248320;
var NMAP_CELL_SIZE = 256;
var MOUSE_THRESHOLD = 10;
var MOVES_MAX=75;
var MOVES_COUNT=0;

var STATIC_POI = $H({
	parkplaetze: 7369,
	kirchen:7339,
	bahnhoefe:7380,
	nachtleben:9379,
	parkhaeuser:7313,
	touristenattraktionen:7376,
	autobahnparkplaetze:7395,
	einkaufszentren:7373,
	tennisplaetze:9369,
	aussichtspunkte:7337,
	faehrterminals:7352,
	yachthaefen:9380,
	flughafenterminals:7383,
	kulturzentren:7319,
	erholungsgebiete:7370,
	zoos:9927
});


var ppmObjects = Array (); // To keep track of all PPM Maps on the current page

function localLog (logentry) {
	if (location.hostname.search('.local') != -1
		|| location.hostname.search('.int') != -1) {
		if (Logger != null) {
			Logger.log (logentry);
		}
	}
}

function centerDivInDiv (divToCenter, divToCenterIn) {
	fullDIVSize=divToCenterIn.getDimensions();
	fullDivWidth=fullDIVSize.width;
	fullDivHeight=fullDIVSize.height;
	divToCenterSize=divToCenter.getDimensions();
	divToCenterWidth=divToCenterSize.width;
	divToCenterHeight=divToCenterSize.height;
	divOffsetX=Math.round((fullDivWidth-divToCenterWidth)/2);
	divOffsetY=Math.round((fullDivHeight-divToCenterHeight)/2);
	$(divToCenter).style.left=divOffsetX+'px';
	$(divToCenter).style.top=divOffsetY+'px';
}

function unloadPpm() {
	ppmObjects.each(function(ppmObject) {
	});
	window.clearInterval(irqInterval);
	return true;
}

// Classes
GeoObject = Base.extend ({
	longitude: 0,
	latitude:0,
	ppmObject:null,

	constructor: function (longitude, latitude, ppmObject) {
		this.longitude = longitude;
		this.latitude = latitude;
		if  (ppmObject != null) {
			this.ppmObject = ppmObject;
		}
	}
});

ScreenObject = Base.extend ({
	x:0,
	y:0,
	width:0,
	height:0,
	zIndex:0,
	documentId: '',
	domNode: null,
	parentNode: null,
	ppmObject: null,

	constructor: function (parentNode, ppmObject) {
		this.domNode = document.createElement('div');
		this.domNode.style.position = "absolute";
		this.parentNode = parentNode;
		if (ppmObject != null) {
			this.ppmObject = ppmObject;
		}
	},

	addWidget: function (name, position, zIndex, parameters) {
		var widget = new Widget (this, name, parameters);
		widget.draw (position, zIndex);
	},

	setId: function (id) {
		this.id = id;
		this.domNode.id = id;
	},

	draw: function () {
		var domNode = this.domNode;
		domNode.style.width = this.width+"px";
		domNode.style.height = this.height+"px";
		domNode.style.zIndex = this.zIndex;
		domNode.style.left = this.x+"px";
		domNode.style.top = this.y+"px";
		$(this.parentNode.appendChild(domNode));
	}
});

EventHandler = Base.extend({
	ppmObject: null,
	infoWin: false,

	constructor: function (ppmObject) {
		this.ppmObject = ppmObject;

		ppmObject.parentNode.ondrag = function() {
			window.event.returnValue = false;
		};

		if(/MSIE/.test(navigator.userAgent)) {
		  ppmObject.parentNode.onselectstart = function(event) {
		  	if (event == null) {
		  		event = window.event;
		  	}
		  	if(!/input|textarea/i.test(Event.element(event).tagName))
		      return false;
		  };
		} else { // assume DOM
		  ppmObject.parentNode.onmousedown = function(event) {
		    if(!/input|textarea/i.test(Event.element(event).tagName))
		      return true;
		  };
		}



		if(ppmObject != null) {
			this.enablePpmEvents ();
		}
	},

	enablePpmEvents: function () {
	
		if (this.ppmObject.width < 450) {
			return;
		}
		ppmObject = this.ppmObject;
		Event.observe(ppmObject.parentNode, "mousemove", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(ppmObject.parentNode, "click", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(ppmObject.parentNode, "contextmenu", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(ppmObject.parentNode, "mousedown", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(document, "mouseup", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(ppmObject.parentNode, "dblclick", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.observe(ppmObject.parentNode, "mouseout", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
	
	},

	disablePpmEvents: function () {
		ppmObject = this.ppmObject;
		Event.stopObserving(ppmObject.parentNode, "click", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(ppmObject.parentNode, "contextmenu", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(ppmObject.parentNode, "mousedown", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(document, "mouseup", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(ppmObject.parentNode, "dblclick", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(ppmObject.parentNode, "mousemove", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		Event.stopObserving(ppmObject.parentNode, "mouseout", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
	},


	handleEvent: function (e, ppmObject) {
		if (ppmObject.eventsDisabled == true || ppmObject.widgetsloading > 0) {
			Event.stop(e);
			return (false);
		}

		var element = Event.element (e);

		ppmObject.mouseX = Event.pointerX(e);
		ppmObject.mouseY = Event.pointerY(e);

		if (ppmObject.processes > 0) {
			if (e.type != 'mouseup') { //Make sure the zoomslider still reacts
				Event.stop(e);
			}
			return (false);
		}


		if ($(ppmObject.parentNode.id+"_modal") != null) {
			if (Position.within(ppmObject.modalDialog, ppmObject.mouseX, ppmObject.mouseY) == true) {

			} else {
				Event.stop(e);
				return false;
			}
		}

		switch (e.type) {
			case 'mouseup':
				if(ppmObject.eagleView == 2) {
					ppmObject.setViewCookie();
					ppmObject.helpStatus.moved++;
				}
				ppmObject.eventMouseUp (e);
			break;		
		
			case 'mousemove':
				
				if (element.id.match ('layer_'+ppmObject.layercount) != null || element.id.match ('overlay')|| Element.hasClassName(element, "ppmTile") || Element.hasClassName(element, "evTile")) {
					ppmObject.drag(e);
				}
			break;

			case 'contextmenu':
				var notInMap = !ppmObject.withinActiveArea (ppmObject.mouseX, ppmObject.mouseY);
				if (ppmObject.noContextMenu == true) {
					Event.stop(e);
					return false;
				}
				if (notInMap == false || this.infoWin == true) {
					ppmObject.cleanupUI();
					var ppmPosition = Position.cumulativeOffset(ppmObject.parentNode);
					ppmObject.contextMenuController.x = Event.pointerX(e)-ppmPosition[0];
					ppmObject.contextMenuController.y = Event.pointerY(e)-ppmPosition[1];
					handledClick=false;
					iconClick=false;
					icon=ppmObject.getHoverIcon();

					if (icon == null) {
						mdX = Event.pointerX(e);
						mdY = Event.pointerY(e);
						if (ppmObject.eagleView == 2) {
							if ($(ppmObject.parentNode.id+'_infowindow') != null) {
								if (Position.within($(ppmObject.parentNode.id+'_infowindow'), mdX, mdY) == true) {
									ppmObject.icons.each(function(ic) {
										if('ev_'+ic.domId == $(ppmObject.parentNode.id+'_infowindow').poiId) {
											icon = ic;
										}
									});
								}
							}
						}
						if ($(ppmObject.parentNode.id+'_infowindow') != null) {
							if (Position.within($(ppmObject.parentNode.id+'_infowindow'), mdX, mdY) == true) {
								ppmObject.icons.each(function(ic) {
									if(ic.domId == $(ppmObject.parentNode.id+'_infowindow').poiId) {
										icon = ic;
									}
								});
							}
						}
					}

					if(icon != null) {
						iconClick = true;
						if(icon.type=='marker') {
							if(ppmObject.PpmMarkers.userMarkers.length > 0) {
								ppmObject.PpmMarkers.userMarkers.each(function(marker) {
									if(icon.domId == marker.myID) {
										handledClick=true;
										ppmObject.markerController.lastMarkerFound=marker;
										ppmObject.markerController.handleRightClick(marker);
									}
								});
							}

							if(!handledClick) {
								if(ppmObject.PpmMarkers.linkMarkers.length > 0) {
								ppmObject.PpmMarkers.linkMarkers.each(function(marker) {
									if(icon.domId == marker.myID) {
										handledClick=true;
										ppmObject.markerController.lastMarkerFound=marker;
										ppmObject.markerController.handleRightClick(marker);
									}
									});
								}
							}

						} else if(icon.type=='se') {
							fakeMarker=ppmObject.iconToMarker(icon);
							fakeMarker.poiID=icon.domId;
							ppmObject.markerController.lastMarkerFound=fakeMarker;
							ppmObject.markerController.handlePOIRightClick("contextMenuSE");
							handledClick=true;
						} else if(icon.type=='ie') {
							fakeMarker=ppmObject.iconToMarker(icon);
							fakeMarker.poiID=icon.domId;
							ppmObject.markerController.lastMarkerFound=fakeMarker;
							ppmObject.markerController.handlePOIRightClick("contextMenuSE");
							handledClick=true;
						} else {
							if(ppmObject.pageMode!='route') {
								ppmObject.contextMenuController.show("");
							}
							handledClick=true;
						}

						Event.stop(e);
						break;
					}

					if(!handledClick) { // wenn mit der Maus nicht ueber dem Icon
						if(ppmObject.pageMode!='route') {
							ppmObject.contextMenuController.show("contextMenuMap");
						}
						handledClick=true;
					}
					Event.stop(e);
				}
			break;

			case 'click':
				if (ppmObject.eventHandlers.click != null) {
					var cont = ppmObject.eventHandlers.click();
					if (cont == false) {
						return;
					}
				}
				if (element.id.match (/^markerController/) != null) {
					ppmObject.markerController.handleLinkClick (element.id);
					Event.stop(e);
					return false;
				}

				if (element.id == ppmObject.parentNode.id+'_set_marker') {
					ppmObject.contextMenuController.hide();
					var x = ppmObject.contextMenuController.x;
					var y = ppmObject.contextMenuController.y;

					if (ppmObject.eagleView != 2) {
						var longlat = ppmObject.getGeo(x,y);
						ppmObject.markerController.createMarker (x-ppmObject.x, y-ppmObject.y, longlat.longitude, longlat.latitude);
					} else {
						ppmObject.processes++;
						query = ppmObject.ajaxPath+"evgetgeo"+ppmObject.ajaxExtension;

						var tileX = Math.round(ppmObject.evWidth/2-ppmObject.width/2-ppmObject.evX)+x;
						var tileY = Math.round(ppmObject.evHeight/2-ppmObject.height/2-ppmObject.evY)+y;

						if (ppmObject.evZoomLevel == 1) {
							tileX *= 3;
							tileY *= 3;
						}

						var evAjax = new Ajax.Request (
							query, {
								parameters: "Customer=999&x="+ppmObject.evLongitude+"&y="+ppmObject.evLatitude+"&screenx="+tileX+"&screeny="+tileY+"&d="+ppmObject.evDirection+'&_rnd='+Math.random(),
								method: 'get',
								onComplete: function (originalRequest) {
									ppmObject.processes--;
									if (originalRequest.responseText.match ('Error') != null) {
										alert ("Fehler: Bildkoordinaten konnten nicht aufgelöst werden");
									} else {
										json = eval("(" + originalRequest.responseText + ")");
										ppmObject.markerController.createMarker (x-ppmObject.evX, y-ppmObject.evY, json.longitude, json.latitude);
									}
								}
						}
						);

					}

					Event.stop(e);
					return false;
				}
				if (element.id == ppmObject.parentNode.id+'_windrose_up') {
					ppmObject.pan (0,ppmObject.height/2);
					Event.stop(e);
					return false;
				}
				if (element.id == ppmObject.parentNode.id+'_windrose_down') {
					ppmObject.pan (0,-ppmObject.height/2);
					Event.stop(e);
					return false;
				}
				if (element.id == ppmObject.parentNode.id+'_windrose_left') {
					ppmObject.pan (ppmObject.width/2,0);
					Event.stop(e);
					return false;
				}
				if (element.id == ppmObject.parentNode.id+'_windrose_right') {
					ppmObject.pan (-ppmObject.width/2,0);
					Event.stop(e);
					return false;
				}
				if (element.id == ppmObject.parentNode.id+'_windrose_center') {
					ppmObject.goHome ();
					Event.stop(e);
					return false;
				}

				if (element.id == ppmObject.parentNode.id+'_ie_toggle_link') {
					if (ppmObject.poi.infoEntries == true) {
						ppmObject.poi.infoEntries = false;
					} else {
						ppmObject.poi.infoEntries = true;
						ppmObject.zoomIE ();
					}

					ppmObject.draw ();
				}

				if (element.id == ppmObject.parentNode.id+'_update_baids') {
					var checkers = $(ppmObject.parentNode.id+"_poi_select").getElementsByTagName ("input");
					if (checkers.length > 0) {
						ppmObject.poi.braIds = Array ();
						ppmObject.poi.staticPoi = Array ();
						for (i=0; i<checkers.length; i++){
							var checker = checkers[i];
							if (Element.hasClassName(checker, "baid_check")) {
								if (checker.checked == true) {
									braids = checker.value.split (";");
									braids.each (function (braid){
										if(/^s/.test(braid)) { //Static POI
											id = braid.substr(1,braid.length-1);
											ppmObject.poi.staticPoi.push(id);
										} else { //Some kind of DynPOI
											ppmObject.poi.braIds.push(braid);
										}
									});
								}
							}
						}
						if (ppmObject.zoomLevel > BRAID_MAX_DISPLAY_LEVEL) {
							ppmObject.setZoomLevel(BRAID_MAX_DISPLAY_LEVEL);
						}
						ppmObject.draw ();
					}
				}

				if (element.id == ppmObject.parentNode.id+'_clear_baids') {
					$(ppmObject.parentNode.id+"_ie_toggle_link").checked = false;
					var checkers = $(ppmObject.parentNode.id+"_poi_select").getElementsByTagName ("input");
					if (checkers.length > 0) {
						for (i=0; i<checkers.length; i++){
							checkers[i].checked = false;
						}
					}
					ppmObject.poi.braIds.clear();
					ppmObject.poi.staticPoi.clear();
					ppmObject.poi.infoEntries = false;
					ppmObject.draw();
				}

				var notInMap = !ppmObject.withinActiveArea (ppmObject.mouseX, ppmObject.mouseY);

				if (notInMap == false) {
					iconFound=ppmObject.getHoverIcon();
					if(iconFound != null) {
						iconClick = true;
						iconFound.showInfoWindow();
						Event.stop(e);
						break;
					}

					rectangleFound=ppmObject.getHoverRectangle();
					if(rectangleFound != null) {
						rectangleClick = true;
						rectangleFound.showInfoWindow();
						Event.stop(e);
						break;
					}
				} else {
					//ppmObject.hideInfoWindow();
				}
			break;

			case 'mousedown':
//				if (Event.element(e).id.match (/_layer/) != null) {//funktioniert im IE nicht
				var mdX = Event.pointerX(e);
				var mdY = Event.pointerY(e);
				if ($(ppmObject.parentNode.id+'_infowindow') != null) {
					if (Position.within($(ppmObject.parentNode.id+'_infowindow'), mdX, mdY) == false) {
						if (ppmObject.eagleView != 2)
							ppmObject.hideInfoWindow();
					}
				}

				oldErrorFunc=window.onerror;
				window.onerror=function (a, b, c, d) { localLog('ERROR - '+a); return true; }

				if (Event.isLeftClick(e)) {
					if (Event.element(e).id.match (/_layer/) != null) {//funktioniert im IE nicht
						if(ppmObject.contextMenuController != null) {
							ppmObject.contextMenuController.hide ();
							ppmObject.contextMenuController.hideDynamicMenu ();
						}
					} else {
						if(/MSIE/.test(navigator.userAgent)) {
							if(Element.hasClassName(Event.element(e), 'evTile')) {
								if(ppmObject.contextMenuController != null) {
									ppmObject.contextMenuController.hide();
									ppmObject.contextMenuController.hideDynamicMenu ();
								}
							}
						}
					}

					window.onerror=oldErrorFunc;

				}

				if(!/input|textarea/i.test(Event.element(e).tagName)) {
					ppmObject.eventMouseDown (e);
				}
			break;

			case 'dblclick':
				var ppmPos = Position.cumulativeOffset(ppmObject.parentNode);
				var mapX = ppmObject.mouseX - ppmPos[0];
				var mapY = ppmObject.mouseY - ppmPos[1];
				var geo = ppmObject.getGeo (mapX, mapY);
				if (ppmObject.eagleView == 1 && (element.id.match ('layer_'+ppmObject.layercount) != null || element.id.match ('overlay') != null)) {
						ppmObject.processes++;
						ppmObject.urchinLog(210);
						var evQuery = ppmObject.ajaxPath+'eagleview_point'+ppmObject.ajaxExtension+'?longitude='+geo.longitude+'&latitude='+geo.latitude+'&_rnd='+Math.random();
						ppmObject.evRequest = new Ajax.Request (
							evQuery,
							{onSuccess: function (originalRequest) {
								ppmObject.processes--;
								response = originalRequest.responseText;
								if(/Error/.test(response)) {
									if(ppmObject.helpStatus.eagleViewUnavailable < ppmObject.helpStatusCount.eagleViewUnavailable) {
										ppmObject.showInfoLayer('eagleview_manual_unavailable', 'manual', null, 350);
									}
								} else {
									ppmObject.evDirections.clear ();
									evLonglat = eval("(" + response + ")");
									ppmObject.evLongitude = 1*evLonglat.longitude;
									ppmObject.evLatitude = 1*evLonglat.latitude;
									if (evLonglat.W2E == 1) {
										bestDirection = 1;
										ppmObject.evDirections.push (1);
									}

									if (evLonglat.E2W == 1) {
										bestDirection = 3;
										ppmObject.evDirections.push (3);
									}

									if (evLonglat.N2S == 1) {
										bestDirection = 0;
										ppmObject.evDirections.push (0);
									}

									if (evLonglat.S2N == 1) {
										bestDirection = 2;
										ppmObject.evDirections.push (2);
									}
									ppmObject.direction = -1;
									ppmObject.evSetDirection (bestDirection);
									ppmObject.evEnter ();
								}
							}
							}

						);
						Event.stop (e);
					} else {

					var allIcons = ppmObject.icons.concat(ppmObject.apiIcons);
					for (i=0; i<allIcons.length;i++) {
						icon = allIcons[i];
						var upp = ppmObject.getUnitsPerPixel();
						leftEdge = 1*icon.longitude-(icon.offsetX*upp);
						rightEdge = 1*icon.longitude+(icon.offsetX*upp);
						topEdge = 1*icon.latitude+(icon.offsetY*upp);
						bottomEdge = 1*icon.latitude-(icon.offsetY*upp);
						if (geo.longitude > leftEdge &&
							geo.longitude < rightEdge &&
							geo.latitude > bottomEdge &&
							geo.latitude < topEdge) {
							return false;
						}
					}

					if (ppmObject.getHoverRectangle() != null) {
												return false;
					}

					if (element.id.match (/_layer/) != null || (/MSIE/.test(navigator.userAgent) && Element.hasClassName(element, 'ppmTile'))) {
						if (ppmObject.zoomLevel > 1) {
							level = ppmObject.zoomLevel -1;
						} else {
							level = ppmObject.zoomLevel;
						}
						ppmObject.moveToGeo(geo.longitude, geo.latitude, level);
					} 
				}

			break;
			case "change":
				if(Event.element(e)==$(ppmObject.parentNode.id+"_ppm_ie_selectbox")){
				}
			break;
			case "mouseout":
				//Check if we are really outside the bounds of the map
				if (!Position.within ($(ppmObject.parentNode.id), ppmObject.mouseX, ppmObject.mouseY)) {
					$(ppmObject.parentNode.id+'_tooltip').style.display='none';
					ppmObject.eventMouseUp (e);
				}
			break;

		}
	}
});



Tile = GeoObject.extend ({
	ext: 0,
	updater: null,
	ppmObject: null,
	aerial:0,
	hybrid:0,
	layer_1:null,
	layer_2:null,
	layer_3:null,
	
	constructor: function (parentNode, ppmObject) {
		this.domNode = document.createElement('div');
		this.domNode.tile = this; //Warning, circular reference. Since Tiles are never actually destroyed, this should not become a problem though

		//this.domNode.onselectstart='return false';
		//this.domNode.ondragstart='return false';
		
		this.domNode.onmousedown = function() {return false;};
		
		this.domNode.style.overflow = "hidden";
		
		this.domNode.style.position = "absolute";
		
		
		
		this.parentNode = parentNode;
		this.width = 256;
		this.height = 256;
		Element.addClassName (this.domNode, "ppmTile");
		if (ppmObject != null) {
			this.ppmObject = ppmObject;
		}
		
		this.layer_1 = document.createElement("img");
		this.layer_1.width=256;
		this.layer_1.height=256;
		this.layer_1.ppmObject = this.ppmObject;
		this.layer_1.style.position = "absolute";
		this.layer_1.style.zIndex = 0;
		Element.addClassName (this.layer_1, "ppmTile");
		this.domNode.appendChild(this.layer_1);
		this.layer_1.galleryimg="false";
		
		this.layer_2 = document.createElement("img");
		this.layer_2.width=256;
		this.layer_2.height=256;
		this.layer_2.ppmObject = this.ppmObject;
		this.layer_2.style.position = "absolute";
		this.layer_2.style.zIndex = 1;
		Element.addClassName (this.layer_2, "ppmTile");
		Element.addClassName (this.layer_2, "dontprint");
		this.domNode.appendChild(this.layer_2);
		this.layer_2.galleryimg="false";
		
		this.layer_3 = document.createElement("img");
		this.layer_3.width=256;
		this.layer_3.height=256;
		this.layer_3.ppmObject = this.ppmObject;
		this.layer_3.style.position = "absolute";
		this.layer_3.style.zIndex = 2;	
		Element.addClassName (this.layer_3, "ppmTile");
		Element.addClassName (this.layer_3, "dontprint");
		this.domNode.appendChild(this.layer_3);
		this.layer_3.galleryimg="false";
					
	
	},
	
	hasConformZoomLevel: function () {
		return isConformZoomlevel (this.ppmObject.getUnitsPerPixel());
	},
	
	hasConformCoordinate: function () {
		return isConformCoordinate (this.longitude, this.latitude, this.ppmObject.getUnitsPerPixel());
	},
	
	queueForDrawing: function ()  {
		//this.layer_1.style.display = "none";
		//this.layer_2.style.display = "none";
		//this.layer_3.style.display = "none";
		
		this.layer_1.style.visibility = "hidden";
		this.layer_2.style.visibility = "hidden";
		this.layer_3.style.visibility = "hidden";
		
		this.layer_1.onload = "";
		this.layer_2.onload = "";
		this.layer_3.onload = "";
		var domId = this.domNode.id;
		
		for (var i=0; i<ppmObject.tilequeues.length;i++) {
			this.ppmObject.tilequeues[i] = this.ppmObject.tilequeues[i].reject (function(tile) {
				return tile.domNode.id == domId;
			});
			this.ppmObject.tilequeues[i].push(this);
			

		}
		
		if ($("status_"+this.domNode.id) != null) {
			$("status_"+this.domNode.id).style.backgroundColor = "#ff0000";
		}
		if ($("status_"+this.domNode.id.replace("tile", "layer2")) != null) {
			$("status_"+this.domNode.id.replace("tile", "layer2")).style.backgroundColor = "#ff0000";
		}
		if ($("status_"+this.domNode.id.replace("tile", "layer3")) != null) {
			$("status_"+this.domNode.id.replace("tile", "layer3")).style.backgroundColor = "#ff0000";
		}
				

	},
	
	logRequestTime: function (layer, image) {
	},
	
	
	logFinishTime: function (layer) {
	},
	
	destroy: function () {
		this.layer_1.onload = null;
		this.layer_2.onload = null;
		this.layer_3.onload = null;
		
		var spacer = this.ppmObject.spacerImage;
		
		this.layer_1.src = spacer;
		this.layer_2.src = spacer;
		this.layer_3.src = spacer;
		
		this.layer_2.filter = null;
		this.layer_3.filter = null;
		
		this.layer_1.ppmObject = null;
		this.layer_2.ppmObject = null;
		this.layer_3.ppmObject = null;
						
		Element.remove (this.layer_1);
		Element.remove (this.layer_2);
		Element.remove (this.layer_3);
		
		this.domNode.onmousedown = null;
		this.domNode.tile = null;
		if (this.domNode.parentNode != null) {
			Element.remove (this.domNode);
		}
		
		this.parentNode = null;
		this.ppmObject = null;
	}
	
	
});


Tile.implement (ScreenObject);

//Complete rewrite of draw function, as it seems totally messed up
Tile.implement ({
	draw: function (layer) {
		// if (layer == null) {
		//	layer = 0;
		//}
		
		this.base();
		
		var poiString = this.ppmObject.buildPoiString();
		
		var mapMode = this.ppmObject.getMapMode();
		switch (mapMode) {
			case 'aerial':
				var baseLayer = 8;
				var topLayer = 0;
				var userLayer = 0;
			break;
			case 'hybrid':
				var baseLayer = 8;
				var topLayer = 4;
				var userLayer = 128;	
			break;
			default:
				if (this.ppmObject.getUnitsPerPixel() < 10240) {
					var baseLayer = 16;
					var topLayer = 0;
					var userLayer = 128;
				} else {
					var baseLayer = 2;
					var topLayer = 1;
					var userLayer = 128;
				}
			break;
		}
		
		if (this.ppmObject.trafficjam == true) {
			var trafficjam=1;
		} else {
			var trafficjam=0;
		}
		
		var spalte = (this.longitude-NMAP_WORLD_X)/(TILESIZE*this.ppmObject.getUnitsPerPixel());	
		var serverId = (spalte % 4)+1;
		switch (layer) {
						
			case 0:		
				this.layer_1.onload = "";
				this.layer_1.src = "";
				if (this.layer_1.isloading == true) {
					this.ppmObject.tileAborted();
				}
				
				if ($("status_"+this.domNode.id) != null) {
					$("status_"+this.domNode.id).style.backgroundColor = "#ffff00";					
				}	
				
				this.layer_1.onload = function () {
					this.onload = "";
					this.style.visibility = "visible";
					if ($("status_"+this.parentNode.id) != null) {
						$("status_"+this.parentNode.id).style.backgroundColor = "#00ff00";					
					}	
					
					this.ppmObject.tileLoaded();							
					this.isloading = false;
				}

				this.ppmObject.tileRequested();								
				this.layer_1.isloading = true;
				this.layer_1.src = "http://nmap0"+serverId+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+this.longitude+"&top="+this.latitude+"&w=256&h=256&zoom="+METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*1000+"&routeid=-1&trafficjam=0&layer="+baseLayer;

			break;
			

			case 1:
				if (topLayer != 0) {
					this.layer_2.onload = "";
					this.layer_2.src = "";
					if (this.domNode.style.filter != null) {
						if (this.layer_2.isloading == true) {
							this.ppmObject.tileAborted();
						}
						
						if ($("status_"+this.domNode.id.replace("tile", "layer2")) != null) {
							$("status_"+this.domNode.id.replace("tile", "layer2")).style.backgroundColor = "#ffff00";
						}
											
						this.layer_2.onload = function () {
							this.style.visibility = "visible";
							this.ppmObject.tileLoaded();
							var src = this.src;
							this.onload = "";
							if ($("status_"+this.parentNode.id.replace("tile", "layer2")) != null) {
								$("status_"+this.parentNode.id.replace("tile", "layer2")).style.backgroundColor = "#00ff00";								
							}
							this.src = this.ppmObject.spacerImage;							
							this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"',sizingMethod='scale')";																
							this.isloading = false;
						}
						this.layer_2.isloading = true;
						this.ppmObject.tileRequested();												
						this.layer_2.src = "http://nmap0"+serverId+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+this.longitude+"&top="+this.latitude+"&w=256&h=256&zoom="+METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*1000+"&routeid=-1&trafficjam=0&layer="+topLayer;				

					} else {
						if (this.layer_2.isloading == true) {
							this.ppmObject.tileAborted();
						}
						if ($("status_"+this.domNode.id.replace("tile", "layer2")) != null) {
							$("status_"+this.domNode.id.replace("tile", "layer2")).style.backgroundColor = "#ffff00";						
						}						

						this.layer_2.onload = function () {
							this.style.visibility = "visible";
							this.onload = "";
							if ($("status_"+this.parentNode.id.replace("tile", "layer2")) != null) {
								$("status_"+this.parentNode.id.replace("tile", "layer2")).style.backgroundColor = "#00ff00";							
							}
							this.ppmObject.tileLoaded();
							this.isloading = false;
						}
						
						this.layer_2.isloading = true;
						this.ppmObject.tileRequested();
						this.layer_2.src = "http://nmap0"+serverId+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+this.longitude+"&top="+this.latitude+"&w=256&h=256&zoom="+METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*1000+"&routeid=-1&trafficjam=0&layer="+topLayer;
						
					}				
				} 
			break;

			case 2:
				if (userLayer != 0 && !document.cookie.match(/nouserlayer/)) {
					this.layer_3.onload = "";
					this.layer_3.src = "";
					if (this.domNode.style.filter != null) {
						if (this.layer_3.isloading == true) {
							this.ppmObject.tileAborted();
						}
						if ($("status_"+this.domNode.id.replace("tile", "layer3")) != null) {
							$("status_"+this.domNode.id.replace("tile", "layer3")).style.backgroundColor = "#ffff00";							
						}
											
						this.layer_3.onload = function () {
							this.style.visibility = "visible";
							this.ppmObject.tileLoaded();
							var src = this.src;
							this.onload = "";
							if ($("status_"+this.parentNode.id.replace("tile", "layer3")) != null) {
								$("status_"+this.parentNode.id.replace("tile", "layer3")).style.backgroundColor = "#00ff00";												
							}
							this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"',sizingMethod='scale')";									
							this.isloading = false;
							this.src = this.ppmObject.spacerImage;
						}
						
						this.layer_3.isloading = true;												
						this.ppmObject.tileRequested();
						this.layer_3.src = "http://nmap0"+serverId+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+this.longitude+"&top="+this.latitude+"&w=256&h=256&zoom="+METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*1000+"&routeid="+this.ppmObject.routeId+"&trafficjam="+trafficjam+"&poicat="+poiString+"&layer="+userLayer;										
												
					} else {
						if (this.layer_3.isloading == true) {
							this.ppmObject.tileAborted();
						}	
						if ($("status_"+this.domNode.id.replace("tile", "layer3")) != null) {
							$("status_"+this.domNode.id.replace("tile", "layer3")).style.backgroundColor = "#ffff00";
						}					

						this.layer_3.onload = function () {
							this.onload = "";
							this.style.visibility = "visible";
							if ($("status_"+this.parentNode.id.replace("tile", "layer3")) != null) {
								$("status_"+this.parentNode.id.replace("tile", "layer3")).style.backgroundColor = "#00ff00";								
							}
							ppmObject.tileLoaded();
							this.isloading = false;
						}						
					}

					this.layer_3.src = "http://nmap0"+serverId+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+this.longitude+"&top="+this.latitude+"&w=256&h=256&zoom="+METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*1000+"&routeid="+this.ppmObject.routeId+"&trafficjam="+trafficjam+"&poicat="+poiString+"&layer="+userLayer;
					this.ppmObject.tileRequested();
					this.layer_3.isloading = true;		
				}
			break;

		}
	}
});

Minimap = GeoObject.extend ({
	tileSize: 256,
	parentNode: null,
	ppmObject: null,
	tile: null,
	ratioX: null,
	ratioY: null,
	navigator:null,
	navigatorImageOffsetX: 3,
	navigatorImageOffsetY: 3,
	movedX:0,
	movedY:0,
	offsetX:0,
	offsetY:0,
	navigatorCenterX:0,
	navigatorCenterY:0,

	constructor: function (parentNode, ppmObject) {
		this.parentNode = parentNode;
		this.ppmObject = ppmObject;
		var table = document.createElement ("table");
		table.setAttribute("cellPadding", 0);
		table.setAttribute("cellSpacing", 0);
		table.style.width = 3*this.tileSize+"px";
		table.style.height = 3*this.tileSize+"px";
		var tbody = document.createElement ("tbody");
		for (y=0; y<3; y++) {
			var tr = document.createElement ("tr");
			for (x=0; x<3;x++) {
				var td = document.createElement ("td");
				td.style.width = this.tileSize+"px";
				td.style.height = this.tileSize+"px";
				td.id = ppmObject.parentNode.id+"_minimap_"+x+"_"+y;
				tr.appendChild (td);
			}
			tbody.appendChild(tr);
		}
		table.appendChild (tbody);

		table.style.position = "absolute";
		this.offsetX = this.tileSize+(this.tileSize-parseInt(this.parentNode.style.width))/2;
		this.offsetY = this.tileSize+(this.tileSize-parseInt(this.parentNode.style.height))/2;
		table.style.left="-"+this.offsetX+"px";
		table.style.top = "-"+this.offsetY+"px";
		this.table = table;
		this.ratioX = ppmObject.width/parseInt(parentNode.style.width);
		this.ratioY = ppmObject.height/parseInt(parentNode.style.height);
		parentNode.appendChild (this.table);
		this.navigator = document.createElement ("div");
		this.navigator.id = ppmObject.parentNode.id+"_minimap_navigator";
		Element.addClassName (this.navigator, "minimap_navigator");
		this.navigator.style.position = "absolute";
		this.navigatorCenterX = ((Math.round(parseInt(parentNode.style.width)-51)/2)-this.navigatorImageOffsetX);
		this.navigatorCenterY = ((Math.round(parseInt(parentNode.style.height)-32)/2)-this.navigatorImageOffsetY);
		this.navigator.style.left = this.navigatorCenterX+"px";
		this.navigator.style.top = this.navigatorCenterY+"px";
		this.navigator.style.width = "58px";
		this.navigator.style.height = "39px";
		if (this.navigator.style.filter != null) {
			this.navigator.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/kt_map/images/minimap_navigator.png',sizingMethod='crop')";
			bg = document.createElement ("div");
			bg.style.width = this.navigator.style.width;
			bg.style.height = this.navigator.style.height;
			bg.style.backgroundColor = "#000000";
			bg.style.filter = "Alpha(opacity:1)";
			this.navigator.appendChild(bg);
		}

		new Draggable (this.navigator,
			{
				revert: function () {
					minimap = ppmObject.minimap;
					navi = this.minimap.navigator;
					centerX = minimap.navigatorCenterX;
					centerY = minimap.navigatorCenterY;
					offsetX = parseInt (navi.style.left)-centerX;
					offsetY = parseInt (navi.style.top)-centerY;
					var upp = ppmObject.getUnitsPerPixel()*3*((minimap.ratioX+minimap.ratioY)/2);
					offsetLongitude = offsetX*upp;
					offsetLatitude = offsetY*upp;
					var longitude = ppmObject.longitude+offsetLongitude;
					var latitude = ppmObject.latitude-offsetLatitude;
					ppmObject.moveToGeo (longitude, latitude);
					minimap.moveToGeo (longitude, latitude);
					minimap.reCenter ();

				}
			}
		);

		parentNode.appendChild (this.navigator);

	},

	updateFromMap: function (forced) {
		if ($(ppmObject.parentNode.id+"_navigation_container") == null || 0 && (forced == null || forced==false) ) {
			return;
		}

		var upp = this.ppmObject.getUnitsPerPixel()*16;
		var ext = (this.tileSize/2)*upp;
		this.table.style.left="-"+this.offsetX+"px";
		this.table.style.top = "-"+this.offsetY+"px";
		var	leftColLongitude = this.ppmObject.longitude-this.tileSize*1.5*upp
		var validLongitude = (upp*TILESIZE)*(Math.floor((leftColLongitude-NMAP_WORLD_X)/(upp*TILESIZE)))+NMAP_WORLD_X;

		var offsetX = (validLongitude-leftColLongitude)/upp; //Benötigte Verschiebung in Pixeln

		
		
		var	topRowLatitude = this.ppmObject.latitude+this.tileSize*1.5*upp
		var validLatitude = (upp*TILESIZE)*(Math.floor((topRowLatitude-NMAP_WORLD_Z2)/(upp*TILESIZE)))+NMAP_WORLD_Z2;

		var offsetY = (topRowLatitude-validLatitude)/upp;

		
		this.table.style.left = (parseInt(this.table.style.left)+offsetX)+"px";
		this.table.style.top = (parseInt(this.table.style.top)+offsetY)+"px";
		
		if (upp <= 40960) {
			for (y=0; y<3; y++) {
				for (x=0; x<3; x++) {
					var td = $(ppmObject.parentNode.id+"_minimap_"+x+"_"+y);
					
					longitude = validLongitude+x*this.tileSize*upp;
					latitude = validLatitude-y*this.tileSize*upp;
	
					bgurl = "url(http://nmap0"+connectionManager.getServerId()+".ppm-ng.de/scripts/image.dll?getxmapdirect&left="+(longitude)+"&top="+(latitude)+"&w=256&h=256&zoom="+upp*100+"&routeid=-1&layer=16)";
	
					td.style.backgroundImage = bgurl;
				}
			}
		}
		this.longitude = ppmObject.longitude;
		this.latitude = ppmObject.latitude;
		this.movedX=0;
		this.movedY=0;
	},

	moveNavi: function (x,y) {
		this.movedX += x/(3*this.ratioX);
		this.movedY += y/(3*this.ratioY);
		this.navigator.style.left = Math.round(this.navigatorCenterX-this.movedX)+"px";
		this.navigator.style.top = Math.round(this.navigatorCenterY-this.movedY)+"px";
	},

	moveToGeo: function (longitude, latitude) {
		var upp = this.ppmObject.getUnitsPerPixel()*3*((this.ratioX+this.ratioY)/2);
		var offsetLong = ppmObject.longitude - this.longitude;
		var offsetLat = ppmObject.latitude - this.latitude;
		var offsetX = Math.round(offsetLong/upp);
		var offsetY = Math.round(offsetLat/upp);
		this.table.style.left = (parseInt (this.table.style.left)-offsetX)+"px";
		this.table.style.top = (parseInt (this.table.style.top)+offsetY)+"px";
		this.longitude = this.ppmObject.longitude;
		this.latitude = this.ppmObject.latitude;
	},

	reCenter: function () {
		this.moveToGeo (this.ppmObject.longitude, this.ppmObject.latitude);
		this.navigator.style.left = this.navigatorCenterX+"px";
		this.navigator.style.top = this.navigatorCenterY+"px";
		this.movedX = 0;
		this.movedY = 0;
	}
});


// Generic Icon class for Infoentry, Standardentry and Marker icons
Icon = GeoObject.extend ({
	symbolUrl: '', // URL to the icon to be shown in map
	symbolWidth:0,
	symbolHeight:0,
	offsetX:0,
	offsetY:0,
	domId:'',
	title:'',
	type:'',

	constructor: function (longitude, latitude, ppmObject,domId, stuff, title) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.ppmObject = ppmObject;
		this.title=title;

		if (this.ppmObject.icons.detect (function (icon) {
			return (icon.domId == domId);
		}) == null) { // Icon not yet in Array
			this.ppmObject.icons.push (this);
		}


		this.domId = domId;

	},

	dumpToString:function()
	{
		t='longitude='+this.longitude+', latitude='+this.latitude+', domId='+this.domId+', symbolUrl:'+this.symbolUrl+', title: '+this.title+', type: '+this.type;
		return t;
	},

	draw:function () {
		ppmObject = this.ppmObject;

		if (ppmObject.eagleView == 2 && this.type != 'marker') {
			return;
		}

		if (ppmObject.eagleView < 2) {
			var img = document.createElement ("img");
			if ($(this.domId) == null)  {
				if (img.style.filter != null) {
					img.src = this.ppmObject.spacerImage;
					img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.symbolUrl+"', sizingMethod='scale');"
				} else {
					img.src = this.symbolUrl;
				}

				img.style.position = "absolute";
				var screenPos = ppmObject.getScreen (this.longitude, this.latitude);
				var leftPos = screenPos.x-ppmObject.x-this.offsetX;
				var topPos = screenPos.y-ppmObject.y-this.offsetY;
				img.style.left = leftPos+"px";
				img.style.top = topPos+"px";

				if(this.type=='marker') {
					img.style.zIndex = 2051;
				} else if(this.type=="ie") {
					img.style.zIndex = 2050;
				} else {
					img.style.zIndex = 2048;
				}
				img.style.width = this.symbolWidth+"px";
				img.style.height = this.symbolHeight+"px";
				img.id = this.domId;

				$(ppmObject.parentNode.id+"_layer_1").appendChild (img);
			}
		} else { // Eagleview Mode
			symbolUrl = this.symbolUrl;
			query = ppmObject.ajaxPath+"evgetpixel"+ppmObject.ajaxExtension;
			pars = "domid="+this.domId+"&centerX="+ppmObject.evLongitude+"&centerY="+ppmObject.evLatitude+"&longitude="+this.longitude+"&latitude="+this.latitude+"&dir="+ppmObject.evDirection+'&_rnd='+Math.random();
			aj = new Ajax.Request(
				query,
				{
					method: 'get',
					parameters: pars,
					onSuccess: function (originalRequest) {
						json = eval("(" + originalRequest.responseText + ")");

						icon = ppmObject.icons.detect (function (icn) {
							return (icn.domId == json.domId);

						});

					    if (ppmObject.evZoomLevel == 1) {
					    	divisor = 3;
					    } else {
					    	divisor = 1;
					    }
						x = Math.round(json.x/divisor);
						y = Math.round(json.y/divisor);

						img = document.createElement ("img");
						img.style.position = "absolute";
						img.style.top = (y-icon.offsetY)+"px";
						img.style.left = (x-icon.offsetX)+"px";
						img.style.zIndex = 8192;
						if (img.style.filter != null) {
							img.src = ppmObject.spacerImage;
							img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+symbolUrl+"', sizingMethod='scale');"
						} else {
							img.src = symbolUrl;
						}

						img.style.width = icon.symbolWidth+"px";
						img.style.height = icon.symbolHeight+"px";
						img.id = "ev_"+icon.domId;

						ppmObject.evTile.appendChild (img);
					}
				}
			);
		}
	},

	undraw:function () {// Removes icon from Map, but keeps it in the Icon List
		if ($(this.domId) != null) {
			Element.remove (this.domId);
		}
	},

	remove: function () {// Removes icon from the PpmObjects Icon-List and from the map
		this.undraw ();
		this.ppmObject.icons = this.ppmObject.icons.reject(function (icon) {
			return (icon.domId == domId);
		});
		if (this.type == 'api') {
			icon.onMap = false;
		}
	},

	showInfoWindow: function () {

	}
}),

ktApiIcon = Icon.extend ({
	symbolUrl: 'http://www.klicktel.de/kt_map/images/POI_markierung.png',
	hoverUrl: '',
	hoverHtml: '',
	symbolWidth:23,
	symbolHeight:26,
	offsetX:11,
	offsetY:26,
	type: 'api',
	clickEventHandler: null,
	hoverEventHandler: null,
	infoHtml: '',
	infoUrl: '',
	infoTitle: '',
	poiClass: '', //Deprecated
	poiClasses: [],
	onMap: false,

	constructor: function (longitude, latitude, ppmObject,domId, stuff, title) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.ppmObject = ppmObject;
		this.title=title;
		this.domId = domId;
		this.poiClasses = [];
		this.ppmObject.apiIcons.push (this);
	},
	
	addClass: function (poiClass) {
		if (!this.poiClasses.detect(function(classIterator) {return classIterator == poiClass})) {
			this.poiClasses.push (poiClass);
		};
	},
	
	removeClass: function (poiClass) {
		this.poiClasses = this.poiClasses.without(poiClass);
	},
	
	hasClassname: function (poiClasses) {
		var result = true;
		var existingPoiClasses = this.poiClasses;
		classNames = poiClasses.split (" ");
		
		classNames.each(function(className) {
			result = result && existingPoiClasses.include(className);
		});
		return result;
	},

	showInfoWindow: function () {
		if (this.clickEventHandler != null) {
			var cont = this.clickEventHandler();
			if (!cont) {
				return;
			}
		}
		var offsetX = this.offsetX+ppmObject.apiSettings.offsetXInfoWindowPoint;
		var offsetY = this.offsetY+ppmObject.apiSettings.offsetYInfoWindowPoint;
		ppmObject.showInfoWindow("infowindow", "ppmid="+ppmObject.parentNode.id+"&title="+encodeURIComponent(this.infoTitle)+"&url="+this.infoUrl+"&html="+encodeURIComponent(this.infoHtml), this.domId, offsetX, offsetY, this.longitude, this.latitude, true, false);
	},

	setClickEvent: function (eventHandler) {
		this.clickEventHandler = eventHandler;
	},

	showHoverSymbol: function () {
		if (this.hoverUrl != "") {
			if ($(this.domId).style.filter != null) {
				$(this.domId).style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.hoverUrl;+"', sizingMethod='scale');"
			} else {
				$(this.domId).src = this.hoverUrl;
			}
		}
	},

	showRegularSymbol: function () {
		if ($(this.domId).style.filter != null) {
			$(this.domId).style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.symbolUrl;+"', sizingMethod='scale');"
		} else {
			$(this.domId).src = this.symbolUrl;
		}
	}

}),

ktApiRectangle = Base.extend ({
	north: 0,
	south: 0,
	east: 0,
	west: 0,
	domId: '',
	title: '',
	ppmObject: null,
	minimumDisplaySize: 50,
	borderColor: "#000000",
	backgroundColor: "#ffcccc",
	hoverColor: "#ccffcc",
	opacity: 40,
	hoverHtml: '',
	infoHtml: '',
	infoUrl: '',
	infoTitle: '',
	above: '',
	below: '',

	constructor: function (longitudeSW, latitudeSW, longitudeNE, latitudeNE, ppmObject, domId, title) {
		this.north = latitudeNE;
		this.south = latitudeSW;
		this.east = longitudeNE;
		this.west = longitudeSW;
		this.ppmObject = ppmObject;
		if (domId !=  null && domId != "") {
			this.domId = domId;
		} else { //Developer didn't provide a DOM-ID. Poeser Pursche!
			this.domId = "rectangle_"+this.north+"_"+this.east+"_"+this.south+"_"+this.west;
		}
		if (title != null && title != "") {
			this.title = title;
		} else { //Developer didn't provide a title. Werft den Purschen zu Poden!
			this.title = " ";
		}
		this.ppmObject.apiRectangles.push (this);

	},

	draw: function () {
		var geoWidth = this.east-this.west;
		var geoHeight = this.north-this.south;
		var pixelWidth = Math.round(geoWidth/(METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*10));
		var pixelHeight = Math.round(geoHeight/(METER_PER_PIXEL[this.ppmObject.zoomLevel-1]*10));

		if ($(this.domId) != null) {
			Element.remove (this.domId);
		}

		if (pixelWidth < 5 || pixelHeight < 5) {
			return;
		}

		//Remove existing div
		if ($(this.domId) != null) {
			Element.remove ($(this.domId));
		}

		var div = document.createElement ("div");
		div.id = this.domId;
		div.style.border = "1px solid "+this.borderColor;
		div.style.zIndex = 2045;
		div.style.width = pixelWidth+"px";
		div.style.position = "absolute";

		div.style.backgroundColor = this.backgroundColor;

		if (div.style.MozOpacity != null) {
			div.style.MozOpacity = this.opacity/100;
		} else if (div.style.opacity != null) {
			div.style.opacity = this.opacity/100;
		}
		if (div.style.filter != null) {
			div.style.filter = ("alpha(opacity="+this.opacity+")");
		}

		var pixelPos = ppmObject.getScreen (this.west, this.north);
		div.style.left = ((pixelPos.x-ppmObject.x)-0.5)+"px";
		div.style.top = (pixelPos.y-ppmObject.y)+"px";

		div.style.height = pixelHeight+"px";

		$(ppmObject.parentNode.id+"_layer_1").appendChild(div);
		
		if (this.below != '') {
			var below = document.createElement ("div");
			Element.update(below, this.below);
			below.style.position="absolute";
			var dim = Element.getDimensions(div);
			below.style.left = ((pixelPos.x-ppmObject.x)-0.5)+"px";
			below.style.top = (pixelPos.y-ppmObject.y+dim.height)+"px";
			below.style.width = dim.width+"px";
			$(ppmObject.parentNode.id+"_layer_"+ppmObject.layercount).appendChild (below);			
		}		
		
		if (this.above != '') {
			var above = document.createElement ("div");
			Element.update(above, this.above);
			above.style.position="absolute";
			$(ppmObject.parentNode.id+"_layer_"+ppmObject.layercount).appendChild (above);			
			var rect = Element.getDimensions(div);
			var dim = Element.getDimensions(above);
			above.style.left = ((pixelPos.x-ppmObject.x)-0.5)+"px";
			above.style.top = (pixelPos.y-ppmObject.y-dim.height)+"px";
			above.style.width = rect.width+"px";

		}
	},

	within: function (longitude, latitude) {
		if (longitude >= this.west &&
			longitude <= this.east &&
			latitude >= this.south &&
			latitude <= this.north) {
				return true;
			} else {
				return false;
			}
	},

	setClickEvent: function (eventHandler) {
		this.clickEventHandler = eventHandler;
	},
	
	setBackgroundColor:function (color) {
		this.backgroundColor = color;
		if ($(this.domId) != null) {
			$(this.domId).style.backgroundColor = color;
		}
	},
	
	setBorderColor: function (color) {
		this.borderColor = color;
		if ($(this.domId) != null) {
			$(this.domId).style.borderColor = color;
		}
	},

	setOpacity: function (opacity) {
		this.opacity = opacity;
		this.draw();
	},

	showInfoWindow: function (infoHtml, infoTitle) {
		if (this.clickEventHandler != null) {
			var cont = this.clickEventHandler();
			if (!cont) {
				return;
			}
		}

		if (infoHtml == null) {
			infoHtml = this.infoHtml;
			infoUrl = this.infoUrl;
		} else {
			infoUrl = "";
		}

		if (infoTitle == null) {
			infoTitle = this.infoTitle;
		}


		var offsetX = (this.east-this.west)/(2 * METER_PER_PIXEL[ppmObject.zoomLevel-1]*10)+ppmObject.apiSettings.offsetXInfoWindowRectangle;
		var offsetY = ppmObject.apiSettings.offsetYInfoWindowRectangle;
		var longitude = this.west+(this.east-this.west)/2;
		var latitude = this.north;
		if ($(this.domId) != null) {
			this.ppmObject.showInfoWindow("infowindow", "ppmid="+ppmObject.parentNode.id+"&title="+encodeURIComponent(infoTitle)+"&url="+infoUrl+"&html="+encodeURIComponent(infoHtml), this.domId, offsetX, offsetY, longitude, latitude, true, false);
		}
	},

	updateInfoWindow: function (infoHtml, infoTitle) {
		this.showInfoWindow (infoHtml, infoTitle);
	}
});

IeIcon = Icon.extend ({
	symbolUrl: '/kt_map/images/POI_infoeintrag.png',
	symbolWidth:23,
	symbolHeight:26,
	offsetX:11,
	offsetY:26,
	type: 'ie',
	entryId: 0,
	title:'',

	showInfoWindow: function () {
		ppmObject.showInfoWindow("infoeintrag", "ppmid="+ppmObject.parentNode.id+"&entryId="+this.entryId, this.domId, 0, 26, this.longitude, this.latitude);
	}
}),

SeIcon = Icon.extend ({
	symbolWidth:23,
	symbolHeight:26,
	offsetX:11,
	offsetY:26,
	type: 'se',
	entryId: 0,

	constructor: function (longitude, latitude, ppmObject,domId, sym, title) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.ppmObject = ppmObject;
		if(this.ppmObject.getLeftEdge() <= longitude && this.ppmObject.getRightEdge() >= longitude && this.ppmObject.getTopEdge() >= latitude && this.ppmObject.getBottomEdge() <= latitude)  {
			if(this.ppmObject.icons.length > 0) {

				fndThs=this.ppmObject.icons.find(function(ic) {
					return (ic.domId == domId);
				});
				if(!fndThs) {
					this.ppmObject.icons.push (this);
				}
			} else {
				this.ppmObject.icons.push (this);
			}

		}
		this.domId = domId;
		this.title=title;
		this.symbolUrl = '/kt_map/images/'+sym+'.png';
	},

	showInfoWindow: function () {
			ppmObject.showInfoWindow("poidetail", "ppmid="+ppmObject.parentNode.id+"&id="+this.entryId, this.domId, 0, 33, this.longitude, this.latitude);
	}
}),

MarkerIcon = Icon.extend ({
	symbolUrl: '/kt_map/images/POI_markierung.png',
	symbolWidth:23,
	symbolHeight:26,
	offsetX:11,
	offsetY:26,
	type: 'marker',
	caption: 'Meine Markierung',
	description: '',
	marker:null,
	title:'',

	constructor: function (longitude, latitude, ppmObject, domId, marker, title) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.ppmObject = ppmObject;
		this.title=marker.displayName;

		if(this.ppmObject.getLeftEdge() <= longitude && this.ppmObject.getRightEdge() >= longitude && this.ppmObject.getTopEdge() >= latitude && this.ppmObject.getBottomEdge() <= latitude)  {
			this.ppmObject.icons.push (this);
		}

		this.domId = domId;
		this.marker=marker;
		this.longitude=marker.longitude;
		this.latitude=marker.latitude;

	},

	showInfoWindow: function () {
		if(this.marker.poiID != null && this.marker.poiID != '') {
			ppmObject.showInfoWindow("poidetail", "ppmid="+ppmObject.parentNode.id+"&id="+this.marker.poiID, this.domId, 0, 33, this.longitude, this.latitude);
		} else {
			ppmObject.showInfoWindow("markerInfowindow", "ppmid="+ppmObject.parentNode.id+"&cid="+(this.marker.markerDBID), this.domId, 0, 33, this.longitude, this.latitude);
		}
	}
}),

Widget =ScreenObject.extend ({
	layer:0,
	template: '',
	ppmObject: null,
	movable: false,
	urlParameters: '',

	constructor: function (ppmObject, template, urlParameters) {
		// Set default layer for new widget, can be changed before drawing
		this.ppmObject = ppmObject;
		if (urlParameters != null) {
			this.urlParameters = "&"+urlParameters;
		}
		this.parentNode = ppmObject.parentNode;
		this.layer = 6;
		this.template = template;
		this.domNode = document.createElement('div');

		this.domNode.style.padding = "0px";
		this.domNode.style.margin = "0px";
		this.ppmObject = ppmObject;
		this.redrawTimeout = null;
		this.domNode.id = ppmObject.parentNode.id+"_"+template+"_container";

		if (this.ppmObject.eagleView == 2 && EVHIDE.indexOf(template) != -1) {
				this.domNode.style.display = "none";
		};

		if (this.ppmObject.eagleView != 2 && EVONLY.indexOf(template) != -1) {
				this.domNode.style.display = "none";
		};

		this.domNode.onselect = function () {
			if (window.event != null) {
				window.event.returnValue = false;
			}
		};

		this.parentNode.ppmObject = ppmObject; // Needed to allow Widgets to access the ppmObject via the Dom Tree
	},

	draw: function (position, zIndex) {
		ppmObject = this.ppmObject;
		ppmObject.widgetsloading++;

		if (ppmObject.widgetPath == null) {
			var widgetPath = "/kt_map/widgets/";
		} else {
			var widgetPath = ppmObject.widgetPath;
			if (widgetPath.substr(widgetPath.length-1,1) != "/") {
				widgetPath += "/";
			}
		}

		if (ppmObject.widgetExtension == null) {
			var widgetExtension = ".php";
		} else {
			var widgetExtension = ppmObject.widgetExtension;
		}

		var myAjax = new Ajax.Updater(
			this.domNode,
			widgetPath+this.template+widgetExtension,
			{
				method: 'get',
				parameters: "ppmid="+this.parentNode.id+this.urlParameters+'&_rnd='+Math.random(),
				evalScripts: true,
				onSuccess: function () {
					ppmObject.irqTasks.updateTransparencies = true;
					ppmObject.irqTasks.makeFoldoutControls = true;
					ppmObject.irqTasks.updateZIndex = true;
				},
				onComplete: function () {
					ppmObject.widgetsloading--;
				}
			});


		if (position != null) {
			switch (typeof(position)) {
				case 'string':
					if (position=="left") {
						if (this.template.match('options_header')) {
							this.ppmObject.leftWidgetHead.appendChild(this.domNode);
						} else {
							this.ppmObject.leftWidgetCol.appendChild(this.domNode);
						}
					}
					if (position=="center") {
						this.ppmObject.centerWidgetCol.appendChild(this.domNode);
					}
					if (position=="right") {
						if (this.template.match('options_header')) {
							this.ppmObject.rightWidgetHead.appendChild(this.domNode);
						} else {
							this.ppmObject.rightWidgetCol.appendChild(this.domNode);
						}
					}
				break;
				case 'object':
					this.domNode.style.position = "absolute";
					this.domNode.style.left = position.x+"px";
					this.domNode.style.top = position.y+"px";
					this.domNode.style.zIndex = 2048;
					this.parentNode.appendChild (this.domNode);
				break;
				default: alert ("Kein gültiger Position Parameter!");
			}
		} else {
			this.domNode.style.position = "absolute";
			this.domNode.style.top = "0px";
			this.domNode.style.left = "0px";
			this.parentNode.appendChild (this.domNode);
		}
		if (zIndex != null) {
			this.domNode.style.zIndex = zIndex;
		}
	}
});

var CheckerBoard = Base.extend ({
	ppmObject:null,

	getTile: function (x,y) {
		return this.matrix [y][x];
	},

	putTile: function (x,y,tile) {
		this.matrix [y][x] = tile;
	},

	constructor: function (x,y, ppmObject) {
		this.matrix = new Array ();
		this.updaters = new Array ();
		this.cols = new Number;
		this.rows = new Number;
		for (rowcount=0; rowcount<y; rowcount++) {
			if ($("ppm_status_table") != null) {
				var tr = document.createElement("tr");
				$("ppm_status_table").appendChild(tr);
				
				var tr2 = document.createElement("tr");
				$("ppm_status_layer2").appendChild(tr2);
				
				var tr3 = document.createElement("tr");
				$("ppm_status_layer3").appendChild(tr3);
			}
			var row = new Array();
			for (colcount=0; colcount<x; colcount++) {
				var tile = new Tile(ppmObject.parentNode, ppmObject);
				row.push(tile);
				if ($("ppm_status_table") != null) {
                	var td = document.createElement("td");
                	td.id = "status_tile_"+colcount+"_"+rowcount;
                	td.style.width="10px";
                	td.style.height="10px";
                	tr.appendChild(td);
                	
                	var td = document.createElement("td");
                	td.id = "status_layer2_"+colcount+"_"+rowcount;
                	td.style.width="10px";
                	td.style.height="10px";
                	tr2.appendChild(td);
                	
                	var td = document.createElement("td");
                	td.id = "status_layer3_"+colcount+"_"+rowcount;
                	td.style.width="10px";
                	td.style.height="10px";
                	tr3.appendChild(td);
                }
			}
			this.matrix.push (row);
		}
		this.cols = x;
		this.rows = y;
		if (ppmObject != null) {
			this.ppmObject = ppmObject;
		}
	},

	rotateLeft: function () {
		for (var i=0; i<this.rows; i++) {
			row = this.matrix[i];
			leftTile = row[0];
			leftTile.longitude += leftTile.ext*2*row.length;
			leftTile.x += (this.cols)*TILESIZE;

			for (j=0; j<this.cols-1;j++) {
				row[j] = row[j+1];
			}

			row[this.cols-1] = leftTile;
			this.matrix[i] = row;
			leftTile.queueForDrawing();
			//leftTile.draw(0);
			//leftTile.draw(1);	
		}
	},

	rotateRight: function () {
		for (i=0; i<this.rows; i++) {
			row = this.matrix[i];
			rightTile = row[this.cols-1];
			rightTile.longitude -= rightTile.ext*2*this.cols;
			rightTile.x -= (this.cols)*TILESIZE;
			for (j=this.cols;j>1;j--) {
				row[j-1] = row[j-2];
			}
			row[0] = rightTile;
			this.matrix[i] = row;
			rightTile.queueForDrawing();
			//rightTile.draw(0);
			//rightTile.draw(1);
		}
	},

	rotateUp: function () {
		topRow = this.matrix[0];
		for (i=0; i<this.cols;i++) {
			currentTile = topRow[i];
			currentTile.latitude -= currentTile.ext*2*this.rows;
			currentTile.y += this.rows*TILESIZE;
			topRow[i] = currentTile;
			currentTile.queueForDrawing();
			//currentTile.draw(0);
			//currentTile.draw(1);			
			
		}


		for (j=0; j<this.rows-1;j++) {
				this.matrix[j] = this.matrix[j+1];
		}

		this.matrix[this.rows-1] = topRow;

	},

	rotateDown: function () {
		bottomRow = this.matrix[this.rows-1];
		for (i=0; i<this.cols;i++) {
			currentTile = bottomRow[i];
			currentTile.latitude += currentTile.ext*2*this.rows;
			currentTile.y -= this.rows*TILESIZE;
			bottomRow[i] = currentTile;
			currentTile.queueForDrawing();
			//currentTile.draw(0);
			//currentTile.draw(1);			
		}

		for (j=this.rows; j>1;j--) {
				this.matrix[j-1] = this.matrix[j-2];
		}

		this.matrix[0] = bottomRow;
	}

});

PpmApi = Base.extend ({
	ppmObject: null
});

Copyright = Base.extend({
	ppmObject: null,
	src: "",
	img: null,
	
	/*
	
	if (this.apiKey == null) {
			ppmCopyright = document.createElement ("img");
			ppmCopyright.style.position = "absolute";
			ppmCopyright.style.marginTop = this.height+"px";
			ppmCopyright.style.zIndex = 512;
			ppmCopyright.style.padding = "2px 5px";
			ppmCopyright.style.fontSize = "9px";
			ppmCopyright.id = "copyright";
			this.parentNode.parentNode.parentNode.insertBefore (ppmCopyright, this.parentNode.parentNode);
			this.copyright = ppmCopyright;
			ppmCopyright.src = "http://www.klicktel.de/kt_map/images/copyright.png";
			if (this.apiKey != null) {
				ppmCopyright.style.backgroundColor = "#ffffff";
			}
		} else {
			ppmCopyright = document.createElement ("img");
			ppmCopyright.style.position = "absolute";
			ppmCopyright.style.bottom = "2px";
			ppmCopyright.style.left = "3px";
			ppmCopyright.id = "copyright";
			if (this.width < 450) {
				ppmCopyright.src = "http://www.klicktel.de/kt_map/images/copyright_minikarte.gif";
			} else {
				ppmCopyright.src = "http://www.klicktel.de/kt_map/images/copyright_api.gif";
			}
			this.parentNode.appendChild (ppmCopyright);
			
		}
	
	*/

	constructor: function (ppmObject) {
		this.ppmObject = ppmObject; //Circular reference, should not be problem since there is only one copyright object
		var img = document.createElement("img");
		if (this.ppmObject.apiKey == null) { //Native klickTel Environment
			img.style.position = "absolute";
			img.style.marginTop = this.ppmObject.height+"px";
			img.style.padding = "2px 5px";
			img.style.fontSize = "9px";
			this.ppmObject.parentNode.parentNode.parentNode.insertBefore (img, this.ppmObject.parentNode.parentNode);
		} else {
			img.style.position = "absolute";
			img.style.bottom = "2px";
			img.style.left = "3px";
			this.ppmObject.parentNode.appendChild (img);
		}
		img.style.zIndex = 512;
		img.id = "copyright";
		this.img = img;
	},
	
	draw: function () {
		var fuellsel = "";
		if ((this.ppmObject.getMapMode() == "map" && this.ppmObject.getUnitsPerPixel() >= 10240) ||
			((this.ppmObject.getMapMode() == "aerial" || this.ppmObject.getMapMode() == "hybrid") && this.ppmObject.getUnitsPerPixel() >= 2560)
		) {
			fuellsel = "_nasa";
		}
		if (this.ppmObject.apiKey == null) { //Native klickTel Environment
			this.img.src = "/kt_map/images/copyright"+fuellsel+".png";
		} else { //API Environment
			if (this.ppmObject.width < 450) {
				this.img.src = "http://"+ktDomain+"/kt_map/images/copyright_minikarte"+fuellsel+".gif";
			} else {
				this.img.src  = "http://"+ktDomain+"/kt_map/images/copyright_api"+fuellsel+".gif";
			}
		}
	}
});

Ppm2 = GeoObject.extend ({
	pageMode:'local',
	zoomLevel: 0,
	ext: 0,
	width:0,
	height:0,
	cols:0,
	rows:0,
	checkerBoard:null,
	parentNode: '',
	mouseDownX:0,
	mouseDownY:0,
	dragging:false,
	x:0,
	y:0,
	forcedLocation:false, // Tells the PPM that the current location was enforced
	zoomSlider: null,
	poi: {
		infoEntries:false,
		braIds: Array (),
		braName: '',
		staticPoi: Array ()
	},
	leftWidgetCol: null,
	centerWidgetCol: null,
	rightWidgetCol: null,

	PpmMarkers: {
		userMarkers:Array(),
		linkMarkers:Array()
	},

	scratchPads: {
		userMarkers:null,
		linkMarkers:null
	},

	markerEditWindow:null,
	markerAddWindow:null,
	aerial:0,
	hybrid:0,
	eagleView: 0,
	irqInterval: null,
	irqTasks: {
		updateTransparencies: false,
		makeFoldoutControls: false,
		updateScratchpads: false,
		updateZindex: false,
		queue: Array()
	},
	irqState: {
		longitude:0,
		latitude:0,
		zoomLevel:0
	},
	destroyedOnMove:false,
	eventHandler: null,
	contextMenuController: null,
	markerController: null,
	eventsDisabled: false,
	badeUpdater: null,
	ieUpdater: null,
	evUpdater:null,
	scoutUpdater: null,
	ivwUpdater: null,
	lastIVWupdate: 0,
	icons: Array (),
	rectangles: Array (),
	hasMoved: false,
	modalDialog: null,
	longitudeHome: 0,
	latitudeHome:0,
	zoomLevelHome:0,
	processes: 0,
	mouseX:0,
	mouseY:0,
	routeId:0,
	poiIeLoading:false,
	poiSeLoading:false,
	minimap: null,
	markerUrlId:null,
	evLongitude: 0,
	evLatitude:0,
	evDirection:-1,
	evDirections: Array (),
	evZoomLevel: 1,
	evX: 0,
	evY: 0,
	evWidth:0,
	evHeight:0,
	evLimitX:0,
	evLimitY:0,
	evRecoverIds: Array (), // Will contain Dom-IDs of Widgets set to display none when switching to Eagle View	evRecoverIds: Array (), //Will contain Dom-IDs of Widgets set to display none when switching to Eagle View
	evTile: null,
	addressMode: 0, // Indicates whether Address or Route Input will be shown. 0 equals Route
	lastAddressMode: -1, //Remembers Adress Mode state at last IRQ
	weather: false,
	trafficjam: false,

	helpStatus:{
		moved:0,
		evNavHover:0,
		zoom:0,
		markerAdd:0,
		trafficJam:0,
		routeInput:0,
		showBusiness:0,
		eagleViewOverlay:0,
		eagleViewAvailable:0,
		eagleViewUnavailable:0
	},

	helpStatusCount:{
		moved:5,
		evNavHover:5,
		zoom:5,
		markerAdd:5,
		trafficJam:5,
		routeInput:5,
		showBusiness:5,
		eagleViewOverlay:5,
		eagleViewAvailable:5,
		eagleViewUnavailable:555
	},

	helpStatusChecked:false,
	helpStatusCheckboxChecked:false,
	scratchPadStatusChecked:false,
	copyright:null,
	scale:null,
	adLayer:null,
	widgetsloading:0, //Counter so we know how many widgets are currently loading
	tilesloading:0,
	tilesrequested:0,
	tilesloaded:0,
	tilesaborted:0,
	noContextMenu: false,
	tenInMap: Array (),
	api: null,
	apiKey: null,
	apiIcons: Array (),
	apiRectangles: Array (),
	infoWindowOpen: false,
	version: 2,
	layercount: 2, //How many div layers will be used
	tilequeues: Array (Array (), Array(), Array()),
	mousespeed: 0,
	initTime: 0,
	ivwinit:false,


	eventHandlers: {
		click: null,
		mouseup: null,
		mousedown: null,
		dblclick: null,
		draw: null,
		iconhoverin: null,
		iconhoverout: null,
		rectanglehoverin: null,
		rectanglehoverout: null
	},

	hoverIcon: null, //Remembers the icon that was hovered during latest IRQ
	hoverRectangle: null,
	widgetPath: null,
	widgetExtension: null,
	ajaxPath:null,
	ajaxExtension: null,
	spacerImage: "/kt_map/images/spacer.gif",
	apiSettings: {
		offsetXInfoWindowPoint:0,
		offsetYInfoWindowPoint:0,
		offsetXInfoWindowRectangle:0,
		offsetYInfoWindowRectangle:0
	},
	initialTrack:0, //Remembers initial Urchin-Tracking for Kartensuche, so it is only called on the first draw

	constructor: function (parentNode, apiKey, widgetPath, widgetExtension, ajaxPath, ajaxExtension) {
		this.initTime = new Date().getTime();
		if (apiKey != null) {
			this.apiKey = apiKey;
			this.api = new PpmApi ();
			this.api.ppmObject = this;
			this.layercount = 1;
		}

		if (widgetPath != null) {
			this.widgetPath = widgetPath;
		} else {
			this.widgetPath = "/kt_map/widgets/";
		}

		if (widgetExtension != null) {
			this.widgetExtension = widgetExtension;
		} else {
			this.widgetExtension = ".php";
		}
		
		if (ajaxPath != null) {
			this.ajaxPath = ajaxPath;
		} else {
			this.ajaxPath = "/kt_map/ajax/";
		}

		if (ajaxExtension != null) {
			this.ajaxExtension = ajaxExtension;
		} else {
			this.ajaxExtension = ".php";
		}

		ppmObject = this;
		parentNode.style.overflow = "hidden";
		try {
  			document.execCommand("BackgroundImageCache", false, true);
		} catch(err) {}
		if (this.apiKey == null) {
			parentNode.style.border = "1px solid black";
		}
		parentNode.style.position = "absolute";

		this.parentNode = parentNode;

		this.badeUpdater = document.createElement ("iframe");
		this.badeUpdater.id = this.parentNode.id+"_badeUpdater";
		document.body.appendChild (this.badeUpdater);
		callbackSe = this.updateSe;
		Event.observe(this.badeUpdater, "load", function(e){callbackSe(e, ppmObject)});
		this.badeUpdater.style.visibility = "hidden";
		this.badeUpdater.style.height="0px";
		this.badeUpdater.style.width="0px";
		this.ieUpdater = document.createElement ("iframe");
		this.ieUpdater.id = this.parentNode.id+"_ieUpdater";
		this.ieUpdater.style.visibility = "hidden";
		this.ieUpdater.style.height="0px";
		this.ieUpdater.style.width="0px";
		document.body.appendChild (this.ieUpdater);
		callbackIe = this.updateIe;
		Event.observe(this.ieUpdater, "load", function(e){callbackIe(e, ppmObject)});
		this.scoutUpdater = document.createElement ("iframe");
		document.body.appendChild (this.scoutUpdater);
		this.scoutUpdater.style.visibility = "hidden";
		this.scoutUpdater.style.height="0px";
		this.scoutUpdater.style.width="0px";
		this.evUpdater = document.createElement ("iframe");
		this.evUpdater.id = this.parentNode.id+"_evUpdater";
		this.evUpdater.style.visibility = "hidden";
		this.evUpdater.style.height="0px";
		this.evUpdater.style.width="0px";
		document.body.appendChild (this.evUpdater);
		callbackEv = this.updateEv;
		Event.observe(this.evUpdater, "load", function(e){callbackEv(e, ppmObject)});
		this.evUpdater.style.position="absolute";
		this.ivwUpdater = document.createElement ("iframe");
		this.ivwUpdater.id = this.parentNode.id+"_ivwUpdater";
		document.body.appendChild (this.ivwUpdater);
		callbackIVW = this.updateIVW;
		Event.observe(this.ivwUpdater, "load", function(e){callbackIVW(e, ppmObject)});
		this.ivwUpdater.style.visibility = "hidden";
		this.ivwUpdater.style.height="0px";
		this.ivwUpdater.style.width="0px";

		mapDimensions = Element.getDimensions (parentNode);
		this.width = mapDimensions.width;
		this.height = mapDimensions.height;

		this.copyright = new Copyright (this);

		if (this.width > 450) {
	
			this.cols = Math.ceil(this.width/TILESIZE)+1;
			this.rows = Math.ceil(this.height/TILESIZE)+1;
	
			this.checkerBoard = new CheckerBoard (this.cols, this.rows, this);
		}
		
		for (i=1;i<=this.layercount;i++) {
			layer = new ScreenObject (parentNode);
			layer.setId(parentNode.id+"_layer_"+i);
			layer.x = 0;
			layer.y = 0;
			layer.zIndex = (i-1)*10;
			layer.width = this.width;
			layer.height = this.height;
			layer.draw ();
		}
		

		div = document.createElement ("div");
		div.style.position = "absolute";
		div.style.top = "0px";
		div.style.left = "0px";
		div.style.zIndex = 32768;
		div.style.width = this.width+"px";
		div.style.height = this.height+"px";
		div.style.display = "none";
		div.id = this.parentNode.id+"_bitte_warten";
		this.parentNode.appendChild (div);
		if (this.apiKey == null) {
			var ajax = new Ajax.Updater (div, "/kt_map/widgets/bitte_warten.php");
		}
		$(parentNode).style.backgroundColor = '#dcdccd';
		this.eventHandler = new EventHandler (this);
		this.contextMenuController = new contextMenuController (this);
		this.markerController = new markerController (this);
		if (this.width >= 450) {
			this.buildLayoutTable ();
		}
		ppmObjects.push(this);
				

		adLayer = document.createElement ("iframe");
		adLayer.allowTransparency="true";
		adLayer.style.width = "200px";
		adLayer.style.height = "150px";
		//adLayer.style.borderRight = "1px solid black";
		//adLayer.style.borderTop = "1px solid black";
		adLayer.style.position = "absolute";
		adLayer.style.left = "0px";
		adLayer.style.bottom = "0px";
		adLayer.style.zIndex = 512;
		adLayer.style.display = "none";
		adLayer.style.overflow = "hidden";
		adLayer.style.padding = "0";
		adLayer.style.border = "none";

		this.parentNode.appendChild (adLayer);
		this.adLayer = adLayer;

		toolTipDIV=document.createElement('div');
		toolTipDIV.id=this.parentNode.id+'_tooltip';
		toolTipDIV.style.display='none';
		toolTipDIV.style.position='absolute';
		toolTipDIV.style.top='1px';
		toolTipDIV.style.left='1px';
		toolTipDIV.style.border='1px solid black';
		toolTipDIV.style.backgroundColor='#FFFFCE';
		toolTipDIV.style.padding='2px 4px 2px 4px';
		toolTipDIV.style.fontFamily='Arial,Helvetica,Sans-Serif';
		toolTipDIV.style.fontSize='11px';
		toolTipDIV.style.color='black';
		toolTipDIV.style.zIndex=4096;
		this.parentNode.appendChild(toolTipDIV);

		if (this.apiKey == null) {
			scale = document.createElement ("img");
			scale.style.position = "absolute";
			scale.style.right = "0px";
			scale.style.bottom = "0px";
			scale.style.zIndex = 512;
			this.parentNode.appendChild (scale);
			this.scale = scale;
		}
		ppmObject.urchinLog(100);
		ppmObject.dbLog ("init", 0);
		this.apiLog('InitialerAufruf');


	},
	
	empty: function () {
		
	},
	
	tileLoaded: function () {
		this.tilesloading--;
		this.tilesloaded++;
	},
	
	tileAborted: function () {
		this.tileloading--;
		this.tilesaborted++;
	},
	
	tileRequested: function () {
		this.tilesloading++;
		this.tilesrequested++;
	},
	
	drawFromTilequeue: function () {
		if (this.mousespeed > MOUSE_THRESHOLD) {
			return;
		}
		if (this.tilequeues.flatten().length > 0) {
			for (var i=0; i<this.tilequeues.length;i++) {

			/*
				if (this.tilequeues[i].length > 0) {
					tile = this.tilequeues[i].shift ();
					break;

				}
			*/
				var l = this.tilequeues[i].length;
				for (var j=0; j<l;j++) {
					tile = this.tilequeues[i].shift ();
					if (tile != null) {
						tile.draw (i);
					}
				}
			}	
		}
	},

	buildPoiString: function () {
		if (this.apiKey != null) {
			return "";
		}
		poiString = "";
		var count = 0;
		
		//Default POI for some zoomlevels
		
		if (this.zoomLevel <= 5) {
			poiString += 7356;
			count++;
		}
		
		if (this.zoomLevel <= 7) {
			count+=4;
			if (count>4) {
				poiString += "|";
			}
			poiString += "7380;3|";
			poiString += "7380;11|";
			poiString += "7380;12|";
			poiString += "7383";			
		}
		
		this.poi.staticPoi.each (function(staticPoi) {
			count++;
			if (count>1) {
				poiString += "|";
			}
			poiString += staticPoi;
		});
		
		if (this.poi.braIds.indexOf("765") != -1 || this.poi.braIds.indexOf("778") != -1) {
			if (count>1) {
				poiString += "|";
			};
			poiString += "7326";
			count++;
		}
		
		if (this.poi.braIds.indexOf("19949") != -1) {
			if (count>1) {
				poiString += "|";
			};
			poiString += "7311";
			count++;
		}
		return poiString;
	},

	addStaticPoi: function (poiType) {
		var numericValue = 0;
		if (typeof poiType == "string") {
			var poi = STATIC_POI.find(function(poi){return poi.key == poiType.toLowerCase()});
			if (poi != null) {
				numericValue = poi[1];
			}
		}
		if (numericValue != 0) {
			if (!this.poi.staticPoi.find(function (poiType) {return poiType == numericValue})) {
				this.poi.staticPoi.push (numericValue);
			}
		}
	},

	removeStaticPoi: function (poiType) {
		var numericValue = 0;
		if (typeof poiType == "string") {
			var poi = STATIC_POI.find(function(poi){return poi.key == poiType.toLowerCase()});
			if (poi != null) {
				numericValue = poi[1];
			}
		}
		if (numericValue != 0) {
			this.poi.staticPoi = this.poi.staticPoi.reject (function (poi) {return poi == numericValue});
		}
	},

	emptyBraidPois: function(ppmObject)
	{
		ppmObject.poi.braIds.clear();
		ppmObject.poi.braName = "";
		ppmObject.updatePoiLayer();
		ppmObject.draw();
	},

	getPageType:function() {
		if(document.location.href.match(/routenplaner/i)) {
			return "Routenplaner";
		} else {
			return "Lokale Suche";
		}
	},

	dbLog: function (logEvent, logRouteId, status) {
		return; //Temporary disabled
		url="http://"+location.hostname+this.ajaxPath+"dblog"+this.ajaxExtension;
		pars="event="+logEvent+"&route_id="+logRouteId+"&status="+status;
		dbLogRequest = new Ajax.Request (
			url,
			{
				method: 'get',
				parameters: pars
			});
	},

	apiLog: function (utmFile) {
		if (this.apiKey == null || ktApiKeys == null) { //Only log if API-Key is set
			return;
		}
		apiKey = this.apiKey;
		var apiUser = ktApiKeys.detect (function (testUser) {
				return testUser.key == apiKey;
			});
		if (apiUser != null && typeof urchinTracker != 'undefined') {
			var trackValue = '/'+apiUser.logname+'/'+utmFile;
			urchinTracker(trackValue);
			if (typeof(dcsMultiTrack) != "undefined") {
				dcsMultiTrack("DCSext.mapAPIUser", apiUser.logname, "DCSext.mapAPIAction", utmFile);
			}			
		}
	},
	
	urchinDirect: function (utmFile) { //Exrem wichtig, everything else must fallengelassen werden
		if (urchinTracker != null) {
			urchinTracker (utmFile);
		}
	},

	urchinLog: function (utmId, utmContent)
	{
		if (this.apiKey != null) {
			return;
		}
		url="http://"+location.hostname+this.ajaxPath+"urchin"+this.ajaxExtension;
		pars="utm_id="+utmId;
		if(utmContent != null) {
			pars+='&utm_content='+escape(utmContent);
		} else {
			pars+='&utm_content='+escape(this.getPageType());
		}
		pars+='&_rnd='+Math.random();
		ppmObject.urchinRequest = new Ajax.Request (
			url,
			{
				method:'get',
				parameters:pars,
				onComplete:function() { localLog('urchinLogged'); }
			}
		);
	},

	IVWLog: function ()
	{
		if (this.apiKey == 2277 && this.ivwinit == false) { //Skip first ivw call for DerWesten
			this.ivwinit=true;
			return;
		}
				
		url="http://"+location.hostname+this.ajaxPath+"ivw"+this.ajaxExtension;
		if (this.getPageType() == "Routenplaner")
			url+='?target='+escape("routenplaner");
		else
			url+='?target='+escape("kartensuche");
		if (this.apiKey != null) {
			url = 'http://www.klicktel.de/kt_map/ajax/ivw.php?target='+escape("kartensuche");
			url+="&apikey="+this.apiKey;
			switch (this.getMapMode()) {
				case "hybrid":
					url+="&mapmode=karte_hybrid";
				break;
				case "eagle":
					url+="&mapmode=karte_ev";
				break;
				case "aerial":
					url+="&mapmode=karte_ev"; //So von der WAZ gewünscht
				break;
				default:
					url+="&mapmode=karte";
				break;
			}
		}
		url +='&_rnd='+Math.random();
		var zeit = new Date();
		if (zeit.getTime() - this.lastIVWupdate > 1500) {
			this.ivwUpdater.src=url;
			this.lastIVWupdate = zeit.getTime();
		}
		this.ivwinit=true;
	},

	
	updateEvAvailability: function () {
		if (this.zoomLevel <= 5) {
			if (this.apiKey != null) {
				//this.evUpdater.src = "http://www.klicktel.de/kt_map/ajax/overlay_"+this.longitude+"_"+this.latitude+"_"+(this.width*METER_PER_PIXEL[this.zoomLevel-1]*10)+"_.gif";
			} else {
				//this.evUpdater.src = "/kt_map/ajax/overlay.php?x="+this.longitude+"&y="+this.latitude+"&radius="+this.width*METER_PER_PIXEL[this.zoomLevel-1]*10;
				this.evUpdater.src = this.ajaxPath+"overlay_"+this.longitude+"_"+this.latitude+"_"+(this.width*METER_PER_PIXEL[this.zoomLevel-1]*10)+"_.gif";
			}
		}
	},

	universalCallback: null,

	showHintBox: function (message, timeout) {
		if (timeout == 0) {
			timeout = 5;
		}
		div = document.createElement ("div");
		div.style.backgroundColor = "#ffff99";
		div.style.border = "1px solid black";
		div.style.width = "400px";
		div.style.height = "200px";
		div.style.top = "50px";
		div.style.left = "50px";
		div.style.fontSize = "12px";
		Element.update (div, message);
		div.style.margin="auto";
		div.style.position = "absolute";
		div.style.zIndex = 16384;
		this.parentNode.appendChild (div);

	},

	showAdLayer: function (distance) {
		this.adLayer.style.display = "block";
		this.adLayer.src = this.ajaxPath+"adlayer"+this.ajaxExtension+"?distance="+parseInt(distance);
	},

	hideAdLayer: function () {
		this.adLayer.style.display="none";
	},

	showInfoWindow:function (name, parameters, poiId, offsetX, offsetY, longitude, latitude, fitToWindow, hidePoi) {
		if (hidePoi == null) {
			hidePoi = true;
		}
		if (offsetX == null) {
			offsetX = 0;
		}
		if (offsetY == null) {
			offsetY = 0;
		}
		if ($(this.parentNode.id+"_infowindow") != null) {
			oldPoiId = $(this.parentNode.id+"_infowindow").poiId;
			Element.remove ($(this.parentNode.id+"_infowindow"));
			if ($(oldPoiId) != null) {
				$(oldPoiId).style.visibility = "visible";
			}
		} else {
			//console.log ("Nothing to remove!");
		}
		if ($(this.parentNode.id+"_infowindow") != null) {
			Element.remove ($(this.parentNode.id+"_infowindow"));
		}
		var div = document.createElement ("div");
		div.id = this.parentNode.id+"_infowindow";
		div.style.position = "absolute";
		div.style.visibility = "hidden";
		ppmObject = this;
		url=ppmObject.widgetPath+name+ppmObject.widgetExtension;
		parameters+='&rnd='+Math.random();
		var myAjax = new Ajax.Updater(
			div,
			url,
			{
				method: 'get',
				parameters: parameters,
				evalScripts: true,
				onComplete: function () {
					div.style.zIndex = 2050;
					$(ppmObject.parentNode.id).appendChild (div);
					dimensions = div.getDimensions();
					if (ppmObject.eagleView < 2) {
						div.style.height = dimensions.height+"px";
						div.style.width = dimensions.width+"px";
						div.poiId = poiId;
						if (hidePoi == true) {
							$(poiId).style.visibility = "hidden";
						}
						if (fitToWindow != null && fitToWindow == true) {
							div.style.left = (parseInt($(poiId).style.left)+ppmObject.x+offsetX-dimensions.width/2)+"px";
							div.style.top = (parseInt($(poiId).style.top)+ppmObject.y+offsetY-dimensions.height)+"px";
							div.style.visibility = "visible";

							//Now check if everything fits on the map

							windowPos = Position.cumulativeOffset(div);
							windowLeftEdge = windowPos[0];
							windowRightEdge = windowPos[0]+dimensions.width;
							windowTopEdge = windowPos[1];
							windowBottomEdge = windowPos[1]+dimensions.height;

							mapPos = Position.cumulativeOffset(ppmObject.parentNode);
							mapLeftEdge = mapPos[0];
							mapRightEdge = mapPos[0]+ppmObject.width;
							mapTopEdge = mapPos[1];
							mapBottomEdge = mapPos[1]+ppmObject.height;

							var correctionX = 0;
							var correctionY = 0;

							if (windowLeftEdge < mapLeftEdge) {
								correctionX = mapLeftEdge - windowLeftEdge;
							}

							if (windowRightEdge > mapRightEdge) {
								correctionX = mapRightEdge - windowRightEdge;
							}

							if (windowTopEdge < mapTopEdge) {
								correctionY = mapTopEdge - windowTopEdge;
							}

							if (windowBottomEdge > mapBottomEdge) {
								correctionY = mapBottomEdge - windowBottomEdge;
							}

							ppmObject.pan (correctionX,correctionY);

						} else {
							div.style.left = (parseInt($(poiId).style.left)+ppmObject.x+offsetX)+"px";
							div.style.top = (parseInt($(poiId).style.top)+ppmObject.y+offsetY-dimensions.height)+"px";
							div.style.visibility = "visible";
							ppmObject.moveToGeo(longitude, latitude);
						}
					} else {
						ppmObject.processes++;
						ppmObject.evTile.appendChild (div);
						div.style.height = dimensions.height+"px";
						div.style.width = dimensions.width+"px";
						div.poiId = "ev_"+poiId;
						$("ev_"+poiId).style.visibility = "hidden";
						var divX = (parseInt($("ev_"+poiId).style.left)+offsetX);
						var divY = (parseInt($("ev_"+poiId).style.top)+offsetY-dimensions.height);
						div.style.left = divX+"px";
						div.style.top = divY+"px";
						div.style.visibility = "visible";

						var tileX = parseInt (ppmObject.evTile.style.left);
						var screenX = divX+tileX; // Pixel position of marker from left edge of visible PPM area
						moveByX = (-1)*(screenX-ppmObject.width/2);

						var tileY = parseInt (ppmObject.evTile.style.top);
						var screenY = divY+dimensions.height+tileY; // Pixel position of marker from left edge of visible PPM area
						moveByY = (-1)*(screenY-ppmObject.height/2);

						// Check if EVTile will move out of bounds
						if (ppmObject.evX+moveByX > ppmObject.evLimitX) {
							moveByX = ppmObject.evLimitX-ppmObject.evX;
						}

						if (ppmObject.evX+moveByX < (-1)*ppmObject.evLimitX) {
							moveByX = (-1)*(ppmObject.evLimitX+ppmObject.evX);
						}

						if (ppmObject.evY+moveByY > ppmObject.evLimitY) {
							moveByY = ppmObject.evLimitY-ppmObject.evY;
						}
						if (ppmObject.evY+moveByY < (-1)*ppmObject.evLimitY) {
							moveByY = (-1)*(ppmObject.evLimitY+ppmObject.evY);
						}

						ef = new Effect.MoveBy(ppmObject.evTile, moveByY, moveByX,
						{
							afterFinish: function () {
								ppmObject.evX += moveByX;
								ppmObject.evY += moveByY;
								ppmObject.processes--;
							}
						});
					}
				}
			}
		);
		this.infoWindowOpen = true;
	},

	hideInfoWindow: function() {
		if ($(this.parentNode.id+"_infowindow") != null) {
			oldPoiId = $(this.parentNode.id+"_infowindow").poiId;
			if ($(oldPoiId) != null) {
				$(oldPoiId).style.visibility = "visible";
			}
			$(this.parentNode.id+"_infowindow").style.display = "none";
		}
		this.infoWindowOpen = false;
	},

	updateInfoWindow: function (html) {
		if ($(this.parentNode.id+"_infowindow") != null) {
			Element.update ($(this.parentNode.id+"_infowindow"), html);
		}
	},

	foldSidebar:function (sideBar) {
		if (sideBar == "left") {
			sideBarNode = this.leftWidgetCol;
		} else {
			sideBarNode = this.rightWidgetCol;
		}
		controls = sideBarNode.getElementsByTagName ("img");
		controls.each (function (control){
			new Effect.Fade (control);
		})

	},

	cleanUpIcons: function () {
		currentIcons = Array ();
		ppmObject = this;
		var lastIcon=null;

		for(i=0; i<this.icons.length; i++) {
			icon=this.icons[i];
			if ((icon.longitude > ppmObject.getLeftEdge()) &&
				(icon.longitude < ppmObject.getRightEdge()) &&
				(icon.latitude < ppmObject.getTopEdge()) &&
				(icon.latitude > ppmObject.getBottomEdge())) {
				currentIcons.push (this.icons[i]);
			} else {
				if ($(icon.domId) != null) {
					Element.remove ($(icon.domId));
				}
				if (icon.type == "api") {
					icon.onMap = false;
				}
			}
		}
		this.icons = currentIcons;
	},

	buildLayoutTable: function () {
		leftMargin = 0;
		rightMargin = 0;
		topMargin = 0;
		leftColumnWidth = 200;
		rightColumnWidth = 240;
		topRowHeight = 26;
		centerColumnWidth = this.width-leftMargin-rightMargin-leftColumnWidth-rightColumnWidth-4;

		tableContainer = document.createElement ("div");

		this.leftWidgetHead = document.createElement("div");
		this.leftWidgetHead.style.position = "absolute";
		this.leftWidgetHead.style.zIndex = "2048";
		this.leftWidgetHead.style.width = leftColumnWidth+"px";
		this.leftWidgetHead.style.left = "0px";
		this.leftWidgetHead.style.top = "0px";

		this.leftWidgetCol = document.createElement("div");
		this.leftWidgetCol.style.position = "absolute";
		this.leftWidgetCol.style.zIndex = "2048";
		this.leftWidgetCol.style.width = leftColumnWidth+"px";
		this.leftWidgetCol.style.left = "0px";
		this.leftWidgetCol.style.top = topRowHeight+"px";

		this.centerWidgetCol = document.createElement("div");
		this.centerWidgetCol.style.position = "absolute";
		this.centerWidgetCol.style.zIndex = "2048";
		this.centerWidgetCol.style.width = centerColumnWidth+"px";
		this.centerWidgetCol.style.left = (leftColumnWidth+1)+"px";
		this.centerWidgetCol.style.top = "0px";

		this.rightWidgetHead = document.createElement("div");
		this.rightWidgetHead.style.position = "absolute";
		this.rightWidgetHead.style.zIndex = "2048";
		this.rightWidgetHead.style.left = (leftColumnWidth+centerColumnWidth+1)+"px";
		this.rightWidgetHead.style.top = "0px";
		this.rightWidgetHead.style.width = rightColumnWidth+"px";

		this.rightWidgetCol = document.createElement("div");
		this.rightWidgetCol.style.position = "absolute";
		this.rightWidgetCol.style.zIndex = "2048";
		this.rightWidgetCol.style.left = (leftColumnWidth+centerColumnWidth+1)+"px";
		this.rightWidgetCol.style.top = topRowHeight+"px";
		this.rightWidgetCol.style.width = rightColumnWidth+"px";

		this.parentNode.appendChild(this.leftWidgetHead);
		this.parentNode.appendChild(this.leftWidgetCol);
		this.parentNode.appendChild(this.centerWidgetCol);
		this.parentNode.appendChild(this.rightWidgetHead);
		this.parentNode.appendChild(this.rightWidgetCol);
	},


	buildCheckerBoard: function () {
		for (y=0; y<this.checkerBoard.rows; y++) {
			for (x=0; x<this.checkerBoard.cols; x++) {
            	var tile = new Tile ($(this.parentNode.id+"_layer_1"), this);
                tile.longitude = this.longitude;
                tile.latitude = this.latitude;
                tile.x = x*TILESIZE;
                tile.y = y*TILESIZE;
                tile.domNode.id = "tile_"+x+"_"+y;
                this.checkerBoard.putTile(x,y,tile);
        	}
        }
	},

	markCenter: function () {
		d = document.createElement("div");
		d.style.position = "absolute";
		d.style.width="4px";
		d.style.height="4px";
		d.style.border="1px solid black";
		d.style.left = (Math.round(this.width/2)-2)+"px";
		d.style.top = (Math.round(this.height/2)-2)+"px";
		this.parentNode.appendChild(d);
	},

	//Konvertierung Geokoordinaten
	getKlickTel: function (longitude, latitude) {
		var a      = 6378137;     // earth radius
      	var e      = 0.081819191; // eccentricity
      	var p0     = 46.5;        // centre of projection
      	var p1     = 40;          // first parallel in degrees
      	var p2     = 55;          // second parallel in degrees
      	var l      = 6;           // centre meridian in degrees

		var phi0 = ( p0 * Math.PI ) / 180;
   		var phi1 = ( p1 * Math.PI ) / 180;
   		var phi2 = ( p2 * Math.PI ) / 180;
   		var lambda0 = ( l * Math.PI ) / 180;

   		// Temporary variables
		var n = Math.log( Math.cos(phi1 ) / Math.cos(phi2 ) ) / Math.log( Math.tan( ( Math.PI / 4 ) + ( phi2 / 2 ) ) / Math.tan( ( Math.PI / 4 ) + ( phi1 / 2 ) ) );

		var f = ( Math.cos( phi1 ) * Math.pow( Math.tan( ( Math.PI / 4 ) + ( phi1 / 2 ) ), n ) ) / n;

		var rho0 = ( a * f ) / Math.pow( Math.tan( ( Math.PI / 4 ) + ( phi0 / 2 ) ), n );

		// Transform WGS84 to klickTel internal
		var phi = ( longitude * Math.PI ) / 180;
		var lambda = ( latitude * Math.PI ) / 180;
		var rho = ( a * f ) / Math.pow( Math.tan( ( Math.PI / 4 ) + ( phi / 2 ) ), n );
		var ny = n * ( lambda - lambda0 );

		var x = 50000000 + Math.round( ( 10 * rho * Math.sin( ny ) ));
		var y = 50000000 + Math.round( ( 10 * ( rho0 - ( rho * Math.cos( ny ) ) ) ));
		return [x, y];
	},

	getWGS84: function (longitude, latitude) {
		var a      = 6378137;     // earth radius
      	var e      = 0.081819191; // eccentricity
      	var p0     = 46.5;        // centre of projection
      	var p1     = 40;          // first parallel in degrees
      	var p2     = 55;          // second parallel in degrees
      	var l      = 6;           // centre meridian in degrees

		var phi0 = ( p0 * Math.PI ) / 180;
   		var phi1 = ( p1 * Math.PI ) / 180;
   		var phi2 = ( p2 * Math.PI ) / 180;
   		var lambda0 = ( l * Math.PI ) / 180;

   		// Temporary variables
		var n = Math.log( Math.cos(phi1 ) / Math.cos(phi2 ) ) / Math.log( Math.tan( ( Math.PI / 4 ) + ( phi2 / 2 ) ) / Math.tan( ( Math.PI / 4 ) + ( phi1 / 2 ) ) );

		var f = ( Math.cos( phi1 ) * Math.pow( Math.tan( ( Math.PI / 4 ) + ( phi1 / 2 ) ), n ) ) / n;

		var rho0 = ( a * f ) / Math.pow( Math.tan( ( Math.PI / 4 ) + ( phi0 / 2 ) ), n );

		var x = (longitude - 50000000)/10;
		var y = (latitude - 50000000)/10;
		var my = Math.atan(x / (rho0 - y));
		var lambda = my/n + lambda0;
		var rho = Math.sqrt(Math.pow(x,2) + Math.pow((rho0 - y),2));
		if (n < 0) {
			rho = -rho;
		}

		var phi = 2*Math.atan(Math.pow((a*f/rho),(1/n))) - Math.PI/2;
		var LongitudeWGS84 = (phi*180/Math.PI);
		var LatitudeWGS84 = (lambda*180/Math.PI);
		return [LongitudeWGS84, LatitudeWGS84];

	},



	setCenter: function (klickTelPoint, zoomLevel) {
		this.longitude = klickTelPoint.longitude;
		this.latitude = klickTelPoint.latitude;
		if (zoomLevel != null) {
			this.setZoomLevel (zoomLevel);
		}
	},

	getLeftEdge: function () {
		return this.longitude-(this.width/2)*this.getUnitsPerPixel(); 
	},

	getTopEdge: function () {
		return this.latitude+(this.height/2)*this.getUnitsPerPixel();
	},

	getRightEdge: function () {
		return this.longitude+(this.width/2)*this.getUnitsPerPixel();
	},

	getBottomEdge: function () {
		return this.latitude-(this.height/2)*this.getUnitsPerPixel();
	},

	getGeo: function (x,y,returnFloat) {
		var upp = this.getUnitsPerPixel();
		if (returnFloat == null || returnFloat == false) {
			var lo = Math.round(this.getLeftEdge()+x*upp);
			var la = Math.round(this.getTopEdge()-y*upp);
		} else {
			var lo = this.getLeftEdge()+x*upp;
			var la = this.getTopEdge()-y*upp;
		}
		return ({longitude:lo, latitude:la});
	},

	getScreen: function (longitude, latitude) {
		// Return screen coordinates for longitude and latitude
		var upp = this.getUnitsPerPixel();
		offsetX = (longitude-this.longitude)/upp;
		offsetY = (this.latitude-latitude)/upp;
		return ({x:Math.round(this.width/2+offsetX), y: Math.round(this.height/2+offsetY)});
	},

	getUnitsPerPixel: function () {
		return METER_PER_PIXEL[this.zoomLevel-1]*UNITS_PER_METER;
	},

	setZoomLevel: function (zoomLevel, noslide) {
		if (this.eagleView == 1 && zoomLevel > 5) {
			this.evLeave();
		}
		if (this.zoomLevel != 0) {
			if (zoomLevel < this.zoomLevel) {
				this.apiLog ("Zoom-In");
			}
			if (zoomLevel > this.zoomLevel) {
				this.apiLog ("Zoom-Out");
			}
		} 
		this.zoomLevel = zoomLevel;
		this.helpStatus.zoom++;
		this.ext = UNITS_PER_METER*(METER_PER_PIXEL[zoomLevel-1]*TILESIZE/2);
		if ($(this.parentNode.id+"_track1") != null && noslide == null) {
			this.zoomSlider.setValue ((12-zoomLevel)*6);
		}

		if ($(this.parentNode.id+"_mapmode_eagle") != null) {
			if (zoomLevel <= 5) {
				this.evOptionEnable();
			} else {
				this.evOptionDisable();
			}
		}
		this.setViewCookie();
	},

	getExtend: function () {
		return (Math.max(this.width, this.height)*this.getUnitsPerPixel()/2);
	},

	evSetZoomLevel: function (zoomLevel, noslide) {
		this.evZoomLevel = zoomLevel;
		if ($(this.parentNode.id+"_track2") != null && (noslide == null || noslide == false)) {
			sliderValue = (1-zoomLevel)*36;
			this.eagleSlider.setValue (sliderValue);
		}
	},

	evZoomOut: function (noslide) {
		if (noslide == null) {
			var noslide = false;
		}
		if (this.evZoomLevel == 1) { //Can't zoom in any further;
			return;
		}
		this.processes++;
		evCenterX = Math.round(this.evWidth/2-this.evX);
		evCenterY = Math.round(this.evHeight/2-this.evY);
		this.evSetZoomLevel (this.evZoomLevel+1, noslide);
		ppmObject = this;
		query = this.ajaxPath+"evgetgeo"+this.ajaxExtension;
		pars="x="+this.evLongitude+"&y="+this.evLatitude+"&d="+this.evDirection+"&screenx="+evCenterX+"&screeny="+evCenterY+'&_rnd='+Math.random();
		var ajGeo = new Ajax.Request (
			query, {
				parameters: pars,
				method: 'get',
				onComplete: function (originalRequest) {
					json = eval("(" + originalRequest.responseText + ")");
					longitude = json.longitude;
					latitude = json.latitude;
					query = ppmObject.ajaxPath+"evgetpixel"+ppmObject.ajaxExtension;
					pars = "centerX="+ppmObject.evLongitude+"&centerY="+ppmObject.evLatitude+"&dir="+ppmObject.evDirection+"&longitude="+longitude+"&latitude="+latitude+'&_rnd='+Math.random();
					var ajPixel = new Ajax.Request (
						query, {
							parameters: pars,
							method: 'get',
							onComplete: function (originalRequest) {
								json = eval("(" + originalRequest.responseText + ")");
								if (ppmObject.evZoomLevel == 1) {
									x = json.x/3;
									y = json.y/3;
								} else {
									x = json.x;
									y = json.y;
								}
								evX = Math.round(ppmObject.evWidth/2-x);
								evY = Math.round(ppmObject.evHeight/2-y);
								if (evX > ppmObject.evLimitX) {
									evX = ppmObject.evLimitX;
								}
								if (evX < (-1)*ppmObject.evLimitX) {
									evX = (-1)*ppmObject.evLimitX;
								}
								if (evY > ppmObject.evLimitY) {
									evY = ppmObject.evLimitY;
								}
								if (evY < (-1)*ppmObject.evLimitY) {
									evY = (-1)*ppmObject.evLimitY;
								}
								ppmObject.evSwitch (evX, evY, ppmObject.evDirection, ppmObject.evZoomLevel, ppmObject.evLongitude, ppmObject.evLatitude)
								//ppmObject.evDrawTile (true, true);
								ppmObject.processes--;
							}
						}
					);
				}
			});
	},

	evZoomIn: function (noslide) {
		if (this.evZoomLevel == 0) { //Can't zoom in any further;
			return;
		}
		if (noslide == null) {
			var noslide = false;
		}
		this.processes++;
		evCenterX = Math.round(this.evWidth/2-this.evX)*3;
		evCenterY = Math.round(this.evHeight/2-this.evY)*3;
		this.evSetZoomLevel (this.evZoomLevel-1, noslide);
		ppmObject = this;
		query = this.ajaxPath+"evgetgeo"+this.ajaxExtension;
		pars="x="+this.evLongitude+"&y="+this.evLatitude+"&d="+this.evDirection+"&screenx="+evCenterX+"&screeny="+evCenterY+'&_rnd='+Math.random();
		var ajGeo = new Ajax.Request (
			query, {
				parameters: pars,
				method: 'get',
				onComplete: function (originalRequest) {
					json = eval("(" + originalRequest.responseText + ")");
					longitude = json.longitude;
					latitude = json.latitude;
					query = ppmObject.ajaxPath+"evgetpixel"+ppmObject.ajaxExtension;
					pars = "centerX="+ppmObject.evLongitude+"&centerY="+ppmObject.evLatitude+"&dir="+ppmObject.evDirection+"&longitude="+longitude+"&latitude="+latitude+'&_rnd='+Math.random();
					var ajPixel = new Ajax.Request (
						query, {
							parameters: pars,
							method: 'get',
							onComplete: function (originalRequest) {
								json = eval("(" + originalRequest.responseText + ")");
								if (ppmObject.evZoomLevel == 1) {
									x = json.x/3;
									y = json.y/3;
								} else {
									x = json.x;
									y = json.y;
								}
								evX = Math.round(ppmObject.evWidth/2-x);
								evY = Math.round(ppmObject.evHeight/2-y);
								if (evX > ppmObject.evLimitX) {
									evX = ppmObject.evLimitX;
								}
								if (evX < (-1)*ppmObject.evLimitX) {
									evX = (-1)*ppmObject.evLimitX;
								}
								if (evY > ppmObject.evLimitY) {
									evY = ppmObject.evLimitY;
								}
								if (evY < (-1)*ppmObject.evLimitY) {
									evY = (-1)*ppmObject.evLimitY;
								}
								ppmObject.evSwitch (evX, evY, ppmObject.evDirection, ppmObject.evZoomLevel, ppmObject.evLongitude, ppmObject.evLatitude)
								//ppmObject.evDrawTile (true, true);
								ppmObject.processes--;
							}
						}
					);
				}
			});
	},


	zoomBraid: function () {
		if (this.zoomLevel > BRAID_MAX_DISPLAY_LEVEL) {
			this.setZoomLevel (BRAID_MAX_DISPLAY_LEVEL);
		}
	},

	zoomIE: function () {
		if (this.zoomLevel > IE_MAX_DISPLAY_LEVEL) {
			this.setZoomLevel (IE_MAX_DISPLAY_LEVEL);
		}
	},

	moveToGeo: function (longitude, latitude, zoomLevel, callback) {
		longitude=Number(longitude);
		latitude=Number(latitude);
		var upp = this.getUnitsPerPixel();
		extendX = Math.round(this.width/2*upp);
		extendY = Math.round(this.height/2*upp);
		geoLeft = this.longitude-extendX;
		geoRight = this.longitude+extendX;
		geoTop = this.latitude + extendY;
		geoBottom = this.latitude - extendY;

		if (longitude>geoLeft && longitude < geoRight && latitude < geoTop && latitude > geoBottom) {
			pixelOffsetX = Math.round((this.longitude - longitude)/upp);
			pixelOffsetY = Math.round((latitude-this.latitude)/upp);

			this.pan (pixelOffsetX, pixelOffsetY, zoomLevel, callback);
		} else {
			this.longitude = longitude;
			this.latitude = latitude;

			if (zoomLevel != null) {
				this.setZoomLevel (zoomLevel);
			} else {
				this.draw ();
			}

			if (callback != null) {
				callback();
			}
		}
	},

	moveToSquare: function (l,t,r,b) {
		centerX = Math.round ((l+r)/2);
		centerY = Math.round ((t+b)/2);

		extend = Math.round(Math.max (Math.abs(l*1-r*1), Math.abs(t*1-b*1))/2);

		var zoomLevel = 1;
		while (zoomLevel <= 12 && extend*3 > Math.min(this.height, this.width) * METER_PER_PIXEL[zoomLevel-1] * UNITS_PER_METER) {
			zoomLevel++;
		}

		this.moveToGeo (centerX, centerY, zoomLevel);
	},

	goHome: function () {
			this.moveToGeo (this.longitudeHome, this.latitudeHome, this.zoomLevelHome);
	},

	zoomIn: function () {
		this.setZoomLevel(this.zoomLevel-1);
		//this.draw ();
	},

	zoomOut: function () {
		this.setZoomLevel(this.zoomLevel+1);
		//this.draw ();
	},


	evSwitch: function(evX, evY, evDirection, evZoomLevel, evLongitude, evLatitude)
	{
		if(evDirection != -1) {
			this.evDirection=evDirection;
		} else {
			this.evDirection=2;
		}

		this.evZoomLevel=evZoomLevel;
		this.evLongitude=evLongitude;
		this.evLatitude=evLatitude;
		this.evEnter();
		this.evX=evX;
		this.evY=evY;

		if (evX > ppmObject.evLimitX) {
			evX = ppmObject.evLimitX;
		}

		if (evX < (-1)*ppmObject.evLimitX) {
			evX = (-1)*ppmObject.evLimitX;
		}

		if (evY > ppmObject.evLimitY) {
			evY = ppmObject.evLimitY;
		}

		if (evY < (-1)*ppmObject.evLimitY) {
			evY = (-1)*ppmObject.evLimitY;
		}

		this.evTile.style.left=(evX-((this.evWidth-this.width)/2))+'px';
		this.evTile.style.top=(evY-((this.evHeight-this.height)/2))+'px';
		this.evX = evX;
		this.evY = evY;
		closeHelpWin();
	},

	evOptionDisable: function () {
		if ($(ppmObject.parentNode.id+"_mapmode_eagle") != null) {
			$(ppmObject.parentNode.id+"_mapmode_eagle").disabled = "disabled";
		//	$(ppmObject.parentNode.id+"_mapmode_eagle_textlink").style.display = "none";
		//	$(ppmObject.parentNode.id+"_mapmode_eagle_textdummy").style.display = "inline";
		}
	},

	evOptionEnable: function () {
		if ($(ppmObject.parentNode.id+"_mapmode_eagle") != null) {
			$(ppmObject.parentNode.id+"_mapmode_eagle").disabled = "";
			$(ppmObject.parentNode.id+"_mapmode_eagle_textlink").style.display = "inline";
			$(ppmObject.parentNode.id+"_mapmode_eagle_textdummy").style.display = "none";
		}
	},

	evEnter: function () {
		ppmObject = this;
		//Element.update (ppmObject.copyright, "&copy; 2006 klickTel AG");
		EVHIDE.each (function (div){
			if ($(ppmObject.parentNode.id+"_"+div+"_container") != null) {
				$(ppmObject.parentNode.id+"_"+div+"_container").style.display = "none";
				ppmObject.evRecoverIds.push (ppmObject.parentNode.id+"_"+div+"_container");
			}
		});

		if ($(domPrefix+"_eagleview_container") != null) {
			$(domPrefix+"_eagleview_container").style.display = "block";
		};

		this.eagleView = 2;
		this.evDrawTile ();

		if($(this.parentNode.id+"_ppm_slider") != null) {
			$(this.parentNode.id+"_ppm_slider").style.display = "none";
		}

		if($(this.parentNode.id+"_eagleview_slider") != null) {
			$(this.parentNode.id+"_eagleview_slider").style.display = "block";
		}
		if (this.scale != null) {
			this.scale.style.display = "none";
		}
		
		if (this.initialTrack == 0 && location.pathname.match(/kartensuche-result.html/)) {
			var ansicht = "EagleView";
			this.urchinDirect ("/kartensuche/kartensuche-tracking.html?Ansicht="+ansicht);
			this.initialTrack++;
		}
		this.IVWLog();

	},

	evGoto: function (longitude, latitude, zoomLevel) {

		if (zoomLevel == null) {
			zoomLevel = this.zoomLevel;
		}
		this.processes++;

		ppmObject = this;
		var evQuery = this.ajaxPath+'eagleview_point'+this.ajaxExtension+'?longitude='+longitude+'&latitude='+latitude+'&_rnd='+Math.random();
		ppmObject.evRequest = new Ajax.Request (
			evQuery,
			{onSuccess: function (originalRequest) {
				ppmObject.processes--;
				response = originalRequest.responseText;
				if(/Error/.test(response)) {
					ppmObject.longitude = longitude;
					ppmObject.latitude = latitude;
					ppmObject.setZoomLevel (zoomLevel);
					ppmObject.evLeave();
				} else {
					evLonglat = eval("(" + response + ")");
					ppmObject.evLongitude = 1*evLonglat.longitude;
					ppmObject.evLatitude = 1*evLonglat.latitude;
					ppmObject.evDrawTile();
				}

			}
		});
	},

	evDrawTile:function (keepRotation, keepOffset) {
		if (keepRotation == null) {
			keepRotation = false;
		}

		if (keepOffset == null) {
			keepOffset = false;
		}

		switch (this.evZoomLevel) {
			case 0:
				var tilesX = 9;
				var tilesY = 6;
				this.evZoomLevel = 0;
				this.evWidth = 4368;
				this.evHeight = 2912;
			break;
			case 1:
				var tilesX = 3;
				var tilesY = 2;
				this.evZoomLevel = 1;
				this.evWidth = 1441;
				this.evHeight = 961;
			break;
		}

		if (keepOffset == false) {
			this.evX = 0;
			this.evY = 0;
		}

		this.evLimitX = Math.floor((this.evWidth-this.width)/2);
		this.evLimitY = Math.floor((this.evHeight-this.height)/2);

		if (this.evTile != null) {
			Element.remove (this.evTile);
			this.evTile = null;
		}

		this.evTile = document.createElement ("div");

		var eagleTable = document.createElement ("table");
		eagleTable.setAttribute ("cellSpacing", "0");
		eagleTable.setAttribute ("cellPadding", "0");
		var tbody = document.createElement ("tbody");
		var evTileWidth = EAGLEVIEW_TILESIZE;
		var evTileHeight = EAGLEVIEW_TILESIZE;
		var apiTemp = "";
		for (var y=0; y<tilesY; y++) {
			if ((y+1)*EAGLEVIEW_TILESIZE > this.evHeight) {
				evTileHeight = this.evHeight-y*EAGLEVIEW_TILESIZE;
			}
			var tr = document.createElement ("tr");
			var offsetY = y*EAGLEVIEW_TILESIZE;
			for (var x=0; x<tilesX; x++) {
				if ((x+1)*EAGLEVIEW_TILESIZE > this.evWidth) {
					evTileWidth = this.evWidth-x*EAGLEVIEW_TILESIZE;
				} else {
					evTileWidth = EAGLEVIEW_TILESIZE;
				}
				offsetX = x*EAGLEVIEW_TILESIZE;
				var td = document.createElement ("td");
				td.style.width = evTileWidth+"px";
				td.style.height = evTileHeight+"px";
				td.style.backgroundColor = "#cccccc";
				tr.appendChild (td);
				var img = document.createElement ("img");
				img.style.backgroundColor = "#cccccc";
				img.style.width = evTileWidth+"px";
				img.style.height = evTileHeight+"px";
				img.setAttribute("galleryimg", "no");
				img.id = this.parentNode.id+"_evtile_"+x+"_"+y;
				Element.addClassName (img,"evTile");
				td.appendChild (img);
				var src = this.spacerImage;
				img.src = src;
			}
			tbody.appendChild (tr);
		}
		eagleTable.appendChild (tbody);
		eagleTable.style.position = "absolute";
		eagleTable.style.zIndex = 0;
		eagleTable.style.top = "0px";
		eagleTable.style.left = "0px";

		this.evTile.appendChild (eagleTable);
		this.evTile.style.position = "absolute";
		this.evTile.style.top = "-"+((this.evHeight-this.height)/2-this.evY)+"px";
		this.evTile.style.left = "-"+((this.evWidth-this.width)/2-this.evX)+"px";
		this.evTile.style.zIndex = 2;
		this.evTile.style.backgroundColor = "#ff0000";
		this.parentNode.appendChild (this.evTile);

		if (keepRotation == false) {
			this.evUpdateDirections ();
		} else {
			this.evUpdateNeighbours ();
		}

		for (var y=0; y<tilesY; y++) {
			for (var x=0; x<tilesX; x++) {
				apiTemp = "api"+((((y*tilesX)+x)%6)+1)+".klicktel.de";
				//apiTemp = "api.release.klickdev.de";
				offsetX = x*EAGLEVIEW_TILESIZE;
				offsetY = y*EAGLEVIEW_TILESIZE;
				var src = "http://"+apiTemp+"/KROUTE/gateway/1.0/evGetImage.php?longitude="+this.evLongitude+"&latitude="+this.evLatitude+"&offsetx="+offsetX+"&offsety="+offsetY+"&dir="+this.evDirection+"&mip="+this.evZoomLevel;
				$(this.parentNode.id+"_evtile_"+x+"_"+y).src = src;
			}
		}

		this.updatePoiLayer ();
		this.icons.each(function (icon) {
			icon.draw ();
		});
	},

	evRotateRight: function () { // Turns to the right until a defined view is established
		var originalDir = this.evDirection;
		this.evTurnRight();
		while (this.evDirections.indexOf(this.evDirection) == -1) {
			this.evTurnRight();
		}
		this.evSetDirection (this.evDirection);
		if (this.evZoomLevel == 1) {
			evCenterX = Math.round(this.evWidth/2-this.evX)*3;
			evCenterY = Math.round(this.evHeight/2-this.evY)*3;
		} else {
			evCenterX = Math.round(this.evWidth/2-this.evX);
			evCenterY = Math.round(this.evHeight/2-this.evY);
		}

		this.processes++;
		query = this.ajaxPath+"evgetgeo"+this.ajaxExtension;
		pars="x="+this.evLongitude+"&y="+this.evLatitude+"&d="+originalDir+"&screenx="+evCenterX+"&screeny="+evCenterY+'&_rnd='+Math.random();
		ppmObject = this;
		var ajGeo = new Ajax.Request (
			query, {
				parameters: pars,
				method: 'get',
				onComplete: function (originalRequest) {
					json = eval("(" + originalRequest.responseText + ")");
					longitude = json.longitude;
					latitude = json.latitude;
					query = ppmObject.ajaxPath+"evgetpixel"+ppmObject.ajaxExtension;
					pars = "centerX="+ppmObject.evLongitude+"&centerY="+ppmObject.evLatitude+"&dir="+ppmObject.evDirection+"&longitude="+longitude+"&latitude="+latitude+'&_rnd='+Math.random();
					var ajPixel = new Ajax.Request (
						query, {
							parameters: pars,
							method: 'get',
							onComplete: function (originalRequest) {
								json = eval("(" + originalRequest.responseText + ")");
								if (ppmObject.evZoomLevel == 1) {
									x = json.x/3;
									y = json.y/3;
								} else {
									x = json.x;
									y = json.y;
								}
								evX = Math.round(ppmObject.evWidth/2-x);
								evY = Math.round(ppmObject.evHeight/2-y);
								if (evX > ppmObject.evLimitX) {
									evX = ppmObject.evLimitX;
								}
								if (evX < (-1)*ppmObject.evLimitX) {
									evX = (-1)*ppmObject.evLimitX;
								}
								if (evY > ppmObject.evLimitY) {
									evY = ppmObject.evLimitY;
								}
								if (evY < (-1)*ppmObject.evLimitY) {
									evY = (-1)*ppmObject.evLimitY;
								}

								ppmObject.evSwitch (evX, evY, ppmObject.evDirection, ppmObject.evZoomLevel, ppmObject.evLongitude, ppmObject.evLatitude)
								ppmObject.evDrawTile (true, true);

								ppmObject.processes--;
							}
						}
					);
				}
			});

	},

	evTurnRight: function () { // Makes a quarter turn to the right, regardless if the view is defined
		if (this.evDirection < 0) {
			this.evDirection = 3;
		} else {
			this.evDirection--;
		}
	},

	evSetDirection: function (dir) {
		if ($(this.parentNode.id+"_eagleview_container").style.display != "one") {
			switch (dir) {
				case 0:
					$(this.parentNode.id+"_evSouth").style.top = "-4px";
					$(this.parentNode.id+"_evSouth").style.left = "102px";

					$(this.parentNode.id+"_evWest").style.top = "102px";
					$(this.parentNode.id+"_evWest").style.left = "208px";

					$(this.parentNode.id+"_evNorth").style.top = "208px";
					$(this.parentNode.id+"_evNorth").style.left = "102px";

					$(this.parentNode.id+"_evEast").style.top = "102px";
					$(this.parentNode.id+"_evEast").style.left = "-4px";
				break;
				case 1:
					$(this.parentNode.id+"_evWest").style.top = "-4px";
					$(this.parentNode.id+"_evWest").style.left = "102px";

					$(this.parentNode.id+"_evNorth").style.top = "102px";
					$(this.parentNode.id+"_evNorth").style.left = "208px";

					$(this.parentNode.id+"_evEast").style.top = "208px";
					$(this.parentNode.id+"_evEast").style.left = "102px";

					$(this.parentNode.id+"_evSouth").style.top = "102px";
					$(this.parentNode.id+"_evSouth").style.left = "-4px";
				break;
				case 2:
					$(this.parentNode.id+"_evNorth").style.top = "-4px";
					$(this.parentNode.id+"_evNorth").style.left = "102px";

					$(this.parentNode.id+"_evEast").style.top = "102px";
					$(this.parentNode.id+"_evEast").style.left = "208px";

					$(this.parentNode.id+"_evSouth").style.top = "208px";
					$(this.parentNode.id+"_evSouth").style.left = "102px";

					$(this.parentNode.id+"_evWest").style.top = "102px";
					$(this.parentNode.id+"_evWest").style.left = "-4px";

				break;
				case 3:
					$(this.parentNode.id+"_evEast").style.top = "-4px";
					$(this.parentNode.id+"_evEast").style.left = "102px";

					$(this.parentNode.id+"_evSouth").style.top = "102px";
					$(this.parentNode.id+"_evSouth").style.left = "208px";

					$(this.parentNode.id+"_evWest").style.top = "208px";
					$(this.parentNode.id+"_evWest").style.left = "102px";

					$(this.parentNode.id+"_evNorth").style.top = "102px";
					$(this.parentNode.id+"_evNorth").style.left = "-4px";
				break;
			}

			this.evDirection = dir;

		} else {
			quarters = (4+(this.evDirection-dir))%4;
			this.evDirection = dir;
			this.processes++;
			for (i=0; i<quarters; i++) {
				ballNorth = $(this.parentNode.id+"_evNorth");
				var targetNorth = this.evDirectionBallGetTarget (parseInt(ballNorth.style.left),
					parseInt(ballNorth.style.top));
				while (parseInt(ballNorth.style.left) != targetNorth.x || parseInt(ballNorth.style.left) != targetNorth.x) {
					if (parseInt(ballNorth.style.left) < targetNorth.x) {
						ballNorth.style.left = (parseInt(ballNorth.style.left)+1)+"px";
					}
					if (parseInt(ballNorth.style.left) > targetNorth.x) {
						ballNorth.style.left = (parseInt(ballNorth.style.left)-1)+"px";
					}
					if (parseInt(ballNorth.style.top) < targetNorth.y) {
						ballNorth.style.top = (parseInt(ballNorth.style.top)+1)+"px";
					}
					if (parseInt(ballNorth.style.top) > targetNorth.y) {
						ballNorth.style.top = (parseInt(ballNorth.style.top)-1)+"px";
				}
				};
			}
			this.processes--;
		}
	},

	evDirectionBallGetTarget: function (x,y) {
		if (x==102 && y==0) {		// Current Position is north
			return {x:204, y:102};
		}
		if (x==204 && y==102) {		// Current Position is east
			return {x:102, y:204};
		}
		if (x==102 && y==204) {		// Current Position is south
			return {x:0, y:102};
		}
		if (x==0 && y==102) {		// Current Position is west
			return {x:102, y:0};
		}

		// Current position is undefined, move to north position anyway
		return {x:102, y:0};
	},

	evUpdateDirections: function () {

		this.processes++;
		ppmObject = this;
		var evQuery = this.ajaxPath+'eagleview_point'+this.ajaxExtension+'?longitude='+ppmObject.evLongitude+'&latitude='+ppmObject.evLatitude+'&_rnd='+Math.random();
		ppmObject.evRequest = new Ajax.Request (
			evQuery,
			{onSuccess: function (originalRequest) {
				ppmObject.processes--;
				response = originalRequest.responseText;
				if(/Error/.test(response)) {
					alert (response);
				} else {
					ppmObject.evDirections.clear ();
					evLonglat = eval("(" + response + ")");
					ppmObject.evLongitude = 1*evLonglat.longitude;
					ppmObject.evLatitude = 1*evLonglat.latitude;
					if (evLonglat.W2E == 1) {
						bestDirection = 1;
						ppmObject.evDirections.push (1);
					}

					if (evLonglat.E2W == 1) {
						bestDirection = 3;
						ppmObject.evDirections.push (3);
					}

					if (evLonglat.N2S == 1) {
						bestDirection = 0;
						ppmObject.evDirections.push (0);
					}

					if (evLonglat.S2N == 1) {
						bestDirection = 2;
						ppmObject.evDirections.push (2);
					}
					if (ppmObject.evDirection == -1) {
						ppmObject.evSetDirection (bestDirection);
					}

					if (ppmObject.evDirections.indexOf(0) == -1) {
						$(ppmObject.parentNode.id+"_evSouth").style.display = "none";
					} else {
						$(ppmObject.parentNode.id+"_evSouth").style.display = "block";
					}
					if (ppmObject.evDirections.indexOf(1) == -1) {
						$(ppmObject.parentNode.id+"_evWest").style.display = "none";
					} else {
						$(ppmObject.parentNode.id+"_evWest").style.display = "block";
					}
					if (ppmObject.evDirections.indexOf(2) == -1) {
						$(ppmObject.parentNode.id+"_evNorth").style.display = "none";
					} else {
						$(ppmObject.parentNode.id+"_evNorth").style.display = "block";
					}
					if (ppmObject.evDirections.indexOf(3) == -1) {
						$(ppmObject.parentNode.id+"_evEast").style.display = "none";
					} else {
						$(ppmObject.parentNode.id+"_evEast").style.display = "block";
					}
					ppmObject.evUpdateNeighbours ();

				}
			}
			}

		);
	},

	evUpdateNeighbours:function () {
		ppmObject = this;
		while ($(this.parentNode.id+"_ev_thumb_center") == null) {
			//Do nothing
		}
		aj = new Ajax.Request (
			this.ajaxPath+"eagleviews"+this.ajaxExtension,
			{
				method: 'get',
				parameters: "x="+this.evLongitude+"&y="+this.evLatitude+"&d="+DIRECTIONS[this.evDirection]+'&_rnd='+Math.random(),
				onSuccess: function (originalRequest) {
					json = eval("(" + originalRequest.responseText + ")");
					var neighbours = json.ev;
					rotation = (ppmObject.evDirection+2)%4;
					var first = null;
					neighbours.reverse();
					for (i=0; i<rotation*2; i++) {
						var first = neighbours.shift();
						neighbours.push (first);
					};
					neighbours.reverse();
					if ($("ev_debug") != null) {
						Element.update ($("ev_debug"), "");
					}
					for (i=0; i<8; i++) {
						if (neighbours[i] != "0:0") {
							$(ppmObject.parentNode.id+"_clouds_"+i).style.display = "none";
							longlat = neighbours[i].split(":");
							$(ppmObject.parentNode.id+"_ev_thumb_"+i).src = "http://"+API_SERVER+"/KROUTE/gateway/1.0/evGetImage.php?longitude="+longlat[0]+"&latitude="+longlat[1]+"&offsetx=0&offsety=0&dir="+ppmObject.evDirection+"&mip=2";

							$(ppmObject.parentNode.id+"_ev_thumb_"+i).longitude = longlat[0];
							$(ppmObject.parentNode.id+"_ev_thumb_"+i).latitude = longlat[1];
						} else {
							$(ppmObject.parentNode.id+"_clouds_"+i).style.display = "none";
							$(ppmObject.parentNode.id+"_ev_thumb_"+i).src = ppmObject.spacerImage;
						}
						if ($("ev_debug") != null) {

						}
					}
				}
			}
		);
		$(ppmObject.parentNode.id+"_ev_thumb_center").src = "http://"+API_SERVER+"/KROUTE/gateway/1.0/evGetImage.php?longitude="+ppmObject.evLongitude+"&latitude="+ppmObject.evLatitude+"&offsetx=0&offsety=0&dir="+ppmObject.evDirection+"&mip=2";
	},

	evLeave: function () {
		if (this.apiKey != null) {
			Element.remove ($(this.parentNode.id+"_layer_"+this.layercount));
			this.layercount--;
		}
		if (this.eagleView == 1) {
			this.hideEagleViewOverlay ();
		}
		
		this.eagleView = 0;
		if (this.evTile != null) {
			Element.remove (this.evTile);
			this.evTile = null;
		}
		$(this.parentNode.id+"_ppm_slider").style.display = "block";
		$(this.parentNode.id+"_eagleview_slider").style.display = "none";
		

		this.evRecoverIds.each (function(id) {
			if($(id) != null) {
				$(id).style.display = "block";
			}
		});

		this.evRecoverIds = Array ();
		if ($(domPrefix+"_eagleview_container") != null) {
			$(domPrefix+"_eagleview_container").style.display = "none";
		}

		if (this.aerial == 0) {

			this.setMapMode ("map");
		} else {

			if (this.hybrid == 0) {
				this.setMapMode ("aerial");
			} else {
				this.setMapMode ("hybrid");
			}
		}

		if (this.scale != null) {
			this.scale.style.display = "";
		}
	},

	evShowOverlay: function () {
		//Add another layer if it is API
		if (this.layercount < 2) {
			this.layercount++;
			layer = new ScreenObject (this.parentNode);
			layer.setId(this.parentNode.id+"_layer_"+this.layercount);
			layer.x = 0;
			layer.y = 0;
			layer.zIndex = (this.layercount-1)*10;
			layer.width = this.width;
			layer.height = this.height;
			layer.draw ();
			$(this.parentNode.id+"_layer_"+this.layercount).update ("");
		}
		this.contextMenuController.hideDynamicMenu();
		this.contextMenuController.hide();
		for (x=0; x<this.checkerBoard.cols; x++) {
			for (y=0; y<this.checkerBoard.rows; y++) {
				tile = this.checkerBoard.getTile(x,y);
				if (tile.longitude != 0 && tile.latitude != 0) {
					tile.img = document.createElement ("img");

					if (tile.img.style.filter != null) {
						tile.img.src = this.ajaxPath+"overlay_"+tile.longitude+"_"+tile.latitude+"_"+tile.ext+"_big.gif";
						tile.img.style.width = TILESIZE+"px";
						tile.img.style.height = TILESIZE+"px";
						tile.img.galleryImg = "no";
					} else {

						tile.img.src = this.ajaxPath+"overlay_"+tile.longitude+"_"+tile.latitude+"_"+tile.ext+"_big.gif";
					}

					tile.img.id = "overlay_"+x+"_"+y;
					tile.img.style.position = "absolute";
					tile.img.style.left = tile.domNode.style.left;
					tile.img.style.top = tile.domNode.style.top;
					tile.img.style.zIndex = 512;
					$(this.parentNode.id+"_layer_1").appendChild (tile.img);
					Event.observe(tile, "click", function (e) { ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
				}
			}
		}
	},

	hideEagleViewOverlay: function () {
		for (x=0; x<this.checkerBoard.cols; x++) {
			for (y=0; y<this.checkerBoard.rows; y++) {
				tile = this.checkerBoard.getTile(x,y);
				Element.remove (tile.img);
			}
		}
	},

	toggleIeDisplay: function () {
		if (this.poi.infoEntries == true) {
			this.poi.infoEntries = false;
			this.cleanUpIcons ();
			if ($(this.parentNode.id+"_ie_toggle_link") != null) {
				Element.update ($(this.parentNode.id+"_ie_toggle_link"), "infoEintr?ge anzeigen");
			}
		} else {
			this.poi.infoEntries = true;
			if ($(this.parentNode.id+"_ie_toggle_link") != null) {
				Element.update ($(this.parentNode.id+"_ie_toggle_link"), "infoEintr?ge ausblenden");
			}
		}
		this.draw ();
	},

	withinActiveArea: function (x,y) {

		if (Position.within(this.leftWidgetCol, x, y) == true) {
			return false;
		}

		if (Position.within(this.centerWidgetCol, x, y) == true) {
			return false;
		}

		if (Position.within(this.rightWidgetCol, x, y) == true) {
			return false;
		}

		if ($(this.parentNode.id+"_infowindow") != null && Position.within($(this.parentNode.id+"_infowindow"), x, y) == true) {
			this.eventHandler.infoWin = true;
			return false;
		}

		if ($(this.parentNode.id+"_metros") != null && Position.within($(this.parentNode.id+"_metros"), x, y) == true) {
			return false;
		}

		if ($(this.parentNode.id+"_zstations") != null && Position.within($(this.parentNode.id+"_zstations"), x, y) == true) {
			return false;
		}

		if ($(this.parentNode.id+"_optimierung") != null && Position.within($(this.parentNode.id+"_optimierung"), x, y) == true) {
			return false;
		}

		if($(this.parentNode.id+'_poi_select') != null) {
			if($(this.parentNode.id+'_poi_select').style.display != 'none') {
				if (Position.within($(this.parentNode.id+'_poi_select'), x, y) == true) {
					return false;
				}
			}
		}

		// Soll auch true sein, wenn auf das infowindow geklickt wird

		if ($(this.parentNode.id+"_infowindow") != null && Position.within($(this.parentNode.id+"_infowindow"), x, y) == true) {
			this.eventHandler.infoWin = true;
			return false;
		}
		return true;
	},


	getMapMode: function()
	{
		if(this.eagleView == 2) {
			return "eagle";
		} else if(this.aerial==0 && this.hybrid == 0) {
			return "map";
		} else if(this.aerial == 1 && this.hybrid == 0) {
			return "aerial";
		} else if(ppmObject.aerial == 1 && ppmObject.hybrid == 1) {
			return "hybrid";
		}

		return "UNKNOWN";
	},

	setMapMode: function (mode) {

		// Set the map to the location of the eagleview tile when switching
		// from eagleview to another mode
		if(this.eagleView  == 2 && mode != "eagle") {
			this.longitude=this.evLongitude;
			this.latitude=this.evLatitude;
		}
	
		if ($(this.parentNode.id+"_layer_2") != null) {
			$(this.parentNode.id+"_layer_2").update ("");
		}
		domPrefix = this.parentNode.id;
		switch (mode) {
			case 'eagle':
				if ($(this.parentNode.id+"_mapmode_eagle") != null && $(this.parentNode.id+"_mapmode_eagle").checked != true) {
					$(this.parentNode.id+"_mapmode_eagle").checked = true;
				}
				this.eagleView = 1;
				this.evShowOverlay ();
				//Element.update (this.copyright, "&copy; 2006 klickTel AG / TeleAtlas / AND BV");
			break;
			case 'aerial':
				if ($(this.parentNode.id+"_mapmode_aerial") != null && $(this.parentNode.id+"_mapmode_aerial").checked != true) {
					$(this.parentNode.id+"_mapmode_aerial").checked = true;
				}
				if (this.eagleView > 0) {
					this.evLeave ();
				}
				this.aerial = 1;
				this.hybrid = 0;
				this.draw ();
				//Element.update (this.copyright, "&copy; 2006 klickTel AG / TeleAtlas / AND BV<br>Luftbilder &copy; GeoContent");
			break;
			case 'hybrid':
				if ($(this.parentNode.id+"_mapmode_hybrid") != null && $(this.parentNode.id+"_mapmode_hybrid").checked != true) {
					$(this.parentNode.id+"_mapmode_hybrid").checked = true;
				}
				if (this.eagleView > 0) {
					this.evLeave ();
				}
				this.aerial = 1;
				this.hybrid = 1;
				this.draw ();
				//Element.update (this.copyright, "&copy; 2006 klickTel AG / TeleAtlas / AND BV<br>Luftbilder &copy; GeoContent");
			break;
			default:
				if ($(this.parentNode.id+"_mapmode_map") != null && $(this.parentNode.id+"_mapmode_map").checked != true) {
					$(this.parentNode.id+"_mapmode_map").checked = true;
				}
				if (this.eagleView > 0) {
					this.evLeave ();
				}
				this.aerial = 0;
				this.hybrid = 0;
				this.draw ();
				//Element.update (this.copyright, "&copy; 2006 klickTel AG / TeleAtlas / AND BV");
		}
		this.setViewCookie();
	},

	iconToMarker:function(icon)
	{
		if(icon.type=='marker') {
			foundMarker=null;
			if (this.PpmMarkers.userMarkers.length > 0) {
				this.PpmMarkers.userMarkers.each(function(marker) {
					if(marker.icon.domId==icon.domId) {
						foundMarker=marker;
					}
				});
			}

			if(foundMarker == null) {
				if (this.PpmMarkers.linkMarkers.length > 0) {
				this.PpmMarkers.linkMarkers.each(function(marker) {
					if(marker.icon.domId==icon.domId) {
						foundMarker=marker;
					}
				});
				}
			}

			if(foundMarker == null) {
				localLog('ERROR - Marker for icon '+icon.domId+' was not found!');
			} else {
				return foundMarker;
			}
		} else {
			var marker=new Marker();
			marker.poiID=icon.domId;
			marker.displayName=icon.title;

			Erg=marker.displayName.match(/<br>/);
			if(Erg) {
				marker.displayName=marker.displayName.replace(/<br>.*/, '');
			}

			marker.ppmObject=this.pmObject;
			marker.longitude=icon.longitude;
			marker.latitude=icon.latitude;
			marker.x = parseInt($(icon.domId).style.left)+icon.offsetX+ppmObject.x;
			marker.y = parseInt($(icon.domId).style.top)+icon.offsetX+ppmObject.y;
			return marker;
		}

	},

	closeLeftWidgetCol: function () {
		this.leftWidgetCol.style.display="none";
		$(this.parentNode.id+"_left_widget_controller").style.backgroundPosition = "-12px 0px";
	},

	openLeftWidgetCol: function () {
		this.leftWidgetCol.style.display="block";
		$(this.parentNode.id+"_left_widget_controller").style.backgroundPosition = "0px 0px";
	},

	switchLeftWidgetCol: function () {
		if (this.leftWidgetCol.style.display == "none") {
			this.openLeftWidgetCol();
		} else {
			this.closeLeftWidgetCol();
		}
	},

	closeRightWidgetCol: function () {
		this.rightWidgetCol.style.display="none";
		$(this.parentNode.id+"_right_widget_controller").style.backgroundPosition = "-12px 0px";
	},

	openRightWidgetCol: function () {
		this.rightWidgetCol.style.display="block";
		$(this.parentNode.id+"_right_widget_controller").style.backgroundPosition = "0px 0px";
	},

	switchRightWidgetCol: function () {
		if (this.rightWidgetCol.style.display == "none") {
			this.openRightWidgetCol();
		} else {
			this.closeRightWidgetCol();
		}
	},

	makeTransparencies:function () {

		// Deactivated for IE to improve performance
		if(/MSIE/.test(navigator.userAgent) || this.apiKey != null) {
			return;
		}

		var ktc=0;

		elements = document.getElementsByClassName ("ppm_transparency");
		if (elements.length > 0) {
			elements.each (function (element){
			ktc++;
				color = element.style.backgroundColor.parseColor();
				if (color != "") {
					element.style.backgroundColor = "";

					classNames = Element.classNames(element);
					classNames.each (function(cssClass) {
						if(/opaque/.test(cssClass)) {
							opacity = cssClass.substring (cssClass.length-2, cssClass.length);

						} else {
							opacity = 80;
						}
					});
					//backgroundUrl = "/kt_map/images/transimage.php?color="+color.substr(1,6)+"&opacity="+opacity;
					backgroundUrl = "/kt_map/images/transimage_"+color.substr(1,6)+"_"+opacity+'.png';
					if (element.style.filter != null) { // Crappy Internet Explorer
						element.style.display = "inline-block";
						element.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+backgroundUrl+"', sizingMethod='scale');"
					} else {
						element.style.backgroundImage = "url("+backgroundUrl+")";
					}
					var fields = element.getElementsByTagName('input');
					for (i=0;i<fields.length;i++) {
						var field = fields[i];
					}
				}
			});
		}
	},


	makeFoldoutControls: function () {
		var open = function (controller) {
			ppmObject.cleanupUI();

			if (controller.hasClassName ("ppm_foldout_exclusive_right")) {
				ppmObject = controller.ppmObject;
				concurrentControllers = document.getElementsByClassName ("ppm_foldout_exclusive_right", controller.ppmObject.rightWidgetCol);
				concurrentControllers.each (function (concurrentController) {
					if (Element.getDimensions(concurrentController.rel).width >0) {
						close ($(concurrentController));
					}
				});
			}

			if (controller.hasClassName ("ppm_foldout_exclusive_left")) {
				ppmObject = controller.ppmObject;
				concurrentControllers = document.getElementsByClassName ("ppm_foldout_exclusive_left", controller.ppmObject.leftWidgetCol);
				concurrentControllers.each (function (concurrentController) {
					if (Element.getDimensions(concurrentController.rel).width >0) {
						close ($(concurrentController));
					}
				});
			}


			if(controller.hasClassName ("ppm_addressmode_0")) {
				ppmObject.addressMode = 0;
			}

			if(controller.hasClassName ("ppm_addressmode_1")) {
				ppmObject.addressMode = 1;
			}


			handle = controller.getElementsByTagName("DIV")[0];
			bgPositions = handle.style.backgroundPosition.split (" ");
			handle.style.backgroundPosition = "0px "+bgPositions[1];
			var affectedNode = $(controller.getAttribute("rel"));
			if (affectedNode != null) {
				//Bugfix:Im IE wird dieser sch... Button immer über dem Menü angezeigt
				if(controller.id==ppmObject.parentNode.id+'_zstations_controller'){
					$(ppmObject.parentNode.id+"_optimierung_foldoutDiv").style.display="none";
				}
				//Bugfix:Im IE wird dieser sch... Button immer über dem Menü angezeigt
				if(controller.id==ppmObject.parentNode.id+'_metros_foldout'){
					$(ppmObject.parentNode.id+"_cityinfo_foldout").style.display="none";
				}
				if(controller.id==ppmObject.parentNode.id+'_optimierung_controller'){
					if ($(ppmObject.parentNode.id+"_poi_select_controller") != null) {
						$(ppmObject.parentNode.id+"_poi_select_controller").style.display="none";
					}
				}

				affectedNode.style.display = "block";

			}

			pos = Position.cumulativeOffset(handle);
			if (Position.within (ppmObject.leftWidgetCol, pos[0], pos[1])) {
				ppmObject.openLeftWidgetCol;
			}
			if (Position.within (ppmObject.rightWidgetCol, pos[0], pos[1])) {
				ppmObject.openRightWidgetCol;
			}

		};

		var close = function (controller) {
			handle = controller.getElementsByTagName("DIV")[0];
			bgPositions = handle.style.backgroundPosition.split (" ");
			handle.style.backgroundPosition = "-12px "+bgPositions[1];
			var affectedNode = $(controller.getAttribute("rel"));
			if (affectedNode != null) {
				//Bugfix:Im IE wird dieser sch... Button immer ï¿½ber dem Menï¿½ angezeigt
				if(controller.id==ppmObject.parentNode.id+'_zstations_controller'){
					$(ppmObject.parentNode.id+"_optimierung_foldoutDiv").style.display="block";
				}
				//Bugfix:Im IE wird dieser sch... Button immer ï¿½ber dem Menï¿½ angezeigt
				if(controller.id==ppmObject.parentNode.id+'_metros_foldout'){
					$(ppmObject.parentNode.id+"_cityinfo_foldout").style.display="block";
				}
				if(controller.id==ppmObject.parentNode.id+'_optimierung_controller'){
					if ($(ppmObject.parentNode.id+"_poi_select_controller") != null) {
						$(ppmObject.parentNode.id+"_poi_select_controller").style.display="block";
					}
				}

				affectedNode.style.display = "none";
				ppmObject.hideHelpWin();
			}
		};

		var openClose = function (controller) {
			var affectedNode = $(controller.getAttribute("rel"));
			if (affectedNode != null) {
				handle = controller.getElementsByTagName("DIV")[0];
				if (affectedNode.style.display == 'none') {
					open (controller);
				} else {
					close (controller);
				}
			}
		}

		var focus = function (controller) {
			handle = controller.getElementsByTagName("DIV")[0];
			bgPositions = handle.style.backgroundPosition.split(" ");
			handle.style.backgroundPosition = bgPositions[0]+" -12px";
		}

		var blur = function (controller) {
			handle = controller.getElementsByTagName("DIV")[0];
			bgPositions = handle.style.backgroundPosition.split(" ");
			handle.style.backgroundPosition = bgPositions[0]+" 0px";
		}

		ppmObject = this;



		elements = document.getElementsByClassName ("ppm_foldout_controller", this.parentNode);
		elements.each (function (controller) {
				controller.ppmObject = ppmObject;
				controller.style.textDecoration = "none";

				var direction = "vertical"; //Default foldout will go up/down
				if (Element.hasClassName (controller, "ppm_foldout_right")) {
					direction = "right";
				}
				if (Element.hasClassName (controller, "ppm_foldout_left")) {
					direction = "left";
				}


				var affectedNode = $(controller.getAttribute("rel"));

				var newDivName=controller.getAttribute("rel")+'_foldoutDiv';

				if($(newDivName) == null) {
					handle = document.createElement("div");
					handle.id=newDivName;
					handle.style.width = "12px";
					handle.style.height = "12px";
					handle.style.backgroundRepeat = "no-repeat";
					handle.style.overflow = "hidden";
					//handle.style.position = "relative";
					handle.style.zIndex = 5;

					if (direction == "vertical") {
						handle.style.backgroundImage = "url(/kt_map/images/foldout_minus_plus_hover.gif)";
					}

					if (direction == "left") {
						handle.style.backgroundImage = "url(/kt_map/images/foldout_right_left_hover.gif)";

					}

					if (direction == "right") {
						handle.style.backgroundImage = "url(/kt_map/images/foldout_left_right_hover.gif)";
					}

					if (affectedNode != null) {
						if (affectedNode.style.display == 'none') {
							handle.style.backgroundPosition = "-12px 0px";
						} else {
							handle.style.backgroundPosition = "0px 0px";
						}
					}
					controller.appendChild (handle);

					controller.onclick = function () {
						openClose (controller);
						return false;
					};

					controller.onmouseover = function () {
						focus (controller);
					}

					controller.onmouseout = function () {
						blur (controller);
					}

					controller.open = function () {open (controller)};
					controller.close = function () {close (controller)};
					controller.focus = function () {focus (controller)};
					controller.blur = function () {blur (controller)};
				}
		});
	},


	makeDemoMarkerIcon: function (){
		var icon = new MarkerIcon (this.longitude, this.latitude, this, "DemoIcon");
		icon.draw ();
	},

	getApiIconsByClass: function (poiClasses) { //poiClasses is a string containing one or more classes separated by whitespace
		var foundIcons = this.apiIcons.findAll (function (apiIcon) {
			return (apiIcon.hasClassname(poiClasses));
		});
		return foundIcons;
	},

	updatePoiLayer: function () {
		this.cleanupUI();
		ppmObject = this;

		if (ppmObject.eagleView < 2) {

			if (this.poi.infoEntries == true && this.zoomLevel <= IE_MAX_DISPLAY_LEVEL) {
				if(!(this.poiIeLoading)) {
					this.processes++;
				}
				this.poiIeLoading=true;
				$(ppmObject.parentNode.id+"_bitte_warten").style.display = "block";
				var ieURL=ppmObject.ajaxPath+"iejson"+ppmObject.ajaxExtension+"?upp="+this.getUnitsPerPixel()+"&centerX="+this.longitude+"&centerY="+this.latitude+"&width="+this.width+"&height="+this.height+'&_rnd='+Math.random();
				this.ieUpdater.src=ieURL;
			} else { // Remove Infoentries from Icon Array
				icons = Array ();
				doubleEntry = false;
				for (i=0; i<this.icons.length; i++) {
					if (this.icons[i].type != 'ie') {
						/*for (j=0; j<icons.length; j++) {
							if(this.icons[i].longitude >= ppmObject.getLeftEdge() && this.icons[i].longitude <= ppmObject.getRightEdge() && this.icons[i].latitude >= ppmObject.getBottomEdge() && this.icons[i].latitude <= ppmObject.getTopEdge()) {
								if (icons[j].poiId == this.icons[i].poiId){
									doubleEntry = true;
								}
							}
							if(!doubleEntry) {
								icons.push(this.icons[i]);
							}
						}*/
						icons.push(this.icons[i]);
					}
				}

				this.icons = icons;
			};

			if (this.PpmMarkers.userMarkers.length > 0) {
				icons = this.icons;
				this.PpmMarkers.userMarkers.each(function(marker) {
					// Visible?
					if(marker.longitude >= ppmObject.getLeftEdge() && marker.longitude <= ppmObject.getRightEdge() && marker.latitude >= ppmObject.getBottomEdge() && marker.latitude <= ppmObject.getTopEdge()) {
						if($(marker.myID) != null && marker.icon != null) {
							foundIt=false;
							for(i=0; i<icons.length; i++) {
								if(icons[i].domId == marker.myID) {
									foundIt=true;
								}
							}
						}

						if(!foundIt) {
							icons.push(marker.icon);
						}
					} else {
						marker.icon = new MarkerIcon (marker.longitude, marker.latitude, marker.ppmObject, marker.myID, marker);
						marker.icon.draw ();
					}
				});
			}

			//von anke
			if (this.PpmMarkers.linkMarkers.length > 0) {
				icons = this.icons;
				this.PpmMarkers.linkMarkers.each(function(marker) {
					// Visible?
					if(marker.longitude >= ppmObject.getLeftEdge() && marker.longitude <= ppmObject.getRightEdge() && marker.latitude >= ppmObject.getBottomEdge() && marker.latitude <= ppmObject.getTopEdge()) {

						if($(marker.myID) != null && marker.icon != null) {
							foundIt=false;
							for(i=0; i<icons.length; i++) {
								if(icons[i].domId == marker.myID) {
									foundIt=true;
								}
							}
						}

						if(!foundIt) {
							icons.push(marker.icon);
						}
					} else {
						marker.icon = new MarkerIcon (marker.longitude, marker.latitude, marker.ppmObject, marker.myID, marker);
						marker.icon.draw ();
					}
				});
			}

			if (this.poi.braIds.length > 0 || this.poi.braName != "") {
				if(!this.poiSeLoading) {
					this.processes++;
				}
				this.poiSeLoading=true;
				$(ppmObject.parentNode.id+"_bitte_warten").style.display = "block";

				var updaterUrl = this.ajaxPath+"poilist"+this.ajaxExtension+"?u="+this.getUnitsPerPixel()+"&x="+this.longitude+"&y="+this.latitude+"&zoomlevel="+this.zoomLevel+"&w="+this.width+"&h="+this.height+"&b=";
				this.poi.braIds.each (function (braid) {
					updaterUrl += braid+";";
				});
				if (this.poi.braName != '') {
					updaterUrl += "&branche="+this.poi.braName;
				}
				this.badeUpdater.src=updaterUrl;
			} else { // Remove Branch Icons from Array
				var icons = Array ();
				for (i=0; i<this.icons.length; i++) {
					if (this.icons[i].type != 'se') {
						/*for (j=0; j<icons.length; j++) {
							if(this.icons[i].longitude >= ppmObject.getLeftEdge() && this.icons[i].longitude <= ppmObject.getRightEdge() && this.icons[i].latitude >= ppmObject.getBottomEdge() && this.icons[i].latitude <= ppmObject.getTopEdge()) {
								if (icons[j].poiId == this.icons[i].poiId){
									doubleEntry = true;
								}
							}
							if(!doubleEntry) {
								icons.push(this.icons[i]);
							}*/
						if(this.icons[i].longitude >= ppmObject.getLeftEdge() && this.icons[i].longitude <= ppmObject.getRightEdge() && this.icons[i].latitude >= ppmObject.getBottomEdge() && this.icons[i].latitude <= ppmObject.getTopEdge()) {
							icons.push(this.icons[i]);
						}
						//}
					}
				}
				this.icons = icons;
			}

			if (this.tenInMap.length > 0) {
				var i=0;
				this.tenInMap.each(function(marker) {
					i++;
					// Visible?
					if(marker.xkoord >= ppmObject.getLeftEdge() && marker.xkoord <= ppmObject.getRightEdge() && marker.ykoord >= ppmObject.getBottomEdge() && marker.ykoord <= ppmObject.getTopEdge()) {
						var id = marker.entryId;
						if (id != null) {
							var data = marker.adrz1;
							var longitude = marker.xkoord;
							var latitude = marker.ykoord;

							var title = marker.adrz1;
							if (id.substr(0,1) == 'I') {
								var icon = new IeIcon (longitude, latitude, ppmObject,ppmObject.parentNode.id+"_tim_"+id, null, title)
								icon.entryId = id.substr(1);
							} else {
								var icon = new SeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_tim_"+id, "POI_standardeintrag", title);
								icon.entryId = id;
							}
							icon.draw ();
							icons.push(icon);
						}
					}
				});
				this.icons = icons;
			}

			/* Not needed, since client does the handling of visible icons
			if (this.apiIcons.length > 0) {
				var i=0;
				this.apiIcons.each(function(apiIcon) {
					i++;
					// Visible?
					if(apiIcon.longitude >= ppmObject.getLeftEdge() && apiIcon.longitude <= ppmObject.getRightEdge() && apiIcon.latitude >= ppmObject.getBottomEdge() && apiIcon.latitude <= ppmObject.getTopEdge()) {
						if (apiIcon.onMap == false) {
							icons.push(apiIcon);
							apiIcon.onMap = true;
						}
						apiIcon.draw ();
					} else {
						apiIcon.onMap = false;
					}
				});
				this.icons = icons;
			}
			*/
		} else { // Eagleview Mode
			this.icons = Array ();
			// (sk) Changed from 3000 to 4500
			var edgeNorth = this.evLatitude+4500; // 2500 Units would mark a perfect square, but since Eagleview Tiles are strangely shaped polygons, I go for safety and use 3000 (50 Meters extra)
			var edgeSouth = this.evLatitude-4500;
			var edgeWest = this.evLongitude-4500;
			var edgeEast = this.evLongitude+4500;

			icons = this.icons;
			this.PpmMarkers.userMarkers.each (function (marker) {
				if (marker.longitude*1 > edgeWest
					&& marker.longitude*1 < edgeEast
					&& marker.latitude*1 > edgeSouth
					&& marker.latitude*1 < edgeNorth
				) {
					icons.push (marker.icon);
				}
			});

			this.apiIcons.each (function (apiIcon) {
				apiIcon.onMap = false;
			});

			this.icons=icons;
		}
	},

	updateEv: function (e, ppmObject) {
		if ($(ppmObject.parentNode.id+"_evUpdater").contentDocument != null) {
			response = $(ppmObject.parentNode.id+"_evUpdater").contentDocument;
		} else if ($(ppmObject.evUpdater).contentWindow != null) {
			response = ppmObject.evUpdater.contentWindow.document;
		}
		json = response.body.innerHTML;
		if (json != "}" && json != "") {
			if (json.match(/^0+$/)) {
					ppmObject.evOptionDisable ();
					
			} else {
					if ($(ppmObject.parentNode.id+"_mapmode_eagle") != null) {
						if(ppmObject.helpStatus.eagleViewAvailable < ppmObject.helpStatusCount.eagleViewAvailable && ppmObject.eagleView != 1) {

							if(ppmObject.eagleView != 2 && ppmObject.apiKey == null) {
								ppmObject.showHelpWin ($(ppmObject.parentNode.id+"_mapmode_eagle"), "eagleview_auto_intro", "topright", "auto", null, 200, 6, 0, false);
								ppmObject.helpStatus.eagleViewAvailable++;
							}
						}
						ppmObject.evOptionEnable();
					}
			}
		}
	},

	updateIe: function (e, ppmObject) {
		if (ppmObject.poi.infoEntries != true || ppmObject.zoomLevel > IE_MAX_DISPLAY_LEVEL) {
			if(ppmObject.processes > 0) ppmObject.processes--;
			ppmObject.poiIeLoading=false;
			return (false);
		}
		if ($(ppmObject.parentNode.id+"_ieUpdater").contentDocument != null) {
			response = $(ppmObject.parentNode.id+"_ieUpdater").contentDocument;
		} else if ($(ppmObject.ieUpdater).contentWindow != null) {
			response = ppmObject.ieUpdater.contentWindow.document;
		}
		json = response.body.innerHTML.strip();
		if (json != "}" && json != "") {
			ppmObject.jso = eval("(" + json + ")");
			var entries = $H(ppmObject.jso);
			entries.each (function (entry) {
				var id = entry[0];
				var data = entry[1];
				var longitude = data[0];
				var latitude = data[1];
				var stuff='';
				var name=data[2];
				var icon = new IeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_ie_"+id, stuff, name);
				icon.entryId = id;
				icon.draw ();
			})
		}

		if (ppmObject.processes > 0) {
			ppmObject.processes--;
		}
		ppmObject.poiIeLoading=false;

	},

	updateSe: function (e, ppmObject) {
		if (ppmObject.zoomLevel > BRAID_MAX_DISPLAY_LEVEL) {
			if(ppmObject.processes > 0) ppmObject.processes--;
			ppmObject.poiSeLoading=false;
			return (false);
		}
		if ($(ppmObject.parentNode.id+"_badeUpdater").contentDocument != null) {
			response = $(ppmObject.parentNode.id+"_badeUpdater").contentDocument;
		} else if ($(ppmObject.badeUpdater).contentWindow != null) {
			response = ppmObject.badeUpdater.contentWindow.document;
		}
		json = response.body.innerHTML;

		if (json.length > 3) {
			ppmObject.jso = eval("(" + json + ")");
			var entries = $H(ppmObject.jso);
			entries.each (function (entry) {
				var id = entry[0];
				var data = entry[1];
				var longitude = data[0];
				var latitude = data[1];
				var type = data[2];

				var title = data[4];
				switch (type) {
					case 'H':
						var icon = new IeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_poi_"+id, '', title);
					break;
					case 'I':
						var icon = new IeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_poi_"+id, '', title);
					break;
					case 'O':
						var icon = new IeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_poi_"+id, '', title);
					break;
					default:
						var icon = new SeIcon (longitude, latitude, ppmObject, ppmObject.parentNode.id+"_poi_"+id, data[3], title);
					break;
				}
				icon.entryId = id;
				icon.draw ();
			})
		}

		if (ppmObject.processes > 0) {
			ppmObject.processes--;
		}
		ppmObject.poiSeLoading=false;
	},

	updateIVW: function (e, ppmObject) {
		if ($(ppmObject.parentNode.id+"_ivwUpdater").contentDocument != null) {
			response = $(ppmObject.parentNode.id+"_ivwUpdater").contentDocument;
		} else if ($(ppmObject.evUpdater).contentWindow != null) {
			response = ppmObject.evUpdater.contentWindow.document;
		}
	},

	pan: function (x,y, zoomLevel, callback) {
		baseLayer = $(this.parentNode.id+"_layer_1");
		this.disableEvents();
		ppmObject = this;
		var upp = ppmObject.getUnitsPerPixel();
		if ($(ppmObject.parentNode.id+"_infowindow") == null) {
			new Effect.MoveBy(baseLayer,y,x, {
					afterFinish:function() {
						ppmObject.longitude -= x*upp;
						ppmObject.latitude += y*upp;
						ppmObject.x += x;
						ppmObject.y += y;
						ppmObject.enableEvents();
						ppmObject.updatePoiLayer();
						if (zoomLevel != null && zoomLevel != ppmObject.zoomLevel) {
							ppmObject.setZoomLevel (zoomLevel);
						} else {

							ppmObject.checkRotation(x,y)
						}
						if (callback != null) {
							callback();
						}
						if (ppmObject.minimap != null) {
							ppmObject.minimap.moveToGeo(ppmObject.longitude, ppmObject.latitude);
						}

						if(ppmObject.universalCallback != null)
						{
							ppmObject.universalCallback();
						}

					}


				});

		} else {
			new Effect.Parallel([
				new Effect.MoveBy(baseLayer,y,x),
				new Effect.MoveBy($(ppmObject.parentNode.id+"_infowindow"),y,x)
			], {
					afterFinish:function() {
						ppmObject.longitude -= x*upp;
						ppmObject.latitude += y*upp;
						ppmObject.x += x;
						ppmObject.y += y;
						ppmObject.enableEvents();
						ppmObject.updatePoiLayer();
						if (zoomLevel != null && zoomLevel != ppmObject.zoomLevel) {
							ppmObject.setZoomLevel (zoomLevel);
						} else {

							ppmObject.checkRotation(x,y);
						}
						if (callback != null) {
							callback();
						}
						if (ppmObject.minimap != null) {
							ppmObject.minimap.moveToGeo(ppmObject.longitude, ppmObject.latitude);
						}


						if(ppmObject.universalCallback != null)
						{
							ppmObject.universalCallback();
						}

						}
				});
		}
		this.setViewCookie();
	},

	update: function (x,y) {
		var upp = this.getUnitsPerPixel()
		this.longitude -= x*upp;
		this.latitude += y*upp;
		this.draw();
	},

	getLeftEdgeTile: function () {
		var cornerTile = this.checkerBoard.getTile(0,0);
		return this.x+cornerTile.x;
	},

	getRightEdgeTile: function () {
		var cornerTile = this.checkerBoard.getTile(this.checkerBoard.cols-1,0);
		return this.x+cornerTile.x+TILESIZE;
	},

	getTopEdgeTile: function () {
		var cornerTile = this.checkerBoard.getTile(0,0);
		return this.y+cornerTile.y;
	},

	getBottomEdgeTile: function () {
		var cornerTile = this.checkerBoard.getTile(0,this.checkerBoard.rows-1);
		return this.y+cornerTile.y+TILESIZE;
	},

	eventMouseDown: function (e) {
		this.dragging = true;
		ppmObject = this;
		this.mouseDownX = Event.pointerX(e);
		this.mouseDownY = Event.pointerY(e);
	},

	eventMouseUp: function (e) {
		this.dragging = false;
		this.mousespeed = 0;
		this.drawFromTilequeue();
		Event.stopObserving($(this.parentNode), "mousemove", function (e) {ppmObject.eventHandler.handleEvent(e, ppmObject)}, false);
		var cont = true;
		if (this.eventHandlers.mouseup != null) {
			cont = this.eventHandlers.mouseup ();
		}
		if (this.hasMoved == true) {
			this.IVWLog();
			if (this.eagleView == 1) {
				this.hideEagleViewOverlay ();
				this.evShowOverlay ();
			}
			this.hasMoved = false;
			if (cont == false) {
				return;
			}
			this.cleanUpIcons ();
			this.updatePoiLayer ();
			if (this.eagleView == 0) {
				this.updateEvAvailability();
			}
			if (this.minimap != null) {
				this.minimap.reCenter();
			}
			if(ppmObject.universalCallback != null)
			{
				ppmObject.universalCallback();
			}

			this.setViewCookie();
			
			this.helpStatus.moved++;

		}
	},

	disableEvents: function () {
		this.eventsDisabled = true;
	},

	enableEvents: function () {
		this.eventsDisabled = false;
	},

	drag: function (e) {
		if (this.dragging == false) {
			return false;
		} else {
			switch (this.eagleView) {
				case 2:
					var x = Event.pointerX(e);
					var y = Event.pointerY(e);

					var movedX = x-this.mouseDownX;
					var movedY = y-this.mouseDownY;


					if (this.evX+movedX < this.evLimitX
					&& this.evX+movedX > -(this.evLimitX)) {
						this.evX += movedX;
						var left = parseInt (this.evTile.style.left);
						this.evTile.style.left = (left+movedX)+"px";
					}

					if (this.evY+movedY < this.evLimitY
					&& this.evY+movedY > -(this.evLimitY)) {
						this.evY += movedY;
						var top = parseInt (this.evTile.style.top);
						this.evTile.style.top = (top+movedY)+"px";
					}
					this.mouseDownX = x;
					this.mouseDownY = y;
				break;
				default:
					this.hasMoved = true;
					var x = Event.pointerX(e);
					var y = Event.pointerY(e);
					var movedX = x-this.mouseDownX;
					var movedY = y-this.mouseDownY;
					this.mousespeed = Math.abs(movedX+movedY);
					//console.log (this.mousespeed);
					this.move (movedX,movedY);
					if (this.minimap != null) {
						this.minimap.moveNavi (movedX, movedY);
					}
					this.mouseDownX = x;
					this.mouseDownY = y;
					
					if(MOVES_MAX>MOVES_COUNT){
						MOVES_COUNT++;
					}else{
						if (this.minimap != null) {
							this.minimap.updateFromMap();
							MOVES_COUNT=0;
						}
					}
					
					
			}

		}
	},

	checkRotation: function (x,y) {
		rotated = false;
		check = true;
		while (check == true) {
			check = false;
			if (x>0) {
				leftEdge = this.getLeftEdgeTile();
				if (leftEdge > -1) {
					this.checkerBoard.rotateRight();
					check = true;
					rotated = true;
				}
			}

			if (x<0) {
				rightEdge = this.getRightEdgeTile();
				if (rightEdge < this.width+1) {
					this.checkerBoard.rotateLeft();
					check = true;
					rotated = true;
				}
			}

			if (y>0) {
				topEdge = this.getTopEdgeTile();
				if (topEdge > -1) {
					this.checkerBoard.rotateDown();
					check = true;
					rotated = true;
				}
			}

			if (y<0) {
				bottomEdge = this.getBottomEdgeTile();
				if (bottomEdge < this.height+1) {
					this.checkerBoard.rotateUp();
					check = true;
					rotated = true;
				}
			}
		}
		if (rotated == true) {
			this.apiLog("Panning");
		}
	},

	makeModal: function (domId, doNotClose) {
		this.cleanupUI(doNotClose);
		if($(this.parentNode.id+"_modal") != null) {
			Element.remove ($(this.parentNode.id+"_modal"));
		}

		div = document.createElement ("div");
		div.id = this.parentNode.id+"_modal";
		this.modalDialog = $(domId);
		div.style.position = "absolute";
		div.style.top = "0px";
		div.style.left = "0px";
		div.style.width = this.parentNode.style.width;
		div.style.height = this.parentNode.style.height;
		div.style.zIndex = $(domId).style.zIndex-1;

		if (div.style.MozOpacity != null) {
			div.style.backgroundColor = "#000000";
			div.style.MozOpacity = "0.4";
		} else if (div.style.opacity != null) {
			div.style.opacity = "0.4";
		}
		if (div.style.filter != null) {
			div.style.backgroundColor = "#000000";
			div.style.filter = ("alpha(opacity=40)");
		}
		this.parentNode.appendChild (div);
	},

	showFadingMessage: function (message, seconds) {

	},

	move: function (x,y) {
		var upp = this.getUnitsPerPixel ();
		baseLayer = $(this.parentNode.id+"_layer_1");
		this.x += x;
		this.y += y;
		this.longitude 	-= x*upp;
		this.latitude 	+= y*upp;
		baseLayer.style.left = this.x+"px";
		baseLayer.style.top = this.y+"px";
		if (this.layercount > 2) {
			topLayer = $(this.parentNode.id+"_layer_"+this.layercount);
			topLayer.style.left = this.x+"px";
			topLayer.style.top = this.y+"px";
		}
		this.checkRotation (x,y);
	},

	setRoute: function (streetnumber, housenumber, zipcity, longitude_hidden, latitude_hidden, displayName, longitude, latitude,country) {

			$(streetnumber).value 	    = '';
			$(housenumber).value = '';
			//$(zipcity).value 	 	    = "["+displayName+"]";
			$(zipcity).value 	 	    = displayName;
			$(longitude_hidden).value = longitude;
			$(latitude_hidden).value   = latitude;
			$(country).value="";

	},
	
	exploQueueTiles: function (leftColLongitude, topRowLatitude, dirX, dirY, upp, counter){
			var xVirtualCenter	=	Math.floor(this.cols/2);
			var yVirtualCenter	=	Math.floor(this.rows/2);
			var x = xVirtualCenter+dirX;
	        var y = yVirtualCenter+dirY;
	        if(x >= 0 && x < this.cols && y >= 0 && y < this.rows) {
	        	var tile =  this.checkerBoard.getTile(x,y);
	            tile.aerial = this.aerial;
	            tile.hybrid = this.hybrid;
	            tile.longitude = leftColLongitude + x*TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];
	            tile.latitude = topRowLatitude - y*TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];
	            isConformCoordinate (tile.longitude, tile.latitude, upp);
	            tile.ext = METER_PER_PIXEL[this.zoomLevel-1]*UNITS_PER_METER*TILESIZE/2;
	            tile.x = x*TILESIZE-screenOffsetX+TILESIZE/2;
	            tile.y = y*TILESIZE-screenOffsetY+TILESIZE/2;
	            tile.queueForDrawing();
	            counter++;            
			}
			return counter;
		}

});

Ppm2.implement (ScreenObject);

Ppm2.implement ({
	draw: function (onCompleteFunction) {
		this.initTime = new Date().getTime();
		/*
		if ($("timelog") != null) {
			while ($("timelog").childNodes.length > 0) {
				$("timelog").removeChild($("timelog").firstChild);
			}
		}
		*/
	
		if (this.eagleView > 1) {
			return;
		}
		
		

		if (this.eventHandlers.draw != null) {
			var cont = this.eventHandlers.draw();
			if (cont == false) {
				return;
			}
		}
		
		// if (((this.getMapMode() == "aerial") || (this.getMapMode() == "hybrid")) && this.zoomLevel < 2) {
		//	 this.setZoomLevel (2);
		// }
		
		if ($(this.parentNode.id+"_minimap") != null && $(this.parentNode.id+"_static_minimap") != null) {
			if (this.getUnitsPerPixel() > 5120) {
				$(this.parentNode.id+"_minimap").style.display = "none";
				$(this.parentNode.id+"_static_minimap").style.display = "block";
			} else {
				$(this.parentNode.id+"_minimap").style.display = "block";
				$(this.parentNode.id+"_static_minimap").style.display = "none";
			}
		}
		
		if (this.width < 450) {
			if ($(this.parentNode.id+"_static") != null) {
				Element.remove ($(this.parentNode.id+"_static"));
			}
			var static = document.createElement ("img");
			
			var left = this.longitude - (this.width/2)*this.getUnitsPerPixel();
			var right = this.longitude + (this.width/2)*this.getUnitsPerPixel();
			var top = this.latitude + (this.height/2)*this.getUnitsPerPixel();
			var bottom = this.latitude - (this.height/2)*this.getUnitsPerPixel();
			
			var mapmode = 0;
			if (this.aerial) {
				mapmode++;
			}
			
			if (this.hybrid) {
				mapmode++;
			}
			
			//static.src = "http://ppm.klicktel.de/scripts/image.dll?GetXMapDirect&left="+left+"&top="+top+"&right="+right+"&bottom="+bottom+"&out=3&w="+this.width+"&h="+this.height+"&routid=-1&aerial="+mapmode+"&poicat=&stau=0&wetter=0&sel_x=-1&sel_y=-1&hnr=1";
			static.src = "http://nmap01.ppm-ng.de/scripts/image.dll?GetXMapDirect&left="+left+"&top="+top+"&w="+this.width+"&h="+this.height+"&zoom="+this.getUnitsPerPixel()*100+"&routeid=-1&trafficjam=0&layer=16";
			static.id = this.parentNode.id+"_static";
			this.parentNode.appendChild(static);
			this.copyright.draw ();
			return;
		}
		
		for (var y=0;y<this.rows;y++) {
			for (var x=0; x<this.cols;x++) {
				tile = this.checkerBoard.matrix[y][x];
				if (tile != null) {
					tile.destroy();
				}
			}
		}
		
		baseLayer = $(this.parentNode.id+"_layer_1");
		baseLayer.style.left = "0px";
		baseLayer.style.top = "0px";
		Element.update (baseLayer, "");
		this.x = 0;
		this.y = 0;

		this.buildCheckerBoard ();

		if (this.zoomLevelHome == 0 && this.longitudeHome == 0 && this.latitudeHome == 0) {
			this.zoomLevelHome = this.zoomLevel;
			this.longitudeHome = this.longitude;
			this.latitudeHome = this.latitude;
		}
		tileWidthUnits = TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];
		tileHeightUnits = TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];

		leftEdge = this.longitude - (this.width/2*METER_PER_PIXEL[this.zoomLevel-1]*UNITS_PER_METER);
		topEdge = this.latitude + (this.height/2*METER_PER_PIXEL[this.zoomLevel-1]*UNITS_PER_METER);

		var upp = this.getUnitsPerPixel();
				

		var validTileLongitude = (upp*TILESIZE)*(Math.floor((this.longitude-NMAP_WORLD_X)/(upp*TILESIZE)))+NMAP_WORLD_X;
		if (this.cols % 2 == 0) { // Even number of rows, more difficult
			//Check if point is in top portion of tile or in bottom
			var distanceToLeft = this.longitude-validTileLongitude;
			var pointInLeft = (distanceToLeft > tileWidthUnits/2);
			if (pointInLeft) {
				var colsLeft = this.cols/2-1;
			} else {
				var colsLeft = this.cols/2;
			}
		} else { //Odd number off rows, this is easy
			var colsLeft = Math.floor (this.cols/2);
		}
		leftColLongitude = validTileLongitude-colsLeft*tileWidthUnits;
		screenOffsetX = Math.floor((leftEdge-(leftColLongitude-tileWidthUnits/2))/upp);           


		var validTileLatitude = (upp*TILESIZE)*(Math.ceil((this.latitude-NMAP_WORLD_Z2)/(upp*TILESIZE)))+NMAP_WORLD_Z2;       
		if (this.rows % 2 == 0) { // Even number of rows, more difficult
			//Check if point is in top portion of tile or in bottom
			var distanceToTop = validTileLatitude-this.latitude;
			var pointInTop = (distanceToTop < tileHeightUnits/2);
			if (pointInTop) {
				var rowsUp = (this.rows/2);
			} else {
				var rowsUp = (this.rows/2)-1;
			}
		} else { //Odd number off rows, this is easy
			var rowsUp = Math.floor (this.rows/2);
		}
		topRowLatitude = validTileLatitude+rowsUp*tileHeightUnits;
		screenOffsetY = Math.floor((topRowLatitude-(topEdge-tileHeightUnits/2))/upp);							
		
		
		
		//Test valid Explosions-Algorythm
		var maxTiles		=	this.cols*this.rows;
		var a_count			=	0;
		var	i				=	0;
		var	x_wayOne		=	-1;
		var	y_wayOne		=	1;
		var	x_wayTwo		=	-1;
		var	y_wayTwo		=	-1;
		var circle			=	1;
		var parkx;
		var parky;
		dirX		=	0*i;
		dirY		=	0*i;
		a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
		i++;
		while(a_count<maxTiles){
			dirX	=	0;
			dirY	=	y_wayOne*i;
			a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
			dirX	=	x_wayOne*i;
			dirY	=	0;
			a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
			x_wayOne=-1*x_wayOne;
			y_wayOne=-1*y_wayOne;
			dirX	=	0;
			dirY	=	y_wayOne*i;
			a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
			dirX	=	x_wayOne*i;
			dirY	=	0;
			a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
			for(var j=1;j<=2;j++){
				if (j==1){
					for (var k=circle;k>=1;k--){
						dirX=	x_wayOne*k;
						dirY=	y_wayOne*circle;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						x_wayOne=-1*x_wayOne;
						y_wayOne=-1*y_wayOne;
						dirX=	x_wayOne*k;
						dirY=	y_wayOne*circle;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						dirX=	x_wayTwo*circle;
						dirY=	y_wayTwo*k;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						x_wayTwo=-1*x_wayTwo;
						y_wayTwo=-1*y_wayTwo;
						dirX=	x_wayTwo*circle;
						dirY=	y_wayTwo*k;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
					}
				}else{
					for (var k=circle-1;k>=1;k--){
						dirX=	x_wayOne*circle;
						dirY=	y_wayOne*k;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						x_wayOne=-1*x_wayOne;
						y_wayOne=-1*y_wayOne;
						dirX=	x_wayOne*circle;
						dirY=	y_wayOne*k;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						dirX=	x_wayTwo*k;
						dirY=	y_wayTwo*circle;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
						x_wayTwo=-1*x_wayTwo;
						y_wayTwo=-1*y_wayTwo;
						dirX=	x_wayTwo*k;
						dirY=	y_wayTwo*circle;
						a_count = this.exploQueueTiles(leftColLongitude, topRowLatitude, dirX, dirY, upp, a_count);
					}
				}
			}
			circle++;
			i++;
		}
		this.drawFromTilequeue();
		this.copyright.draw ();
		 
		//End
		/*	

		if (this.rows<=8 && this.cols<=8){
			//Snail queueing 
	
			var totalTiles = this.rows*this.cols;
			var queued = 0;
			
			var xVirtual = Math.round ((this.cols-1)/2);
			var yVirtual = Math.round ((this.rows-2)/2);	
		
			var dirTurns = 0;
			var steps = 0;
			var distance = 1;
			
			var directions = Array ({x:1,y:0}, {x:0,y:-1}, {x:-1,y:0}, {x:0, y:1});
					
			while (queued < totalTiles) {
				if (xVirtual >= 0 && xVirtual < this.cols && yVirtual >= 0 && yVirtual < this.rows) {
					x = xVirtual;
					y = yVirtual;
					var tile =  this.checkerBoard.getTile(x,y);
					tile.aerial = this.aerial;
					tile.hybrid = this.hybrid;
					tile.longitude = leftColLongitude + x*TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];
					tile.latitude = topRowLatitude - y*TILESIZE*UNITS_PER_METER*METER_PER_PIXEL[this.zoomLevel-1];
					tile.ext = METER_PER_PIXEL[this.zoomLevel-1]*UNITS_PER_METER*TILESIZE/2;
					
					
					tile.x = x*TILESIZE-screenOffsetX+TILESIZE/2;
					tile.y = y*TILESIZE-screenOffsetY+TILESIZE/2;
					//tile.x = x*TILESIZE-screenOffsetX+TILESIZE/2;
					//tile.y = y*TILESIZE-screenOffsetY+TILESIZE/2;
					tile.queueForDrawing();
					queued++;
					
				}
				
				var direction =  directions[dirTurns%4];
				
				xVirtual+=direction.x;
				yVirtual+=direction.y;
				steps++;
				if (steps == distance) {
					dirTurns++;
					steps = 0;
					if ((dirTurns % 2) == 0) {
						distance++;					
					}
				}
				
			}
		*/
		//this.drawFromTilequeue();			

		
		if (1) { //Set Minimap mode according to zoomlevel
		}

		this.IVWLog();
		
		//Log initial draw of Kartensuche
		if (this.initialTrack == 0 && location.pathname.match(/kartensuche-result.html/)) {
			switch (this.getMapMode()) {
				case "aerial":
					var ansicht = "Luftbild";
				break;
				case "hybrid":
					var ansicht = "Hybrid";
				break;
				default:
					var ansicht = "Karte";
				
			}
			this.urchinDirect ("/kartensuche/kartensuche-tracking.html?Ansicht="+ansicht);
			this.initialTrack++;
		}
		
	if (this.PpmMarkers.linkMarkers.length == 0) {
		this.PpmMarkers.userMarkers.each (function (marker){
			marker.draw ();
		})
	} else {
		this.PpmMarkers.userMarkers.each (function (marker){
			marker.draw ();
		})
		this.PpmMarkers.linkMarkers.each (function (marker){
			marker.draw ();
		})
	}

	this.updatePoiLayer ();

	this.updateEvAvailability();

	if (this.minimap != null) {
		this.minimap.updateFromMap();
	}

	if (this.eagleView == 1) {
		this.evShowOverlay ();
	}
	if (this.scale != null) {
		this.scale.src = "http://www.klicktel.de/kt_map/images/scale.php?mpp="+METER_PER_PIXEL[this.zoomLevel-1];
	}


		if(onCompleteFunction != null) {
			onCompleteFunction();
		}

	},

	getAbsoluteActiveArea:function()
	{
		ppmPos=Position.cumulativeOffset($(this.parentNode.id));
		ppmAreaLeft=ppmPos[0]+parseInt(this.leftWidgetCol.style.width);
		ppmAreaTop=ppmPos[1]+parseInt(this.leftWidgetCol.style.top);
		ppmAreaRight=ppmPos[0]+this.width-parseInt(this.rightWidgetCol.style.width);
		ppmAreaBottom=ppmPos[1]+parseInt(this.leftWidgetCol.style.top)+this.height;
		a=[ppmAreaTop, ppmAreaRight, ppmAreaBottom, ppmAreaLeft];
		return a;
	},

	setHelpStatus: function(v)
	{
		if($(this.parentNode.id+'_useful_check_help') != null) {
			if(v == 1) {
				$(this.parentNode.id+'_useful_check_help').checked=true;
			} else {
				$(this.parentNode.id+'_useful_check_help').checked=false;
			}
		}
		HELP_PPM_Active=v;
	},

	showInfoLayer: function(infoId, type, onBeforeShow, layerWidth)
	{
		if(layerWidth == null) {
			layerWidth=350;
		}


		absDims=this.getAbsoluteActiveArea();
		areaWidth=absDims[1]-absDims[3];
		areaHeight=absDims[2]-absDims[0];
		initShowInfoLayer(Math.round(absDims[3]+((areaWidth-layerWidth)/2)), (absDims[0]+20), infoId, 1, layerWidth, onBeforeShow, type);
	},


	showHelpWin: function(elId, helpId, orientation, type, onBeforeShow, layerWidth, offsetX, offsetY, centerOnObject, forcedXPos, forcedYPos)
	{
		if(layerWidth == null) {
			layerWidth=350;
		}

		if(centerOnObject == null) {
			centerOnObject=true;
		}

		if(offsetX == null) offsetX=0;
		if(offsetY == null) offsetY=0;
		initShowHelpWin(elId, helpId, orientation, 1, layerWidth, centerOnObject, onBeforeShow, type, offsetX, offsetY, forcedXPos, forcedYPos);
	},

	hideHelpWin: function()
	{
		closeHelpWin();
	},

	hideInfoLayer: function()
	{
		hideInfoLayer();
	},


	setViewCookie:function()
	{
		if (this.apiKey != null) {
			return;
		}
		url='http://'+location.hostname+this.ajaxPath+'cookie'+this.ajaxExtension;
		// LONG,LAT,MAPMODE,ZOOMLEVEL
		if(this.eagleView == 2) {
			pars="action=set&area=ppm&type=position&option=loc&value="+this.evLongitude+'-'+this.evLatitude+'-eagle-'+this.evZoomLevel+'-'+this.evDirection;
		} else {
			pars="action=set&area=ppm&type=position&option=loc&value="+this.longitude+'-'+this.latitude+'-'+this.getMapMode()+'-'+this.zoomLevel+'-0';
		}
		pars+='&_rnd='+Math.random();
		var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars,  onComplete: function() {}});
	},


	showTooltip:function(x,y,html) {
		Element.update($(ppmObject.parentNode.id+'_tooltip'), html);

		if (this.eagleView < 2) {
			newX=x+this.x;
			newY=y+ppmObject.y;
		} else {
			newX=x-(this.evWidth-this.width)/2+this.evX;
			newY=y+this.y-(this.evHeight-this.height)/2+this.evY;
		}

		var dimensions = Element.getDimensions(this.parentNode.id+'_tooltip');
		listWidth  = dimensions.width;
		listHeight = dimensions.height;

		if (newX <= this.width/2 && newY <= this.height/2) {
			// oben links
			$(this.parentNode.id+'_tooltip').style.left = newX+"px";
			$(this.parentNode.id+'_tooltip').style.top  = newY+"px";
		} else if (newX > this.width/2 && newY <= this.height/2) {
			//oben rechts
			$(this.parentNode.id+'_tooltip').style.left = newX-listWidth+"px";
			$(this.parentNode.id+'_tooltip').style.top  = newY+"px";
		} else if (newX <= this.width/2 && newY > this.height/2) {
			// unten links
			$(this.parentNode.id+'_tooltip').style.left = newX+"px";
			$(this.parentNode.id+'_tooltip').style.top  = (newY-listHeight)+"px";
		} else if (newX > this.width/2 && newY > this.height/2) {
			// unten rechts;
			$(this.parentNode.id+'_tooltip').style.left = (newX-listWidth)+"px";
			$(this.parentNode.id+'_tooltip').style.top  = (newY-listHeight)+"px";
		}

		$(this.parentNode.id+'_tooltip').style.display='block';
	},

	cleanupApiIcons: function () {
		this.apiIcons.each (function (point) {
			if ($(point.domId) != null) {
				Element.remove ($(point.domId));
			}
		});
		this.apiIcons = [];
	},

	cleanupApiRectangles: function () {
		this.apiRectangles.each (function(rectangle) {
			if ($(rectangle.domId) != null) {
				Element.remove ($(rectangle.domId));
			}
		});
		this.apiRectangles = [];
	},

	cleanupApiObjects: function () {
		this.cleanupApiIcons();
		this.cleanupApiRectangles();
	},

	cleanupUI:function(doNotClose)
	{
		ppmObject=this;
		divs=['tooltip'];
		if(divs.length > 0) {
			divs.each(function(div) {
				if (doNotClose != null) {
					doNotClose.each(function(id){
						if($(ppmObject.parentNode.id+'_'+div) != null) {
							if (ppmObject.parentNode.id+'_'+div != id){
								$(ppmObject.parentNode.id+'_'+div).style.display='none';
							}
						}
					});
				} else {
					if($(ppmObject.parentNode.id+'_'+div) != null) {
						$(ppmObject.parentNode.id+'_'+div).style.display='none';
					}
				}
			});
		}

		myFoldoutsLeft=document.getElementsByClassName('ppm_foldout_right', ppmObject.leftWidgetCol);
		myFoldoutsRight=document.getElementsByClassName('ppm_foldout_left', ppmObject.rightWidgetCol);

		if(myFoldoutsLeft.length > 0) {
			myFoldoutsLeft.each(function(elm) {
				if (doNotClose != null) {
					doNotClose.each(function(id){
						if (elm.id != id){
							elm.close();
						}
					});
				} else {
					elm.close();
				}

			});
		}

		if(myFoldoutsRight.length > 0) {
			myFoldoutsRight.each(function(elm) {
				if (doNotClose != null) {
					doNotClose.each(function(id){
						if (elm.id != id){
							elm.close();
						}
					});
				} else {
					elm.close();
				}
			});
		}

		divs=ppmObject.contextMenuController.menus;
		if(divs.length > 0) {
			divs.each(function(div) {
				if (doNotClose != null) {
					doNotClose.each(function(id){
						if($(ppmObject.parentNode.id+'_'+div) != null) {
							if ($(ppmObject.parentNode.id+'_'+div) != id){
								$(ppmObject.parentNode.id+'_'+div).style.display='none';
							}
						}
					});
				} else {
					if($(ppmObject.parentNode.id+'_'+div) != null) {
						$(ppmObject.parentNode.id+'_'+div).style.display='none';
					}
				}
			});
		}

		// Close help layers (help.js)
		if($('helpLayer') != null) {
			closeHelpWin();
		}

		if($('infoLayer') != null) {
			closeInfoLayer();
		}
	},



	findMarkerByID: function(markerArray, markerDBID)
	{
		markerFound=null;
		if(markerArray.length > 0) {
			markerArray.each(function(marker) {
				if(marker.markerDBID == markerDBID) {
					markerFound=marker;
				}
			});
		}
		return markerFound;
	},


	findMarkerByRefID: function(markerArray, markerDBID)
	{
		markerFound=null;
		if(markerArray.length > 0) {
			markerArray.each(function(marker) {
				if(marker.refID == markerDBID) {
				markerFound=marker;
				}
			});
		}
		return markerFound;
	},

	findMarkerByMyID: function(markerArray, myID)
	{
		markerFound=null;
		if(markerArray.length > 0) {
			markerArray.each(function(marker) {
				if(marker.myID == myID) {
				markerFound=marker;
				}
			});
		}
		return markerFound;
	},

	getHoverRectangle: function() {
		if (ppmObject.eagleView > 0) {
			return null; //No rectangles in EagleView Mode
		}
		results=Array();
		var ppmPos = Position.cumulativeOffset(ppmObject.parentNode);
		var mapX = ppmObject.mouseX - ppmPos[0];
		var mapY = ppmObject.mouseY - ppmPos[1];
		var geo = ppmObject.getGeo (mapX, mapY);
		if(ppmObject.apiRectangles.length > 0) {
			ppmObject.apiRectangles.each(function(rectangle) {
				if (rectangle.within (geo.longitude, geo.latitude)) {
					results.push (rectangle);
				}
			});
		}
		if (results.length>0) {
			return results[results.length-1];
		} else {
			return null;
		}
	},

	getHoverIcon:function()
	{
		switch (ppmObject.eagleView) {
			case 1: //Overlay grid, don't do Hovers
				return null;
			break;

			case 2:
				results=Array();
				var ppmPos = Position.cumulativeOffset(ppmObject.parentNode);
				var mapX = ppmObject.mouseX - ppmPos[0];
				var mapY = ppmObject.mouseY - ppmPos[1];
				//Only use markers, work on special marker icons in EV Mode
				for (i=ppmObject.icons.length-1; i>=0 ;i--) {
					icon=ppmObject.icons[i];
					if ($("ev_"+icon.domId) != null && Position.within($("ev_"+icon.domId), ppmObject.mouseX, ppmObject.mouseY)) {
							results.push(icon);
					}
				};
			break;

			default:
			results=Array();
			var ppmPos = Position.cumulativeOffset(ppmObject.parentNode);
			var mapX = ppmObject.mouseX - ppmPos[0];
			var mapY = ppmObject.mouseY - ppmPos[1];
			var geo = ppmObject.getGeo (mapX, mapY);
			var allIcons = ppmObject.icons.concat(ppmObject.apiIcons);
			if(allIcons.length > 0) {
				hovered=false;
				var upp = ppmObject.getUnitsPerPixel();
				for (i=allIcons.length-1; i>=0 ;i--) {
					icon = allIcons[i];
					leftEdge = 1*icon.longitude-(icon.offsetX*upp);
					rightEdge = 1*icon.longitude+(icon.offsetX*upp);
					topEdge = 1*icon.latitude+(icon.offsetY*upp);
					bottomEdge = 1*icon.latitude;
					if (geo.longitude > leftEdge &&
						geo.longitude < rightEdge &&
						geo.latitude > bottomEdge &&
						geo.latitude < topEdge &&
						ppmObject.withinActiveArea(ppmObject.mouseX, ppmObject.mouseY)
						) {
						results.push(icon);
					}
				}
			} else {
				return null;
			}
		}

		// If more than one icon was found, pick the correct one!
		ieFound=0;
		seFound=0;
		markerFound=0;
		foundIE=Array();
		foundSE=Array();
		foundMarkers=Array();
		foundApi=Array();
		if(results.length > 0) {
			if(results.length == 1) {
				return results[0];
			} else {
				results.each(function(icon) {
					if(icon.type=='ie') {
						ieFound++;
						foundIE.push(icon);
						return icon; // Use the first IE icon found!
					} else if(icon.type=='se') {
						seFound++;
						foundSE.push(icon);
					} else if(icon.type=='marker') {
						markerFound++;
						foundMarkers.push(icon);
					} else if(icon.type=='api') {
						markerFound++;
						foundApi.push(icon);
					} else {
						console.log('ERROR - ICON HAS AN INVALID TYPE: '+icon.type);
					}
				});

				if(foundIE.length > 0) {
					return foundIE[0];
				}

				if(foundMarkers.length > 0) {
					return foundMarkers[0];
				}

				if(foundSE.length > 0) {
					return foundSE[0];
				}

				if(foundApi.length > 0) {
					return foundApi[0];
				}
			}
		}
		return null;
	}
	
});

ConnectionManager = Base.extend ({
	PPM_SERVERS:4,
	roundRobin:0,

	getServerId: function () {
		if (this.roundRobin == this.PPM_SERVERS) {
			this.roundRobin = 0;
		}
		this.roundRobin++;
		return this.roundRobin;
	}


});

var irqBusy=false;
var widgetsLoaded=false;

function irq () {
	if (ppmObjects.length< 1) {
		return;
	}
	irqBusy=true;
	if (typeof(irq.sequence) == 'undefined') {
		irq.sequence = 0;
	} else {
		irq.sequence++;
	}



	ppmObjects.each(function(ppmObject) {
		if (ppmObject.widgetsloading > 0) {
			return;
		} else {
			if(widgetsLoaded == false) {
				widgetsLoaded=true;
				//ppmObject.irqTasks.queue.push(ppmObject.makeFoldoutControls);
				//ppmObject.irqTasks.queue.push(ppmObject.makeTransparencies);
			}
		}


		//Check for visible API-Icons
		/* No longer needed since client does API Icon handling
		if (ppmObject.dragging == false || irq.sequence % 2 == 0) { //Reduce update frequency when dragging
			ppmObject.apiIcons.each (function (icon) {
				if (icon.longitude > ppmObject.getLeftEdge() &&
					icon.longitude < ppmObject.getRightEdge() &&
					icon.latitude > ppmObject.getBottomEdge() &&
					icon.latitude < ppmObject.getTopEdge()) {
					if (icon.onMap == false) {
						ppmObject.icons.push(icon);
						icon.onMap = true;
						icon.draw();
					}
				}
			});
		}
		*/
		
		
	
		if (ppmObject.mousespeed < MOUSE_THRESHOLD) {
			//if (this.hybrid != 1) {
			if (ppmObject.tilesloading == 0 || ppmObject.tilequeues.flatten().length > 8) {
				ppmObject.drawFromTilequeue();
			}
		}

		if ($("queuesize") != null) {
			$("queuesize").style.left = (ppmObject.tilequeues.flatten().length*20)+"px";
		}
		
		if ($("tilesloading") != null) {
			$("tilesloading").style.left = (ppmObject.tilesloading*20)+"px";
		}
		
		if ($("mousespeed") != null) {
			$("mousespeed").style.left = (ppmObject.mousespeed*20)+"px";
		}

		if (ppmObject.dragging == true) {
			return;
		}

		if (ppmObject.irqTasks.updateTransparencies == true) {
			ppmObject.irqTasks.updateTransparencies = false;
			ppmObject.makeTransparencies ();
		}

		if (ppmObject.irqTasks.makeFoldoutControls == true) {
			ppmObject.irqTasks.makeFoldoutControls = false;
			ppmObject.makeFoldoutControls();
		}

		if (ppmObject.irqTasks.updateZIndex == true) {
			ppmObject.irqTasks.updateZIndex = false;
			if ($(ppmObject.parentNode.id+"_contextMenuMap_container") != null) {
				$(ppmObject.parentNode.id+"_contextMenuMap_container").style.zIndex = 8192;
			}
		}


		if (ppmObject.irqTasks.queue.length > 0 && ppmObject.processes == 0) {
			var queuefunction = ppmObject.irqTasks.queue.pop();
			queuefunction ();
		}

		if (ppmObject.zoomLevel > 5) {
			ppmObject.evOptionDisable();
		}

		if(ppmObject.irqTasks.updateScratchpads == true) {
			ppmObject.irqTasks.updateScratchpads = false;
			if(ppmObject.scratchPads.linkMarkers != null) {
				ppmObject.scratchPads.linkMarkers.update();
			}
			if(ppmObject.scratchPads.userMarkers != null) {
				ppmObject.scratchPads.userMarkers.update();
			}
		}


		if ($(ppmObject.parentNode.id+"_modal") != null) {
			if ($(ppmObject.modalDialog.id) == null || ppmObject.modalDialog.style.display == 'none') {
				ppmObject.modalDialog = null;
				if($(ppmObject.parentNode.id+"_modal") != null) {
					Element.remove ($(ppmObject.parentNode.id+"_modal"));
				}
			}
		}

		if (ppmObject.longitude != ppmObject.irqState.longitude ||
			ppmObject.latitude != ppmObject.irqState.latitude ||
			ppmObject.zoomLevel != ppmObject.irqState.zoomLevel
		) {
			ppmObject.irqState.longitude = ppmObject.longitude;
			ppmObject.irqState.latitude = ppmObject.latitude;
			ppmObject.irqState.zoomLevel = ppmObject.zoomLevel;
		}


		if (ppmObject.processes < 0) {
			ppmObject.processes = 0;
		}

		// HELP COOKIE PARSING

		if(ppmObject.helpStatusChecked==false && ppmObject.apiKey == null) {
			url='http://'+location.hostname+ppmObject.ajaxPath+'cookie'+ppmObject.ajaxExtension;
			pars="action=get&area=ppm&type=help&_rnd="+Math.random();
			ppmObject.helpStatusChecked=true;
			var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars,  onComplete: function(obj) {
				json = obj.responseText;
				if (json != "}" && json != "") {
					ppmObject.jso = eval("(" + json + ")");
					var entries = $H(ppmObject.jso);
					entries.each (function (entry) {
						var cName = entry[0];
						var cValue = entry[1];
						if(cName=="active") {
							ppmObject.setHelpStatus(cValue);
							if($(ppmObject.parentNode.id+'_useful_check_help') != null) {
								if(cValue == 1) {
									$(ppmObject.parentNode.id+'_useful_check_help').checked=true;
								} else {
									$(ppmObject.parentNode.id+'_useful_check_help').checked=false;
								}
								ppmObject.helpStatusCheckboxChecked=true;
							} else {
								ppmObject.helpStatusCheckboxChecked=false;
							}
						}
					})
				}
			}});
		} else if(ppmObject.helpStatusCheckboxChecked == false) {
			// If the checkbox is not yet there we need to check this on any irq
			if($(ppmObject.parentNode.id+'_useful_check_help') != null) {
				if(HELP_PPM_Active == 1) {
					$(ppmObject.parentNode.id+'_useful_check_help').checked=true;
				} else {
					$(ppmObject.parentNode.id+'_useful_check_help').checked=false;
				}
				ppmObject.helpStatusCheckboxChecked=true;
			} else {
				ppmObject.helpStatusCheckboxChecked=false;
			}
		}


		// Depending on timing the Scratchpad is sometimes not fully open when the page is loaded
		// This should fix the problem
		if(ppmObject.scratchPadStatusChecked == false) {
			if($(ppmObject.parentNode.id+'_Scratchpad_user') != null) {
				if(ppmObject.scratchPads.userMarkers != null) {
					if(ppmObject.scratchPads.userMarkers.isOpen == 1) {
						ppmObject.scratchPadStatusChecked=true;
						ppmObject.scratchPads.userMarkers.update();
					}
				}
			}
		}

		if (ppmObject.processes == 0) {
			if($(ppmObject.parentNode.id+"_bitte_warten").style.display != "none") {
				$(ppmObject.parentNode.id+"_bitte_warten").style.display = "none";
				if(ppmObject.universalCallback != null)
				{
					ppmObject.universalCallback();
				}
			}

			// Set the radio buttons for the mapmode automatically
			if(irq.sequence % 4 == 0) {
				if(ppmObject.eagleView) {
					if($(ppmObject.parentNode.id+'_mapmode_eagle') != null) {
						$(ppmObject.parentNode.id+'_mapmode_eagle').checked=true;
					}
				} else if(ppmObject.aerial==0 && ppmObject.hybrid == 0) {
					if($(ppmObject.parentNode.id+'_mapmode_map') != null) {
						$(ppmObject.parentNode.id+'_mapmode_map').checked=true;
					}
				} else if(ppmObject.aerial == 1 && ppmObject.hybrid == 0) {
					if($(ppmObject.parentNode.id+'_mapmode_aerial') != null) {
						$(ppmObject.parentNode.id+'_mapmode_aerial').checked=true;
					}
				} else if(ppmObject.aerial == 1 && ppmObject.hybrid == 1) {
					if($(ppmObject.parentNode.id+'_mapmode_hybrid') != null) {
						$(ppmObject.parentNode.id+'_mapmode_hybrid').checked=true;
					}
				}
			}

			if($(ppmObject.parentNode.id+"_modal") == null) {

			if(ppmObject.eagleView == 1) {
				if(ppmObject.helpStatus.eagleViewOverlay < ppmObject.helpStatusCount.eagleViewOverlay) {
					ppmObject.showInfoLayer('eagleview_overlay_intro', 'manual'); // Manuell, da sonst nicht angezeigt, wenn autom. Hilfe deaktiviert!
					ppmObject.helpStatus.eagleViewOverlay++;
				}
			}

				var icon=ppmObject.getHoverIcon();

				if(icon != null) {
					if (icon != ppmObject.hoverIcon) { //This is a new hover, do the event handling
						ppmObject.hoverIcon = icon;

						if (ppmObject.eventHandlers.iconhoverin != null) {
							var cont = ppmObject.eventHandlers.iconhoverin(icon);
							if (cont == false) {
								return}
							;
						}

						if (icon.hoverUrl != null && icon.hoverUrl != "") {
							icon.showHoverSymbol();
						}

						if(($(icon.domId) != null) || ($('ev_'+icon.domId) != null)) {
							var iconTipX = parseInt($(icon.domId).style.left)+icon.offsetX;
							var iconTipY = parseInt($(icon.domId).style.top)+icon.offsetY;
							ppmObject.showTooltip (iconTipX, iconTipY, icon.title);
						}
					}
				} else { //No hover icon found
					if (ppmObject.hoverIcon != null) { //New hover out, do the event handling
						icon = ppmObject.hoverIcon;
						ppmObject.hoverIcon = null;
						if (ppmObject.eventHandlers.iconhoverout != null) {
							var cont = ppmObject.eventHandlers.iconhoverout(icon);
							if (cont == false) {
								return;
							}
						}
						if (icon.hoverUrl != null && icon.hoverUrl != "") {
							icon.showRegularSymbol();
						}
						$(ppmObject.parentNode.id+'_tooltip').style.display='none';
					}
				}
			}

			var rectangle=ppmObject.getHoverRectangle();

			if(rectangle != null) {
				if (rectangle != ppmObject.hoverRectangle) { //This is a new hover, do the event handling
					if (ppmObject.hoverRectangle != null && ppmObject.hoverRectangle != rectangle) { //New hover out, do the event handling
						if ($(ppmObject.hoverRectangle.domId) != null) {
							$(ppmObject.hoverRectangle.domId).style.backgroundColor = ppmObject.hoverRectangle.backgroundColor;
						}
					}
					ppmObject.hoverRectangle = rectangle;
					if (ppmObject.eventHandlers.rectanglehoverin != null) {
						var cont = ppmObject.eventHandlers.rectanglehoverin(rectangle);
						if (cont == false) {
							return;
						}
					}
					if ($(rectangle.domId) != null) {
						$(rectangle.domId).style.backgroundColor = rectangle.hoverColor;
						ppmObject.showTooltip (parseInt($(rectangle.domId).style.left)+20, parseInt($(rectangle.domId).style.top)+20, rectangle.title);
					}
				}
			} else { //No hover icon found
				if (ppmObject.hoverRectangle != null) { //New hover out, do the event handling
					rectangle = ppmObject.hoverRectangle;
					ppmObject.hoverRectangle = null;

					if (ppmObject.eventHandlers.rectanglehoverout != null) {
						var cont = ppmObject.eventHandlers.rectanglehoverout(rectangle);
						if (cont == false) {
							return;
						}
					}
					$(ppmObject.parentNode.id+'_tooltip').style.display='none';
					if ($(rectangle.domId) != null) {
						$(rectangle.domId).style.backgroundColor = rectangle.backgroundColor;
					}
				}
			}

		} else {
			if($(ppmObject.parentNode.id+"_bitte_warten").style.display != "block") {
				ppmObject.cleanupUI();
				$(ppmObject.parentNode.id+"_bitte_warten").style.display = "block";
			}
		}


		if (ppmObject.pageMode == 'local') {
			switch (ppmObject.addressMode) {
				case 0:
					if ($(ppmObject.parentNode.id+"_route_address_container") != null) {
						$(ppmObject.parentNode.id+"_route_address_container").style.display="block";
						if (ppmObject.addressMode != ppmObject.lastAddressMode) {
							$(ppmObject.parentNode.id+"_enter_address_content").close();
							$(ppmObject.parentNode.id+"_route_eingabe_content").open();
						}
					}
				break;
				case 1:
					if ($(ppmObject.parentNode.id+"_route_address_container") != null) {
						$(ppmObject.parentNode.id+"_route_address_container").style.display="block";
						if (ppmObject.addressMode != ppmObject.lastAddressMode) {
							$(ppmObject.parentNode.id+"_enter_address_content").open();
							$(ppmObject.parentNode.id+"_route_eingabe_content").close();
						}
					}
				break;
			}
		}

		if (ppmObject.eagleView != 2 && $(ppmObject.parentNode.id+"_eagleview_container") != null) {
			$(ppmObject.parentNode.id+"_eagleview_container").style.display = "none";
		}
		ppmObject.lastAddressMode = ppmObject.addressMode;
	});

	irqBusy=false;
}

var connectionManager = new ConnectionManager ();


IRQ_FREQUENCY=0.5;
var irqInterval = new PeriodicalExecuter(irq, IRQ_FREQUENCY);

function isConformCoordinate (longitude, latitude, upp) {
		var miMmPerPixel = upp*100;
		var mX = longitude - NMAP_WORLD_X;
		var mY = latitude - NMAP_WORLD_Z;
		if(isConformZoomlevel(upp)){
            var RealCellSize = NMAP_CELL_SIZE*miMmPerPixel/100;
			if (mX%RealCellSize != 0) {
				console.warn ("Non-Conform Longitude: "+longitude);
			}
			if (mY%RealCellSize != 0) {
				console.warn ("Non-Conform Latitude: "+latitude);
			}
           	return mX%RealCellSize==0 && mY%RealCellSize==0;
      	}
		return false;
}

function isConformZoomlevel (upp) {
		var zl=125;
		var miMmPerPixel = upp*100;
		while(zl<=miMmPerPixel && zl<=4096000 ) {
			if( zl==miMmPerPixel ) {
                  return true;
            }
            
             if( zl==4096000 ) { //Maximum Zoomlevel
                  return false;
            }
            zl <<= 1;			
		}
}

function doRouting (ppmid, longitude, latitude, zipcity,streetnumber, housenumber) {
	$(ppmid).ppmObject.addressMode = 0;
	$(ppmid+'_streetnumber_b').value=streetnumber;
	$(ppmid+'_housenumber_b').value=housenumber;
	$(ppmid+'_zipcity_b').value=zipcity;
	$(ppmid+'_longitude_b').value=longitude;
	$(ppmid+'_latitude_b').value=latitude;

	$($(ppmid).ppmObject.parentNode.id+"_ppm_routing_input").show();
	$(ppmid).ppmObject.markerInfoDialogWindow.open('&Uuml;bernahme erfolgreich', 'Der Eintrag wurde als Ziel f&uuml;r Ihre Routenplanung &uuml;bernommen.');
}