/**
 * Creates a Map Object for naviki.
 * The object is an adapter between the google api and 
 * the naviki architecture.
 */
naviki.main.Map = function(config){	

	// store the div id for this map
	this.obj   = config['cidMap'];
	this.id    = config['cid'];
	this.mapId = this.id+"Map";
	this.maxHeightWithoutMap = config['maxHeightWithoutMap'];
	this.have_fe_user        = config['have_fe_user'];
	this.config              = config;
	this.controls            = true;
	this.mapSearch           = true;
	
	//variables for way overlay
	this.highlightOverlay = null;
	this.highlightKml     = "";
	this.wayOverlay       = new Array();
	this.wayKml           = null;
	this.oldFactor        = 0;
	this.updateWay        = false;
	
	//GoogleMap settings
	this.mapType        = config['mapType'];
	this.lat            = config['lat'];
	this.lon            = config['lon'];
	this.zoom           = config['zoom'];
	this.layer          = config['layer'];
	this.mapTypes       = new Object();
	this.tree           = null;
	this.maps           = config['maps'];
	this.clickLayer     = true;
	this.stopsLayerIcon = "";

	//browser 
	this.browser = config['browser'];
	this.version = config['version'];
	
	if(this.browser=="msie" && this.version=="6"){
		this.isIE6 = 1;
	}else{
		this.isIE6 = 0;
	}
	
	//geolocation
	this.glocClicked = false;
    this.polygon1    = null; 
    this.polygon2	 = null;
    
    // variables for google earth
    this.ge               = null;
    this.lastMapTypeGE    = false;
    this.gefile           = null;
    this.geDraggingMarker = true;
    this.tmpSatellite;
    
    // variables for georeference of Images
    this.imagemarkers = new Array();

    // variables for routing request
    this.routingmarkers = new Array(); 
    
    // control events
	eventMgr.enableControls.subscribe(this.enableControls, this);
	eventMgr.disableControls.subscribe(this.disableControls, this);    
    // map load events
	eventMgr.onWindowResize.subscribe(this.onResize, this);
	eventMgr.onWindowLoad.subscribe(this.onLoad, this);
	eventMgr.onWindowUnLoad.subscribe(this.onUnLoad, this);
	// map action events
	eventMgr.onMapMoveEnd.subscribe(this.onMapMoveEnd, this);
	eventMgr.onMapDrag.subscribe(this.onMapDrag, this);
	eventMgr.onMapZoom.subscribe(this.onMapZoom, this);
	eventMgr.mapPositioning.subscribe(this.mapPositioning, this);
	// google earth events
	eventMgr.disableGeDraggingMarker.subscribe(this.disableGeDraggingMarker, this);	
	eventMgr.enableGeDraggingMarker.subscribe(this.enableGeDraggingMarker, this);
	eventMgr.disableGoogleEarth.subscribe(this.disableGoogleEarth, this);	
	// georeference of Images events
	eventMgr.requestGeolocationImage.subscribe(this.requestGeolocationImage, this); 
	eventMgr.removeGeolocationImage.subscribe(this.removeGeolocationImage, this);
	eventMgr.removeAllGeolocationImage.subscribe(this.removeAllGeolocationImage, this); 
	eventMgr.addGeolocationImage.subscribe(this.addGeolocationImage, this);
	eventMgr.enableDraggableGeolocationImage.subscribe(this.enableDraggableGeolocationImage, this);
	eventMgr.disableDraggableGeolocationImage.subscribe(this.disableDraggableGeolocationImage, this);
	// overlay events
	eventMgr.onMapAddOverlay.subscribe(this.onMapAddOverlay, this);
	eventMgr.onMapRemoveOverlay.subscribe(this.onMapRemoveOverlay, this);
	eventMgr.removeWayInfoMarker.subscribe(this.removeWayInfoMarker, this);
	eventMgr.addWayInfoMarker.subscribe(this.addWayInfoMarker, this);
	eventMgr.removeWayOverlay.subscribe(this.removeWayOverlay, this); 
	eventMgr.removeHighlightOverlay.subscribe(this.removeHighlightOverlay, this); 
	eventMgr.addHighlightOverlay.subscribe(this.addHighlightOverlay, this); 
	eventMgr.addWayOverlay.subscribe(this.addWayOverlay, this);
	eventMgr.updateWayOverlay.subscribe(this.updateWayOverlay, this);
	// routing request events
	eventMgr.addRoutingMarker.subscribe(this.addRoutingMarker, this);
	eventMgr.disableDraggingMarker.subscribe(this.disableDraggingMarker, this);
	eventMgr.enableDraggingMarker.subscribe(this.enableDraggingMarker, this);
	// search events
	eventMgr.displaySearchResult.subscribe(this.displaySearchResult,this);
	// enable/disable search events
	eventMgr.enableMapFunctions.subscribe(this.enableMapFunctions, this);
	eventMgr.disableMapFunctions.subscribe(this.disableMapFunctions, this);		
};

naviki.main.Map.MAX_ZOOM_LEVEL = 19;
naviki.main.Map.MIN_ZOOM_LEVEL = 0;

naviki.main.Map.prototype.mapPositioning = function(type, e, me){
	me.gmap.setCenter(new GLatLng(e[0], e[1]),parseInt(e[2]));
};

naviki.main.Map.prototype.onMapMoveEnd = function(type, e, me){
	// ok, now save the actual position in the session.
	if (me.have_fe_user == 0) {
		return;
	}

	var address = "index.php?eID=tx_naviki_pi_map&actionId=storeMapViewInSession&lat="+me.gmap.getCenter().lat()+"&lng="+me.gmap.getCenter().lng()+"&zoom="+me.gmap.getZoom();
	var oCallback = {
		success : function(o) {
		},
		failure : function(o) {
			alert("Sorry, no data found for that address!\n Here is the response: " + o);
		},
		cache : false
	};	
	var getXML = YAHOO.util.Connect.asyncRequest("GET", address, oCallback); 
		
};

naviki.main.Map.prototype.onMapDrag = function(type, e, me){
	me.updateBrowserURL(e[0]);
};

naviki.main.Map.prototype.onMapZoom = function(type, e, me){
	if(me.wayOverlay.length>0){
		eventMgr.updateWayOverlay.fire();
	}
	me.updateBrowserURL(e[0]);
};

naviki.main.Map.prototype.updateBrowserURL = function(gmap){

	window.location.hash = "lat="   + gmap.getCenter().lat() 
	    				 + "&lon="  + gmap.getCenter().lng()
	    				 + "&zoom=" + gmap.getZoom();
	    				 
};

naviki.main.Map.prototype.onUnLoad = function(type, e, me){
	
	if(typeof me.ge != "undefined"){
		me.ge.getTourPlayer().pause(); 
		me.ge.getTourPlayer().setTour(null);
		me.ge = null;
	}
	if(typeof me.gmap != "undefined"){
		me.gmap = null;
	}	
};


/**
 * resizes the map so that the map uses 
 * the maximum size of the browser window.
 * 
 * The function is an Event-Callback, so that
 * the "this"-Pointer  points to the event source. 
 *  
 * @param type A String, which describes the Event-Name
 * @param e An array with parameters from the event fire position. 
 * 		    (Here: null)
 * @param me naviki.main.Map  A Pointer to the Map Object (normally this). 
 * 
 */    
naviki.main.Map.prototype.onResize = function(type, e, me){
	// if the event is fired by the eventMgr,
	// then this points to the eventMgr.
	// Call again to correct the this pointer.
	if (me != null){
		me.onResize(type, e, null);
		return;
	}

	// update the height from the map
	var e = document.getElementById(this.id);
	var h = -this.maxHeightWithoutMap;
	if (window.innerHeight){
		// request the FireFox Document height
		h += window.innerHeight;
	} else {
		// request the IE Document height
		h += window.document.documentElement.clientHeight;   
	}
	if (h < 430)
		h = 430;
	e.style.height = h + "px";
};

/**
 * Builds a map at the div with the Id me.this.
 * 
 * The function is an Event-Callback, so that
 * the "this"-Pointer  points to the event source. 
 *  
 * @param type A String, which describes the Event-Name
 * @param e An array with parameters from the event fire position. 
 * 		    (Here: null)
 * @param me   A Pointer to the Map Object (normally this). 
 * 
 */
naviki.main.Map.prototype.onLoad = function(type, e, me){
	
	// if the event is fired by the eventMgr,
	// then this points to the eventMgr.
	// Call again to correct the this pointer.
	if (me != null){
		me.onLoad(type, e, null);
		return;
	}
	
	if (this.initialized)
		return;
	this.initialized = true;
	
    // resize
	this.onResize("onWindowResize", [null], this); 

	// define the google map
	this.gmap = new GMap2(document.getElementById(this.id));
	this.gmap.myMap = this;
	
	// set map position
	var uri = window.location.hash;
	if(uri.length!=0){
		var tmp = uri.substr(uri.indexOf("#")+1,uri.length); 

		tmp = tmp.split("&");
		
		if(tmp.length==3){

			if(tmp[0].search(/lat/)>=0 && tmp[1].search(/lon/)>=0 && tmp[2].search(/zoom/)>=0){
				
				this.lat  = parseFloat(tmp[0].substr(tmp[0].indexOf("=")+1,tmp[0].length)); 
				this.lon  = parseFloat(tmp[1].substr(tmp[1].indexOf("=")+1,tmp[1].length));
				this.zoom = parseInt(tmp[2].substr(tmp[2].indexOf("=")+1,tmp[2].length));
			}
		}
	}
	this.gmap.setCenter(new GLatLng(this.lat, this.lon), this.zoom);

	// fire the click event over the event Manager
	if(typeof this.leftClick == "undefined"){
		this.leftClick = GEvent.addListener(this.gmap, "click", function(overlay,LatLon,overlayLatLon){		
			if(overlay==null){
				eventMgr.hideContextMenu.fire();
			}
				
			if(overlay==null && typeof LatLon != 'undefined'){
				if(this.myMap.clickLayer){
					this.myMap.selectedLayer = new Array();
		        	var nodeCount            = this.myMap.tree.getNodeCount();
		    		for(var i=1;i<=nodeCount;i++){
		    			if(this.myMap.tree.getNodeByIndex(i).checked==true){
		    				this.myMap.selectedLayer.push(this.myMap.tree.getNodeByIndex(i));
		    			}
		    		}
		    		
		    		if(this.myMap.selectedLayer.length>0){
		    			this.myMap.layerClickAction(LatLon);
		    		}
				}
			}
		});
	}
	
	// set maptypechanged listener
	if(typeof this.maptypechanged == "undefined"){
		this.maptypechanged=true;
		GEvent.addListener(this.gmap, "maptypechanged", function() {
			if(this.getCurrentMapType().getName(false)=="Earth"){
				var myObj =	this.myMap;
				this.myMap.hideCustomizeGMenuMapOverlayControl();
				this.myMap.hideCustomizeFullScreenControl();
				this.myMap.hideGeolocationControl();
				this.myMap.setTourKml();
				this.myMap.drawing.hideDrawMode();
				
				this.myMap.gmap.getEarthInstance(function(ge){
					myObj.ge = myObj.initEarth(ge);
				});
			}else{
				this.myMap.ge = null;
				this.myMap.showCustomizeGMenuMapOverlayControl();
				this.myMap.showCustomizeFullScreenControl();
				this.myMap.showGeolocationControl();
				this.myMap.drawing.showDrawMode();
			}
		});				
	} 
	
	// set mapmoveend listener
	if(typeof this.mapmoveend == "undefined"){
		this.mapmoveend=true;
		GEvent.addListener(this.gmap, "moveend", function() {
			eventMgr.onMapMoveEnd.fire(this.myMap.gmap);
		});				
	} 
	
	// set drag listener
	if(typeof this.drag == "undefined"){
		this.drag=true;
		GEvent.addListener(this.gmap, "drag", function() {
			eventMgr.onMapDrag.fire(this.myMap.gmap);
		});				
	}
	
	// set zoomend listener
	if(typeof this.zoomend == "undefined"){
		this.zoomend=true;
		GEvent.addListener(this.gmap, "zoomend", function() {
			eventMgr.onMapZoom.fire(this.myMap.gmap);
		});				
	}
	
	// initialize a context menu for routing
	this.contextmenu = new ContextMenu(this);	

	// initialize a context menu for routing
	this.drawing = new drawing(this.gmap,this.id,this.contextmenu);	
	
	this.gmap.enableScrollWheelZoom();
	this.gmap.enableDoubleClickZoom();
	this.gmap.addControl(new GLargeMapControl3D());

	if(naviki.Util.geolocation==1 && typeof navigator.geolocation!='undefined'){
		this.initGeolocation();		
	}
	if(this.config['desc_visible']==1){
		this.generateLandingpageMarker();
	}	
	if(this.config['fullscreenControl']==1){
		this.customizeFullScreenControl();
	}
	if(this.config['overlayControl']==1){
		this.customizeGMenuMapOverlayControl();
	}
	if(this.config['maptypeControl']==1){
		this.customizeGMenuMapTypeControl();
	}		
};

naviki.main.Map.prototype.generateLandingpageMarker = function(){

	var lpLat      = this.config['lpLat'];
	var lpLon      = this.config['lpLon'];
	var lpText     = this.config['lpText'];
	var lpPicture  = this.config['lpPicture'];
	var lpHomepage = this.config['lpHomepage'];

	if(parseFloat(lpLat)>0 && parseFloat(lpLon)>0){
	    var point        = new GLatLng(lpLat, lpLon);
	    var newicon      = new GIcon(G_DEFAULT_ICON);
	    newicon.image    = naviki.Util.FILEADMIN_PATH + "img/pi_map/lp_marker.png";
	    newicon.iconSize = new GSize(29,46);
	    var marker       = new GMarker(point,{draggable: false, icon: newicon});
	
		var text = "<br /><table><tbody><tr><td>";
		if(lpPicture!=""){
			lpPicture = "uploads/tx_naviki_domain_model_geoobject/" + lpPicture;
			text += "<img src='"+lpPicture+"' width='75' height='75' border='0' align='left' style='margin-right:5px;'>";
		}
		text += "<p align='justify'>" + lpText + "</p>";
		text += "</td></tr>";
		text += "<tr><td><br /><a href=" + lpHomepage + ">" + lpHomepage + "</a></td></tr>";
		text += "</tbody></table>";
			
	    GEvent.addListener(marker, "click", function() {
	        marker.openInfoWindowHtml(text);
	    }); 
			
	    eventMgr.onMapAddOverlay.fire(marker);
	}
};

naviki.main.Map.prototype.setControlContainer = function(){
	var container = document.createElement("div");    
	container.id  = this.id + "controlContainer";
	YAHOO.util.Dom.addClass(container, 'controlContainer');
	this.gmap.getContainer().appendChild(container);	
};

naviki.main.Map.prototype.hideCustomizeFullScreenControl = function(){	

	var container;
	
	container = document.getElementById(this.id + "fullscreenContainer");
	YAHOO.util.Dom.setStyle(container, 'display', "none");
	
	container = document.getElementById(this.id + "maptypeButton");
	YAHOO.util.Dom.setStyle(container, 'right', "7px");
	
	container = document.getElementById(this.id + "maptypeIframe");
	YAHOO.util.Dom.setStyle(container, 'right', "7px");	

	container = document.getElementById(this.id + "maptypeItems");
	YAHOO.util.Dom.setStyle(container, 'right', "7px");			
};

naviki.main.Map.prototype.showCustomizeFullScreenControl = function(){

	var container;
	
	container = document.getElementById(this.id + "fullscreenContainer");
	YAHOO.util.Dom.setStyle(container, 'display', "");

	container = document.getElementById(this.id + "maptypeButton");
	YAHOO.util.Dom.setStyle(container, 'right', "33px");
	
	container = document.getElementById(this.id + "maptypeIframe");
	YAHOO.util.Dom.setStyle(container, 'right', "33px");	

	container = document.getElementById(this.id + "maptypeItems");
	YAHOO.util.Dom.setStyle(container, 'right', "33px");	
};

naviki.main.Map.prototype.customizeFullScreenControl = function(){

	var fullscreen = false;
	var myObj      = this;
	var tooltip    = document.createElement("p");
    var container  = document.createElement("div");
	var menuButton = document.createElement("div");
	var iframe     = document.createElement("iframe");
	var map        = myObj.gmap.getContainer();
	
    var cc = document.getElementById(this.id+"controlContainer");
    if(cc==null){
    	this.setControlContainer();
    	cc = document.getElementById(this.id+"controlContainer");
    }	

    tooltip.title = naviki.Lang.getLL('fullscreen_max_title');
	menuButton.id   = this.id + "fullscreenButton";
	container.id    = this.id + "fullscreenContainer";
	iframe.id       = this.id + "fullscreenIframe";

	YAHOO.util.Dom.addClass(menuButton, 'fullscreenButton');
	YAHOO.util.Dom.addClass(container, 'fullscreenContainer');
	YAHOO.util.Dom.addClass(iframe, 'fullscreenIframe');
	YAHOO.util.Dom.setStyle(menuButton, 'right', "7px");
		
	// add container to the map
	tooltip.appendChild(menuButton);
	container.appendChild(tooltip);
	container.appendChild(iframe);
	cc.appendChild(container);	
	
	YAHOO.util.Event.on(menuButton, 'click', function(){
		
		if(myObj.controls == true){
		
			if(fullscreen==false){
				YAHOO.util.Dom.removeClass (menuButton,'fullscreenButton');
				YAHOO.util.Dom.addClass(menuButton, 'redusescreenButton');
				tooltip.title = naviki.Lang.getLL('fullscreen_min_title');
				fullscreen      = true;
				style           = YAHOO.util.Dom.getAttribute(map,"style");
				YAHOO.util.Dom.setAttribute(map,"style","position:fixed;width:100%;height:100%;top:0px;left:0px;background-color:#ffffff;");
				myObj.gmap.checkResize();
				if(document.getElementById(myObj.id + "earthItem") != "undefined"){
					document.getElementById(myObj.id + "earthItem").style.display = "none";
				}
			}else{
				YAHOO.util.Dom.removeClass (menuButton,'redusescreenButton');
				YAHOO.util.Dom.addClass(menuButton, 'fullscreenButton');
				tooltip.title = naviki.Lang.getLL('fullscreen_max_title');
				fullscreen      = false;
				YAHOO.util.Dom.setAttribute(map,"style",style);
				myObj.gmap.checkResize();
				
				if(document.getElementById(myObj.id + "earthItem") != "undefined"){
					document.getElementById(myObj.id + "earthItem").style.display = "";
				}
			}
		}
	});
};

naviki.main.Map.prototype.addMaps = function(id){
	
	var element = document.getElementById(id);
	var items   = "";
	var obj     = null;
	var active  = 0;
	var tmp     = new Array();
	
    var copyright_1 = naviki.Lang.getLL('copyright.0')+" "+naviki.Lang.getLL('copyright.1');;
    var copyright_2 = naviki.Lang.getLL('copyright.0');
	
	for(var i=0;i<this.maps.length;i++){
		switch(parseInt(this.maps[i]['type'])){
			// osm maps
			case 1:
				switch(parseInt(this.maps[i]['osm'])){
					case 2:					
					    var copyOSM     = new GCopyrightCollection(copyright_2 + " <a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a>");
					    copyOSM.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesMapnik = new GTileLayer(copyOSM, 1, 18, {tileUrlTemplate: 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png'});
					    var mapMapnik   = new GMapType([tilesMapnik],     G_NORMAL_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'osm'});
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapMapnik;
					    tmp.push(obj);				
						break;
					case 3:
					    var copyBikeOSM     = new GCopyrightCollection(copyright_2 + " <a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a>");
					    copyBikeOSM.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesBikeMapnik = new GTileLayer(copyBikeOSM, 1, 15, {tileUrlTemplate: 'http://tile.opencyclemap.org/cycle/{Z}/{X}/{Y}.png'});
					    var mapBikeMapnik   = new GMapType([tilesBikeMapnik],     G_NORMAL_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'osm_bike'});
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapBikeMapnik;
					    tmp.push(obj);
						break;						
				}
				break;
			// google maps	
			case 2:
				switch(parseInt(this.maps[i]['google'])){
					case 1:
					    var copyNormal  = new GCopyrightCollection(copyright_1);
					    copyNormal.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesNormal = new GTileLayer(copyNormal, 1, 19);
					    var mapNormal   = new GMapType([tilesNormal,G_NORMAL_MAP.getTileLayers()[0]], G_NORMAL_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'normal'});
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapNormal;
					    tmp.push(obj);
						break;
					case 2:
					    var copyPhysical  = new GCopyrightCollection(copyright_1);
					    copyPhysical.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesPhysical = new GTileLayer(copyPhysical, 1, 15);
					    var mapPhysical   = new GMapType([tilesPhysical,G_PHYSICAL_MAP.getTileLayers()[0]], G_PHYSICAL_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'physical'});
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapPhysical;
					    tmp.push(obj);					
						break;
					case 3:
					    var copyHybrid  = new GCopyrightCollection(copyright_1);
					    copyHybrid.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesHybrid = new GTileLayer(copyHybrid, 1, 18);
					    var mapHybrid   = new GMapType([tilesHybrid,G_HYBRID_MAP.getTileLayers()[0],G_HYBRID_MAP.getTileLayers()[1]],G_HYBRID_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'hybrid'});
					    mapHybrid.getMaximumResolution = function () { return 18 ;}; 
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapHybrid; 
					    tmp.push(obj);						
						break;	
					case 4:
					    var copySatellite  = new GCopyrightCollection(copyright_1);
					    copySatellite.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    var tilesSatellite = new GTileLayer(copySatellite, 1, 18);
					    var mapSatellite   = new GMapType([tilesSatellite,G_SATELLITE_MAP.getTileLayers()[0]],G_SATELLITE_MAP.getProjection(), this.maps[i]['name'],{ urlArg: 'satellite'});
					    obj      = new Object(); 
						obj.uid  = this.maps[i]['uid'];
						obj.name = this.maps[i]['name'];
					    obj.type = mapSatellite; 
					    tmp.push(obj);
						break;
					case 5:
						if(naviki.Util.googleEarth == "1"){
						    obj      = new Object(); 
							obj.uid  = this.maps[i]['uid'];
							obj.name = this.maps[i]['name'];
						    obj.type = G_SATELLITE_3D_MAP;
						    tmp.push(obj);
						    
						    var copySatellite  = new GCopyrightCollection(copyright_1);
						    copySatellite.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
						    var tilesSatellite = new GTileLayer(copySatellite, 1, 18);
						    this.tmpSatellite = new GMapType([tilesSatellite,G_SATELLITE_MAP.getTileLayers()[0]],G_SATELLITE_MAP.getProjection(), this.maps[i]['name'],{urlArg: 'tmpEarth'}); 
						}
						break;
				}
				break;
		}				
		
		if(obj!=null){
			items += "<a href='javascript:"+this.obj+".setMapType("+(tmp.length-1)+");'>"+this.maps[i]['name']+"</a>";
			obj    = null;
			
			if(parseInt(this.mapType)==parseInt(this.maps[i]['uid'])){
				active = tmp.length-1;
			}
		}
	}
	
	if(items!=""){
		element.innerHTML = items;
		this.maps         = tmp;
		this.setMapType(active);
	}
};

naviki.main.Map.prototype.setMapType = function(pos){
	
	var menuText = document.getElementById(this.id + "maptypeText");

	this.gmap.setMapType(this.maps[pos].type);
	menuText.innerHTML = this.maps[pos].name;
	
	this.activeMap = this.maps[pos];
	this.storeMapType(this.maps[pos].uid);
};

naviki.main.Map.prototype.customizeGMenuMapTypeControl = function(){
	
	var myObj      = this;
    var container  = document.createElement("div");
	var menuItems  = document.createElement("div");
	var menuButton = document.createElement("div");
	var menuText   = document.createElement("div"); 
	var iframe     = document.createElement("iframe");

    var cc = document.getElementById(this.id+"controlContainer");
    if(cc==null){
    	this.setControlContainer();
    	cc = document.getElementById(this.id+"controlContainer");
    }	
	
	menuItems.id   = this.id + "maptypeItems";
	menuButton.id  = this.id + "maptypeButton";
	menuText.id    = this.id + "maptypeText";
	container.id   = this.id + "maptypeContainer";
	iframe.id      = this.id + "maptypeIframe";

	YAHOO.util.Dom.addClass(menuItems, 'maptypeItems');
	YAHOO.util.Dom.addClass(menuButton, 'maptypeButton');
	YAHOO.util.Dom.addClass(menuText, 'maptypeText');
	YAHOO.util.Dom.addClass(container, 'maptypeContainer');
	YAHOO.util.Dom.addClass(iframe, 'maptypeIframe');
	YAHOO.util.Dom.setStyle(menuButton, 'right', "33px");
	
	// add container to the map
	menuButton.appendChild(menuText);
	container.appendChild(menuItems);
	container.appendChild(menuButton);
	container.appendChild(iframe);	
	cc.appendChild(container);
	
	// listen for mousemove
	YAHOO.util.Event.on(document, 'mousemove', function(e){
	
		if(myObj.controls == true){
		
			if(document.all){
				posx = window.event.clientX + document.documentElement.scrollLeft;
				posy = window.event.clientY + document.documentElement.scrollTop;
			}else{
				posx = e.pageX;
				posy = e.pageY;
			}
	
			var region1 = YAHOO.util.Dom.getRegion(myObj.id + "maptypeButton");
			if (posx > region1.left && posx < (region1.left + region1.width) && posy > region1.top && posy < (region1.top + region1.height)){
				document.getElementById(myObj.id + "maptypeItems").style.display  = "inline";
				document.getElementById(myObj.id + "maptypeIframe").style.display = "inline";
			}
	
			var region2 = YAHOO.util.Dom.getRegion(myObj.id + "maptypeItems");
			if (posx < region2.left || posx > (region2.left + region2.width) || posy < region1.top || posy > (region1.top + region1.height + region2.height)){
				document.getElementById(myObj.id + "maptypeItems").style.display = "none";
				document.getElementById(myObj.id + "maptypeIframe").style.height = region1.height + "px";
			}else{
				if(typeof region2.height!="undefined"){
					document.getElementById(myObj.id + "maptypeIframe").style.height = (region1.height + region2.height - 1) + "px";
				}
			}
		}
	});
	
	YAHOO.util.Event.on(document, 'mouseup', function(e){
		var region1 = YAHOO.util.Dom.getRegion(myObj.id + "maptypeButton");
		document.getElementById(myObj.id + "maptypeItems").style.display = "none";
		document.getElementById(myObj.id + "maptypeIframe").style.height = region1.height + "px";
	});

	this.addMaps(menuItems.id);
};

naviki.main.Map.prototype.customizeGMenuMapOverlayControl = function(){

	var myObj      = this;
    var container  = document.createElement("div");
	var menuItems  = document.createElement("div");
	var menuButton = document.createElement("div");
	var menuText   = document.createElement("div");

    var cc = document.getElementById(this.id+"controlContainer");
    if(cc==null){
    	this.setControlContainer();
    	cc = document.getElementById(this.id+"controlContainer");
    }	
	
	menuItems.id  = this.id + "overlayItems";
	menuButton.id = this.id + "overlayButton";
	menuText.id   = this.id + "overlayText";
	container.id  = this.id + "overlayContainer";

	YAHOO.util.Dom.addClass(menuItems, 'overlayItems');
	YAHOO.util.Dom.addClass(menuButton, 'overlayButton');
	YAHOO.util.Dom.addClass(menuText, 'overlayText');
	YAHOO.util.Dom.addClass(container, 'overlayContainer');
	YAHOO.util.Dom.setStyle(menuButton, 'right', "134px"); 	
	
	menuText.innerHTML = naviki.Lang.getLL('more');
	menuButton.appendChild(menuText);
	
	// add container to the map
	container.appendChild(menuItems);
	container.appendChild(menuButton);
	cc.appendChild(container);
	
	// listen for mousemove
	YAHOO.util.Event.on(document, 'mousemove', function(e){
		
		if(myObj.controls == true){
		
			if(document.all){
				posx = window.event.clientX + document.documentElement.scrollLeft;
				posy = window.event.clientY + document.documentElement.scrollTop;
			}else{
				posx = e.pageX;
				posy = e.pageY;
			}
	
			var region1 = YAHOO.util.Dom.getRegion(myObj.id + "overlayButton");
			if (posx > region1.left && posx < (region1.left + region1.width) && posy > region1.top && posy < (region1.top + region1.height)){
				document.getElementById(myObj.id + "overlayItems").style.display  = "inline";
			}
	
			var region2 = YAHOO.util.Dom.getRegion(myObj.id + "overlayItems");
			if ((posx < region2.left || posx > (region2.left + region2.width) || posy < region2.top || posy > (region2.top + region2.height))&&(posx < region1.left || posx > (region1.left + region1.width) || posy < region1.top || posy > (region1.top + region1.height))){
				document.getElementById(myObj.id + "overlayItems").style.display  = "none";
			}
		}
	});	

	this.gmap.myObj = this;
	this.tree = new YAHOO.widget.TreeView(this.id + "overlayItems");
	this.buildTree(this.tree.getRoot(),0);
	this.tree.draw();

	if(this.layer.length<=0){
		menuButton.style.visibility = "hidden";
	}
};

naviki.main.Map.prototype.buildTree = function(root,idx){

	var xmlObj;
	var node;
	var label;
	var copy;
	var tileLayer;
	var myLayer;
	var overlay;
	
	for(var i=0;i<this.layer.length;i++){
		
		if(parseInt(this.layer[i]["treenode"])==idx){
		
			switch(parseInt(this.layer[i]["type"])){
				case 0:
					label  = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"]};
					node   = new naviki.main.MapTaskNode(label, root, false);
					this.buildTree(node,this.layer[i]["uid"]);
					break;	
				case 1:
					if(this.isIE6==0 && this.layer[i]["tileUrl"]!=""){
					    copy = new GCopyrightCollection(this.layer[i]["tileCopyright"]);
					    copy.addCopyright(new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, " "));
					    tileLayer = new GTileLayer(copy, 1, 17, {tileUrlTemplate: this.layer[i]["tileUrl"]+"{Z}/{X}/{Y}.png"});
					    myLayer   = new GTileLayerOverlay(tileLayer);
					    overlay   = new Array(myLayer);
					    label     = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"]};
						node      = new naviki.main.MapTaskNode(label, root, false, false, overlay, this.gmap);
					}					
					break;
				case 2:
					if(this.layer[i]["googleLayerId"]!=""){
						label   = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"]};
						overlay = new Array(new GLayer(this.layer[i]["googleLayerId"]));
						node    = new naviki.main.MapTaskNode(label,root, false, false, overlay,this.gmap);
					}	
					break;
				case 3:
					xmlObj  = new GGeoXml("" + naviki.Util.DOMAIN_URL + "uploads/tx_naviki_domain_model_layer/" + this.layer[i]["kmlFile"]);
					overlay = new Array(xmlObj);	
					label   = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"]};
					node    = new naviki.main.MapTaskNode(label , root, false, false, overlay, this.gmap);
					break;		
				case 4:
/*					
					xmlObj  = new GGeoXml("" + naviki.Util.DOMAIN_URL + "uploads/tx_naviki_layer/" + this.layer[i]["kml"]);
					overlay = new Array(xmlObj);
					label   = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"],haveWays:this.layer[i]["haveWays"]};
					node    = new naviki.main.MapTaskNode(label , root, false, false, overlay, this.gmap);
					break;
*/					
				case 6:
					var myObj = this;
					var haltestellen = new GTileLayer(new GCopyrightCollection(""), 1,17);
					haltestellen.getTileUrl = function(a,b,c){
						var lULP  = new GPoint(a.x * 256, (a.y + 1) * 256);
						var lLRP  = new GPoint((a.x + 1) * 256, a.y * 256);
						var lUL   = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lULP, b, c);
						var lLR   = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lLRP, b, c);
						var lBbox = lUL.x + "," + lUL.y + "," + lLR.x + "," + lLR.y;
						
						var lURL = "http://maps2.connect-info.net/mapserv";
						lURL += "?MAP=/data/umn/hannit/mapfiles/haltestellen_remoteJson.map";
						lURL += "&LAYERS=haltestellenpunkte";
						lURL += "&TRANSPARENT=TRUE";
						lURL += "&FORMAT=png";
						lURL += "&SERVICE=WMS";
						lURL += "&VERSION=1.1.1";
						lURL += "&REQUEST=GetMap";
						lURL += "&STYLES=";
						lURL += "&EXCEPTIONS=application/Fvnd.ogc.se_inimage";
						lURL += "&SRS=EPSG:4326";
						lURL += "&BBOX=" + lBbox;
						lURL += "&WIDTH=256";
						lURL += "&HEIGHT=256";
						
						return lURL;
					};
					haltestellen.getOpacity = function() {
						return 1.0;
					};
					
					// icon in the bubble
					this.stopsLayerIcon = this.layer[i]["wmsStopsIcon"];

					// add wms layer with GTileLayerOverlay
					var WMSLayer = new GTileLayerOverlay(haltestellen);
				
					overlay = new Array(WMSLayer);	
					label   = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"]};
					node    = new naviki.main.MapTaskNode(label , root, false, false, overlay, this.gmap);
					break;
				case 7:
					overlay = new Array();
					for(var j=0;j<this.layer[i]["weather"].length;j++){
						if(this.layer[i]["weather"][j]['state']=="OK"){
						    var point        = new GLatLng(this.layer[i]["weather"][j]['lat'], this.layer[i]["weather"][j]['lon']);
						    var newicon      = new GIcon(G_DEFAULT_ICON);
						    newicon.image    = this.layer[i]["weather"][j]['image']['url'];
						    newicon.iconSize = new GSize(52,52);
						    var marker       = new GMarker(point,{draggable: false, icon: newicon});
						    overlay.push(marker);
						}
					}
					label   = {label:this.layer[i]["name"],mylabel:this.layer[i]["uid"],myType:this.layer[i]["type"],haveWays:this.layer[i]["haveWays"]};
					node    = new naviki.main.MapTaskNode(label , root, false, false, overlay, this.gmap);
					break;	
			}
			
			if(parseInt(this.layer[i]["active"])==1 && parseInt(this.layer[i]["type"])!=0){
				if(parseInt(this.layer[i]["type"])==2){
					if(this.isIE6==0){
						node.setUpCheck(true);
					}
				}else{
					node.setUpCheck(true);
				}
			}
		}
	}
};

naviki.main.Map.prototype.showCustomizeGMenuMapOverlayControl = function(){
	
	var nodeCount = this.tree.getNodeCount();
	var overlay;
	for(var i=1;i<=nodeCount;i++){
		if(this.tree.getNodeByIndex(i).checked==true){
			overlay = this.tree.getNodeByIndex(i).overlay;
			if(overlay){
				eventMgr.onMapAddOverlay.fire(overlay);
			}
		}
	}	
	
	if(this.layer.length>0){
		var overlayButton = document.getElementById(this.id + "overlayButton");
		overlayButton.style.visibility = "visible";
	}
};

naviki.main.Map.prototype.hideCustomizeGMenuMapOverlayControl = function(){
	
	var nodeCount = this.tree.getNodeCount();
	var overlay;
	for(var i=1;i<=nodeCount;i++){
		if(this.tree.getNodeByIndex(i).checked==true){
			overlay = this.tree.getNodeByIndex(i).overlay;
			if(overlay){
				eventMgr.onMapRemoveOverlay.fire(overlay);
			}
		}
	}
	
	if(this.layer.length>0){
		var overlayButton = document.getElementById(this.id + "overlayButton");
		overlayButton.style.visibility = "hidden";
	}	
};

/*############################################################################
 *######################## geolocation function ##############################
 *############################################################################
 */
naviki.main.Map.prototype.hideGeolocationControl = function(){
	var element = document.getElementById(this.id+"geolocationContainer");
	if(element!=null){
		element.style.display = "none";
	}
};

naviki.main.Map.prototype.showGeolocationControl = function(){
	var element = document.getElementById(this.id+"geolocationContainer");
	if(element!=null){
		element.style.display = "";
	}
};

naviki.main.Map.prototype.initGeolocation = function(){

	var myObj      = this;
	var tooltip    = document.createElement("p");
    var container  = document.createElement("div");
	var menuItems  = document.createElement("div");

    var cc = document.getElementById(this.id+"controlContainer");
    if(cc==null){
    	this.setControlContainer();
    	cc = document.getElementById(this.id+"controlContainer");
    }	
	
    tooltip.title = naviki.Lang.getLL('geolocation_title');
	menuItems.id  = this.id + "geolocationItem";
	container.id  = this.id + "geolocationContainer";

	YAHOO.util.Dom.addClass(menuItems, 'geolocationItem-no');
	YAHOO.util.Dom.addClass(container, 'geolocationContainer');
	YAHOO.util.Dom.setStyle(menuItems, 'right', "236px"); 
	
	// add container to the map
	tooltip.appendChild(menuItems);
	container.appendChild(tooltip);
	cc.appendChild(container);
		
	YAHOO.util.Event.on(menuItems, 'click', function(e){
		var location,lat,lon;
		if(YAHOO.util.Dom.getAttribute(menuItems,'class')=="geolocationItem-no"){
			YAHOO.util.Dom.replaceClass(menuItems, 'geolocationItem-no', 'geolocationItem-wait');
			location = navigator.geolocation;
			location.getCurrentPosition(
				function(position){
					lat = position.coords.latitude;
					lon = position.coords.longitude;
					YAHOO.util.Dom.replaceClass(menuItems, 'geolocationItem-wait', 'geolocationItem-act');
					myObj.drawPosition(lat,lon);
				}, 
				function(positionError){
					YAHOO.util.Dom.replaceClass(menuItems, 'geolocationItem-wait', 'geolocationItem-no');							
				},
				{
					timeout:30000,
					maximumAge:600000,
					enableHighAccuracy:false
				}
			);	
		}else if(YAHOO.util.Dom.getAttribute(menuItems,'class')=="geolocationItem-act"){
			YAHOO.util.Dom.replaceClass(menuItems, 'geolocationItem-act', 'geolocationItem-no');
			myObj.clearPosition();
		}
	});
};

naviki.main.Map.prototype.clearPosition = function() {
	if(typeof this.geolocationCircle!='undefined'){
		this.gmap.removeOverlay(this.geolocationCircle);
	}
	if(typeof this.geolocationMarker!='undefined'){
		this.gmap.removeOverlay(this.geolocationMarker);
		GEvent.removeListener(this.geolocationMarkerEvent);
	}	
};

naviki.main.Map.prototype.drawPosition = function(lat,lon) {
	var myObj = this;
	var zoom  = this.gmap.getCurrentMapType().getMaximumResolution();
	if(zoom>15){
		zoom = 15;
	}
	this.gmap.setCenter(new GLatLng(lat, lon), zoom);
//    this.geolocationCircle = this.drawCircle(100,"#000080",1, 0.2,"#0000FF",0.1);
    this.geolocationMarker      = new GMarker(this.gmap.getCenter(),{draggable: false, icon: new GIcon(G_DEFAULT_ICON)});    
    this.geolocationMarkerEvent = GEvent.addListener(this.geolocationMarker, 'click', function() {
    	
    	var link = "";
    	var lat  = this.getLatLng().lat();
    	var lon  = this.getLatLng().lng();
    	var x    = myObj.gmap.fromLatLngToContainerPixel(this.getLatLng()).x;
    	var y    = myObj.gmap.fromLatLngToContainerPixel(this.getLatLng()).y;
    	
    	for (var key in myObj.contextmenu.links){
			link += myObj.contextmenu.links[key];
		}
		
		if(link.length!=0){
	    	link = link.replace(/###LAT###/g,  lat);
	    	link = link.replace(/###LNG###/g,  lon);
	    	link = link.replace(/###ZOOM###/g, myObj.gmap.getZoom());
		
			myObj.contextmenu.coor['lat'] = lat;
			myObj.contextmenu.coor['lng'] = lon;                       
	        myObj.contextmenu.contextMenuShow(x,y,link);
		}
    });
  
    
//    this.gmap.addOverlay(this.geolocationCircle);
    this.gmap.addOverlay(this.geolocationMarker);	
};

naviki.main.Map.prototype.drawCircle = function(radius, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity){
	
    var gPoint = this.gmap.fromLatLngToContainerPixel(this.gmap.getCenter());
    var lat    = gPoint.y;
    var lng    = gPoint.x;	
	
	var d2r     = Math.PI/180;
    var r2d     = 180/Math.PI;
    var Clat    = radius; 
    var Clng    = Clat/Math.cos(lat*d2r); 
    var Cpoints = [];
    
    for (var i=0; i < 33; i++) { 
    	var theta = Math.PI * (i/16);
        Cy = lat + (Clat * Math.sin(theta));
        Cx = lng + (Clng * Math.cos(theta));
        var P = this.gmap.fromContainerPixelToLatLng(new GPoint(Cx,Cy));
        Cpoints.push(P);
    }

    var polygon = new GPolygon(Cpoints, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity);

    return polygon;
};

/*############################################################################
 *###### enable/disable customize map controls and earth mouse controls ######
 *############################################################################
 */

naviki.main.Map.prototype.enableControls = function(type,e,me){
	
	if(me.ge!=null && me.lastMapTypeGE == true){

		me.lastMapTypeGE = false;		

		if(me.browser=="msie"){
			me.gmap.setMapType(G_SATELLITE_3D_MAP);
		}else{
			me.ge.getNavigationControl().setVisibility(me.ge.VISIBILITY_SHOW);
			me.ge.getOptions().setMouseNavigationEnabled(true);			
		}
	}
	
	me.controls = true;
};

naviki.main.Map.prototype.disableControls = function(type,e,me){

	if(me.ge!=null && me.gmap.getCurrentMapType().getName(false)=="Earth"){

		me.lastMapTypeGE = true;		
		
		if(me.browser=="msie"){
			me.gmap.setMapType(me.tmpSatellite);
		}else{
			me.ge.getNavigationControl().setVisibility(me.ge.VISIBILITY_HIDE);
			me.ge.getOptions().setMouseNavigationEnabled(false);
			me.ge.getTourPlayer().pause();
		}
	}
	
	me.controls = false;
};

/*############################################################################
 *############## ways next to point, search Event functions ##################
 *############################################################################
 */

naviki.main.Map.prototype.displaySearchResult = function(type, e, me){
	
	if ((typeof me.gmap.lastSearchResult ) != 'undefined'){
		me.gmap.removeOverlay(me.gmap.lastSearchResult);
	}
	
	
	var coorstring = e[0].getData("coordinates");
	var coors = coorstring.split(",",2);
	
    var point = new GLatLng(coors[0],coors[1]);
    me.gmap.panTo(point);
    me.gmap.setCenter(point,13);
    
    var tinyIcon = new GIcon();
	tinyIcon.image = naviki.Util.FILEADMIN_PATH + "img/pi_map/naviki_marker_transparent.png";
	tinyIcon.iconSize = new GSize(39, 39);
	tinyIcon.iconAnchor = new GPoint(0, 0);
	tinyIcon.infoWindowAnchor = new GPoint(1, 1);
	
	// Set up our GMarkerOptions object literal
	markerOptions = { icon:tinyIcon };
	
	var marker = new GMarker(point,markerOptions);
    me.gmap.addOverlay(marker);
	marker.openInfoWindowHtml("<b>"+e[0].getData("name")+"</b>");
	me.gmap.lastSearchResult = marker;
};

naviki.main.Map.prototype.createBounds = function(lat,lon){
	
    var point   = new GLatLng(lat,lon);
	var deltaX  = 20;
	var deltaY  = 20;
	
	this.center     = new Object();
	this.center.lat = lat;
	this.center.lon = lon;
	
    this.pointXY = this.gmap.fromLatLngToContainerPixel(point);
	this.polygon = new GPolygon(
		[
			this.gmap.fromContainerPixelToLatLng(new GPoint(this.pointXY.x - deltaX, this.pointXY.y - deltaY)),
			this.gmap.fromContainerPixelToLatLng(new GPoint(this.pointXY.x + deltaX, this.pointXY.y - deltaY)),
			this.gmap.fromContainerPixelToLatLng(new GPoint(this.pointXY.x + deltaX, this.pointXY.y + deltaY)),
			this.gmap.fromContainerPixelToLatLng(new GPoint(this.pointXY.x - deltaX, this.pointXY.y + deltaY)),
			this.gmap.fromContainerPixelToLatLng(new GPoint(this.pointXY.x - deltaX, this.pointXY.y - deltaY))
		 ],
		 "#f33f00",
		 5,
		 1,
		 "#ff0000",
		 0.2
	);

	document.myObj = this;
	YAHOO.util.Event.on(document, 'mousemove', this.handlerMousemove);
	YAHOO.util.Event.on(document, 'click', this.handlerClick);
	
	eventMgr.hideContextMenu.fire();
	this.gmap.addOverlay(this.polygon);
};

naviki.main.Map.prototype.handlerClick = function(e){

	var bounds = this.myObj.polygon.getBounds();
	var zoom   = this.myObj.gmap.getBoundsZoomLevel(bounds);
    var lat    = this.myObj.center.lat;
	var lng    = this.myObj.center.lon;   
	var bbox   = ""; 
	
	for(var i=0;i<this.myObj.polygon.getVertexCount();i++){
		if(i!=0){
			bbox += ",";
		}
		bbox += this.myObj.polygon.getVertex(i).lng() + " " + this.myObj.polygon.getVertex(i).lat();
	}
	
	this.myObj.gmap.removeOverlay(this.myObj.polygon);
	YAHOO.util.Event.removeListener (document , "click" , this.myObj.handlerClick); 
	YAHOO.util.Event.removeListener (document , "mousemove" , this.myObj.handlerMousemove );
	
	if(this.myObj.config['waySearchresultsTargetSite']!="" && typeof this.myObj.config['waySearchresultsTargetSite']!='undefined'){
		var url = this.myObj.config['waySearchresultsTargetSite'] + "?zoom="+zoom+"&lat="+lat+"&lng="+lng+"&bbox="+bbox;
		var url = "http://" + window.location.hostname + "/" + url;
		window.location.href = url;
	}
};

naviki.main.Map.prototype.handlerMousemove = function(e){

	var deltaX;
	var deltaY;
	var region  = YAHOO.util.Dom.getRegion(this.myObj.id);
	
	if(document.all){
		posx = window.event.clientX + document.documentElement.scrollLeft;
		posy = window.event.clientY + document.documentElement.scrollTop;
	}else{
		posx = e.pageX;
		posy = e.pageY;
	}
	
	if((posx - region.left)>this.myObj.pointXY.x){
		deltaX  = (posx - region.left) - this.myObj.pointXY.x;
	}else{
		deltaX  = this.myObj.pointXY.x - (posx - region.left);
	}
	
	if((posy - region.top)>this.myObj.pointXY.y){
		deltaY = (posy - region.top) - this.myObj.pointXY.y;
	}else{
		deltaY = this.myObj.pointXY.y - (posy - region.top);
	}
	
	if (posx > region.left && posx < (region.left + region.width) && posy > region.top && posy < (region.top + region.height)){
		this.myObj.gmap.removeOverlay(this.myObj.polygon);
		this.myObj.polygon = new GPolygon(
			[
			 	this.myObj.gmap.fromContainerPixelToLatLng(new GPoint(this.myObj.pointXY.x - deltaX, this.myObj.pointXY.y - deltaY)),
			 	this.myObj.gmap.fromContainerPixelToLatLng(new GPoint(this.myObj.pointXY.x + deltaX, this.myObj.pointXY.y - deltaY)),
			 	this.myObj.gmap.fromContainerPixelToLatLng(new GPoint(this.myObj.pointXY.x + deltaX, this.myObj.pointXY.y + deltaY)),
			 	this.myObj.gmap.fromContainerPixelToLatLng(new GPoint(this.myObj.pointXY.x - deltaX, this.myObj.pointXY.y + deltaY)),
			 	this.myObj.gmap.fromContainerPixelToLatLng(new GPoint(this.myObj.pointXY.x - deltaX, this.myObj.pointXY.y - deltaY))
			 ],
			 "#f33f00",
			 5,
			 1,
			 "#ff0000",
			 0.2
		);
		this.myObj.gmap.addOverlay(this.myObj.polygon);	
	}
};

/*############################################################################
 *######################### eid functions ####################################
 *############################################################################
 */
naviki.main.Map.prototype.storeMapType = function (type){

	if (this.have_fe_user == 0) {
		return;
	}
	
	var address = "index.php?eID=tx_naviki_pi_map&actionId=storeMapType&mapType="+type;
	var oCallback = {
		success : function(o) {
		},
		failure : function(o) {
			alert("Sorry, no data found for that address!\n Here is the response: " + o);
		},
		cache : false
	};	
	var getXML = YAHOO.util.Connect.asyncRequest("GET", address, oCallback); 	
};

/*############################################################################
 *####################### google earth functions #############################
 *############################################################################
 */
naviki.main.Map.prototype.initEarth = function(ge){
	
	if(ge!=null){		
			
		var myObj = this;
		var link  = "";
		
		ge.getWindow().setVisibility(false);
		ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
		
		// Show Terrain
		var layerRoot    = ge.getLayerRoot();
		var terrainLayer = layerRoot.getLayerById(ge.LAYER_TERRAIN);
		terrainLayer.setVisibility(true);
		
		// set Listener
		if(typeof this.ge_mousedown == "undefined"){
			this.ge_mousedown=true;
			google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event) {
				if(event.getButton()==0){
					if (event.getTarget().getType() == 'KmlPlacemark' &&  event.getTarget().getGeometry().getType() == 'KmlPoint' && myObj.geDraggingMarker == true) {
						var icon = event.getTarget().getComputedStyle().getIconStyle().getIcon().getHref();
						if(icon.search(/www.geocodezip.com\/mapIcons\/marker.+/)>=0){
							var placemark = event.getTarget();
						    dragInfo = {
						    	      placemark: event.getTarget(),
						    	      dragged  : false,
						    	      href     : icon
						    };
						}
						if(icon.search(/naviki_imagemarker.+/)>=0){
							var placemark = event.getTarget();
						    dragInfo = {
						    	      placemark: event.getTarget(),
						    	      dragged  : false,
						    	      href     : icon
						    };							
						}
					}
				}
			});
		}
	
		if(typeof this.ge_dblclick == "undefined"){
			this.ge_dblclick=true;	
			google.earth.addEventListener(ge.getWindow(), 'dblclick', function(event) {
				if (event.getTarget().getType() == 'KmlPlacemark' &&  event.getTarget().getGeometry().getType() == 'KmlPoint') {
					var icon = event.getTarget().getComputedStyle().getIconStyle().getIcon().getHref();
					if(icon.search(/naviki_imagemarker.+/)>=0){
						for(var i=0;i<myObj.imagemarkers.length;i++){
							if(myObj.imagemarkers[i].getIcon().image==icon){
								var marker = myObj.imagemarkers[i];
								window.open(marker.href.link,"Image","width="+marker.href.width+",height="+marker.href.height);		;
								break;
							}
						}
					}
				}
			});
		}		
		
		if(typeof this.ge_mousemove == "undefined"){
			this.ge_mousemove=true;	
			google.earth.addEventListener(ge.getGlobe(), 'mousemove', function(event) {
			 	if (dragInfo) {
			    	event.preventDefault();
			    	var point = dragInfo.placemark.getGeometry();
			    	point.setLatitude(event.getLatitude());
			    	point.setLongitude(event.getLongitude());
			    	dragInfo.dragged = true;
			  	}
			});
		}
	
		if(typeof this.ge_mouseup == "undefined"){
			this.ge_mouseup=true;	
			google.earth.addEventListener(ge.getWindow(), 'mouseup', function(event) {
				if (dragInfo) {
					var icon = dragInfo.href;
					var index;
					if(icon.search(/www.geocodezip.com\/mapIcons\/marker.+/)>=0){
						var pos  = icon.search(/marker.+/);
						index    = icon.substring(pos+6);
						pos      = index.search(/..+/);
						index    = index.substring(0,pos+1);
						index    = parseInt(index)-1;
						dragInfo = null;
						eventMgr.moveRoutingMarker.fire(index,event.getLongitude(),event.getLatitude());
					}
					if(icon.search(/naviki_imagemarker.+/)>=0){
						for(var i=0;i<myObj.imagemarkers.length;i++){
							if(myObj.imagemarkers[i].getIcon().image==dragInfo.href){
								eventMgr.responseGeolocationImage.fire(event.getLatitude(), event.getLongitude(), myObj.imagemarkers[i].title);
								dragInfo = null;
								break;
							}		
						}
					}					
		  		}
			});
		}
		
		if(typeof this.geWindow_mousemove == "undefined"){
			this.geWindow_mousemove=true;	
			google.earth.addEventListener(ge.getWindow(), 'mousemove', function(event) {

				posx = event.getClientX();
			 	posy = event.getClientY();
			 	
				region1 = YAHOO.util.Dom.getRegion(myObj.id + "maptypeButton");
				region2 = YAHOO.util.Dom.getRegion(myObj.id + "maptypeItems");
				if (posx < region2.left || posx > (region2.left + region2.width) || posy < region1.top || posy > (region1.top + region1.height + region2.height)){
					document.getElementById(myObj.id + "maptypeItems").style.display = "none";
					document.getElementById(myObj.id + "maptypeIframe").style.height = region1.height + "px";
				}
			});
		}		
	
		if(typeof this.viewChange == "undefined"){
			this.viewChange=true;	
			google.earth.addEventListener(ge.getView(), 'viewchangeend', function(event){
				var box = ge.getView().getViewportGlobeBounds();
			});
		}			
		
		if(typeof this.ge_rightclick == "undefined"){
			this.ge_rightclick=true;
			google.earth.addEventListener(ge.getGlobe(), 'mousedown', function(event) {
				if(event.getButton()==2){
					
					var coor = new GLatLng(event.getLatitude(),event.getLongitude());
					var x    = event.getClientX();
					var y    = event.getClientY();
					var link = "";					
					
					if (event.getTarget().getType() == 'KmlPlacemark' &&  event.getTarget().getGeometry().getType() == 'KmlPoint' && myObj.geDraggingMarker == true) {					
						var icon = event.getTarget().getComputedStyle().getIconStyle().getIcon().getHref();
						if(icon.search(/naviki_imagemarker.+/)>=0){
							for(var i=0;i<myObj.imagemarkers.length;i++){
								if(myObj.imagemarkers[i].getIcon().image==icon){
			    					link = "<a href='javascript:"+myObj.obj+".removeGeolocationImageByLink(\""+myObj.imagemarkers[i].title+"\");'><div>&nbsp;"+ naviki.Lang.getLL('delete') + "&nbsp;</div></a>";
			    					 myObj.contextmenu.contextMenuShow(x,y,link);
									break;
								}
							}
						}
					}
					else{
			        	for (var key in myObj.contextmenu.links){
			        		link += myObj.contextmenu.links[key];
			        	}
			        	
			        	if(parseInt(myObj.config['waysNextToPoint'])==1){
			        		link += "<a href='javascript:"+myObj.obj+".createBounds(###LAT###,###LNG###);'><div>&nbsp;"+ naviki.Lang.getLL('ways_nextto_point') + "&nbsp;</div></a>";
			        	}
			        	
			        	if(link.length!=0){
				        	link = link.replace(/###LAT###/g,  coor.lat());
				        	link = link.replace(/###LNG###/g,  coor.lng());
				        	link = link.replace(/###ZOOM###/g, myObj.gmap.getZoom());
			        	
							myObj.contextmenu.coor['lat'] = coor.lat();
							myObj.contextmenu.coor['lng'] = coor.lng();                       
					        myObj.contextmenu.contextMenuShow(x,y,link);
			        	}
					}
				}
				else{
					// hide contextmenu
					eventMgr.hideContextMenu.fire();
				}
			});
		}
		
		ge.getWindow().setVisibility(true);
	}
	
	return ge;
};

naviki.main.Map.prototype.setTourKml = function(){
	
	if(this.gmap.getCurrentMapType().getName(false)=="Earth" && this.gefile!=null){
		window.clearInterval(this.interval);
		this.interval = window.setInterval(this.obj+".loadTourKml()", 50);
	}
};

naviki.main.Map.prototype.loadTourKml = function(){

	if(this.ge!=null){
		if(this.ge.getWindow().getVisibility()==true){
	
			window.clearInterval(this.interval);
			var myObj = this;
	
			myObj.ge.getTourPlayer().setTour(null);
			google.earth.fetchKml (myObj.ge, myObj.gefile, function (kmlObject){
				if(!kmlObject){
					return;
				}
				myObj.ge.getFeatures().appendChild(kmlObject);
				walkKmlDom(kmlObject, function(){
					if (this.getType () == 'KmlTour'){
						tour = this;
						myObj.ge.getTourPlayer().setTour(tour);
						return false;
					}
				});
			});
		}
	}
};

naviki.main.Map.prototype.disableGeDraggingMarker = function(type,e,me){
	me.geDraggingMarker = false;
};

naviki.main.Map.prototype.enableGeDraggingMarker = function(type,e,me){
	me.geDraggingMarker = true;
};

naviki.main.Map.prototype.disableGoogleEarth = function(type,e,me){
	
	var earth;
	var mapTypes    = me.gmap.getMapTypes();
	var currentType = me.gmap.getCurrentMapType().getName(false);

	for(var i=0;i<mapTypes.length;i++){
		if(mapTypes[i].getName(false)=="Earth"){
			earth = mapTypes[i];
			break;
		}
	}
	
	if(currentType=="Earth"){
		earth = me.gmap.getCurrentMapType();
		me.gmap.setMapType(mapTypes[0]);
		me.gmap.removeMapType(earth);
	}else{
		if(typeof earth != "undefined"){
			me.gmap.removeMapType(earth);
		}
	}
	
	me.gmap.addControl(new GMenuMapTypeControl());
};

/*############################################################################
 *######################## georeference of Images ############################
 *############################################################################
 */
naviki.main.Map.prototype.requestGeolocationImage = function(type,e,me){
	
	var region    = YAHOO.util.Dom.getRegion(me.id);
	var pos       = -1;
	var available = false;

	if(parseInt(e[0])> region.x && parseInt(e[0]) < (region.x + region.width) && parseInt(e[1]) > region.y && parseInt(e[1]) < (region.y + region.height)){

		var x     = parseInt(e[0]) - region.x;
		var y     = parseInt(e[1]) - region.y;
	    var point = me.gmap.fromContainerPixelToLatLng(new GPoint(x,y));
		
		for(var i=0;i<me.imagemarkers.length;i++){
			if(me.imagemarkers[i].title==e[3]){
				me.imagemarkers[i].setLatLng(point);
				available = true;
				break;
			}
		}
		
		if(available==false){

		    var newicon      = new GIcon(G_DEFAULT_ICON);
		    newicon.image    = ""+naviki.Util.DOMAIN_URL+e[2];
		    newicon.iconSize = new GSize(40,40);
		    newicon.imageMap = [0,0 , 40,0, 40,40 , 0,40];
			
			var marker   = new GMarker(point,{draggable: true, icon: newicon, title: "DoubleClick to enlarge"});
			marker.title = e[3];
			marker.href  = e[4];			
			
			GEvent.addListener(marker, "dragend", function() {
				eventMgr.responseGeolocationImage.fire(marker.getLatLng().lat(), marker.getLatLng().lng(), marker.title);
			});
			
			GEvent.addListener(marker, "dragstart", function() {
				eventMgr.hideContextMenu.fire();
			});
			
			GEvent.addListener(marker, "dblclick", function(){
				window.open(marker.href.link,"Image","width="+marker.href.width+",height="+marker.href.height);		
			});
			
			me.imagemarkers.push(marker);
			eventMgr.onMapAddOverlay.fire(marker);
		}
		
		eventMgr.responseGeolocationImage.fire(point.lat(), point.lng(),e[3]);
	}
};

naviki.main.Map.prototype.removeAllGeolocationImage = function(type,e,me){
	
	for(var i=0;i<me.imagemarkers.length;i++){
		eventMgr.onMapRemoveOverlay.fire(me.imagemarkers[i]);
	}
	me.imagemarkers = new Array();
};

naviki.main.Map.prototype.removeGeolocationImage = function(type,e,me){
	
	for(var i=0;i<me.imagemarkers.length;i++){
		if(me.imagemarkers[i].title==e[0]){
			eventMgr.onMapRemoveOverlay.fire(me.imagemarkers[i]);
			me.imagemarkers.splice(i,1);
			break;
		}
	}	
};

naviki.main.Map.prototype.removeGeolocationImageByLink = function(overlayTitle){
	eventMgr.responseGeolocationImage.fire("", "", overlayTitle);
	eventMgr.removeGeolocationImage.fire(overlayTitle);
	eventMgr.hideContextMenu.fire();
};

naviki.main.Map.prototype.addGeolocationImage = function(type, e, me) {
	
    var point        = new GLatLng(parseFloat(e[0]),parseFloat(e[1]));
    var newicon      = new GIcon(G_DEFAULT_ICON);
    newicon.image    = ""+naviki.Util.DOMAIN_URL+e[2];
    newicon.iconSize = new GSize(40,40);
    newicon.imageMap = [0,0 , 40,0, 40,40 , 0,40];
	
	var marker   = new GMarker(point,{draggable: true, icon: newicon, title: "DoubleClick to enlarge"});	
	marker.title = e[3];
	marker.href  = e[4];
	
	GEvent.addListener(marker, "dragend", function() {
		eventMgr.responseGeolocationImage.fire(marker.getLatLng().lat(), marker.getLatLng().lng(), marker.title);
	});
	
	GEvent.addListener(marker, "dragstart", function() {
		eventMgr.hideContextMenu.fire();
	});	
	
	GEvent.addListener(marker, "dblclick", function() {
		window.open(marker.href.link,"Image","width="+marker.href.width+",height="+marker.href.height);		
	});	
	
	marker.disableDragging();
	me.imagemarkers.push(marker);
	me.gmap.addOverlay(marker);
};

naviki.main.Map.prototype.enableDraggableGeolocationImage = function(type, e, me){
	
	var marker;
	
	for(var i=0;i<me.imagemarkers.length;i++){
		
		var marker = me.imagemarkers[i];
		marker.enableDragging();
	}
	
	eventMgr.enableGeDraggingMarker.fire();
};

naviki.main.Map.prototype.disableDraggableGeolocationImage = function(type, e, me){	
	eventMgr.disableGeDraggingMarker.fire();
};


/*############################################################################
 *#################### add/remove overlays in map ############################
 *############################################################################
*/
naviki.main.Map.prototype.addWayInfoMarker = function(type, e, me) {
	me.wayinfoMarker = new GMarker(new GLatLng(e[0], e[1]));
	eventMgr.onMapAddOverlay.fire(me.wayinfoMarker);
};

naviki.main.Map.prototype.removeWayInfoMarker = function(type, e, me) {
	if(typeof me.wayinfoMarker != "undefined"){
		eventMgr.onMapRemoveOverlay.fire(me.wayinfoMarker);
	}
};

naviki.main.Map.prototype.onMapAddOverlay = function(type, e, me) {
	me.gmap.addOverlay(e[0]);
};

naviki.main.Map.prototype.onMapRemoveOverlay = function(type, e, me) {
	me.gmap.removeOverlay(e[0]);
};

naviki.main.Map.prototype.updateWayOverlay = function(type,e,me){
	
	var factor = me.getZoomFactor(me.gmap.getZoom());

	if(factor!=me.oldFactor && me.updateWay==true){

		for(var i=0;i<me.wayOverlay.length;i++){

			me.gmap.removeOverlay(me.wayOverlay[i]['obj']);
			
			var kml    = me.wayOverlay[i]['file'];
			var myObj  = me;
			var pos    = kml.lastIndexOf("_");
						
			if(me.gmap.getCurrentMapType().getName(false)!="Earth"){
				switch(factor){
					case 1:
						kml = kml.substr(0,pos) + "_50.kml";
						break;
					case 2:
						kml = kml.substr(0,pos) + "_150.kml";
						break;
					case 3:
						kml = kml.substr(0,pos) + "_250.kml";
						break;
					default:
						kml = kml.substr(0,pos) + "_max.kml";
						break;
				}
			}else{
				kml = kml.substr(0,pos) + "_max.kml";
			}
			
			var geoxml = new GGeoXml(""+naviki.Util.DOMAIN_URL + kml);
			myObj.gmap.addOverlay(geoxml);
			myObj.wayOverlay[i]['obj'] = geoxml;
		}
		myObj.oldFactor  = factor;
	}
};

naviki.main.Map.prototype.removeWayOverlay = function(type,e,me){
	
	if(me.wayOverlay.length>0){
		for(var i=0;i<me.wayOverlay.length;i++){
			if(me.wayOverlay[i]['file']==e[0]){
				me.gmap.removeOverlay(me.wayOverlay[i]['obj']);
				me.wayOverlay.splice(i,1);
				break;
			}
			if(me.wayOverlay.length>0){
				me.oldFactor  = 0;
			}
		}
	}	
	
	if(me.gmap.getCurrentMapType().getName(false)=="Earth"){
		me.ge.getTourPlayer().setTour(null);
	}else{
		me.gefile = null;
	}
};

naviki.main.Map.prototype.addWayOverlay = function(type,e,me){
	
	me.updateWay = false;

	var geoxml;
	var factor;
	var kml    = e[0];
	var myObj  = me;
	var pos    = kml.lastIndexOf("_");	
	var obj    = new Object();
	
	if(e[1]){
		me.gefile = "" + naviki.Util.DOMAIN_URL + e[1];
	}else{
		me.gefile = null;
	}
	
	geoxml = new GGeoXml(""+naviki.Util.DOMAIN_URL + e[0], function(){
		if (geoxml.loadedCorrectly()) {
			if(geoxml.getDefaultCenter() != null && geoxml.getDefaultBounds() != null) {
	
				if(typeof e[3] == 'undefined' || e[3] == 0){
					var c  = geoxml.getDefaultCenter();
					var z  = myObj.gmap.getBoundsZoomLevel(geoxml.getDefaultBounds());
					factor = myObj.getZoomFactor(z);
					myObj.gmap.setCenter(c , z);
				}else{
					factor = myObj.getZoomFactor(myObj.gmap.getZoom());
				}
				
				if(myObj.gmap.getCurrentMapType().getName(false)!="Earth"){
					switch(factor){
						case 1:
							kml = kml.substr(0,pos) + "_50.kml";
							break;
						case 2:
							kml = kml.substr(0,pos) + "_150.kml";
							break;
						case 3:
							kml = kml.substr(0,pos) + "_250.kml";
							break;
						default:
							kml = kml.substr(0,pos) + "_max.kml";
							break;
					}
				}else{
					kml = kml.substr(0,pos) + "_max.kml";
					myObj.setTourKml();
				}

				var tmp = new GGeoXml(""+naviki.Util.DOMAIN_URL + kml);
				myObj.gmap.addOverlay(tmp);
				
				obj['file'] = e[0];
				obj['obj']  = tmp;
				
				myObj.wayOverlay.push(obj);
				
				myObj.oldFactor  = factor;
				myObj.updateWay  = true;
				myObj.setTourKml();				
       		}				
    	}
	});
};

naviki.main.Map.prototype.removeHighlightOverlay = function(type,e,me){
	if(me.highlightOverlay!=null){
		me.gmap.removeOverlay(me.highlightOverlay);
		me.highlightOverlay = null;
		me.highlightKml     = "";
	}	
};

naviki.main.Map.prototype.addHighlightOverlay = function(type,e,me){
	
	eventMgr.removeHighlightOverlay.fire();
	
	var factor = me.getZoomFactor(me.gmap.getZoom());
	var kml    = e[0];
	var myObj  = me;
	
	if(me.gmap.getCurrentMapType().getName(false)!="Earth"){
		switch(factor){
			case 1:
				kml = kml + "_50.kml";
				break;
			case 2:
				kml = kml + "_150.kml";
				break;
			case 3:
				kml = kml + "_250.kml";
				break;
			default:
				kml = kml + "_max.kml";
				break;
		}
	}else{
		kml = kml + "_max.kml";
	}

	var geoxml = new GGeoXml(""+naviki.Util.DOMAIN_URL + kml);
	myObj.gmap.addOverlay(geoxml);
	myObj.highlightOverlay = geoxml;
	myObj.oldFactor        = factor;
};

naviki.main.Map.prototype.getZoomFactor = function(zoom){

	var factor = 0;
	
	switch(zoom){
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
			factor = 1;
			break;
		case 7:
		case 8:
		case 9:
			factor = 2;
			break;
		case 10:
		case 11:
		case 12:
			factor = 3;		
			break;
		default:
			factor = 4;			
			break;
	}
	return factor;
};

/*##########################################################################
 *######################## routing request events ########################## 
 *##########################################################################
 */
naviki.main.Map.prototype.addRoutingMarker = function(type, e, me) {

	if(me.routingmarkers.length>0){
		for(var j=0;j<me.routingmarkers.length;j++){
			if(me.routingmarkers[j]!="null"){
				me.gmap.removeOverlay(me.routingmarkers[j]);
			}
		}
	}
	me.routingmarkers = new Array();
	
	var coord = e[0].split(";");
	var latlng;
	var marker;
	var newIcon;
	
	for(var i=0;i<coord.length;i++){

		if(coord[i]!="null"){
			latlng        = coord[i].split(",");
			
			newIcon       = new GIcon(G_DEFAULT_ICON); 
			newIcon.image = "http://www.geocodezip.com/mapIcons/marker"+(i+1)+".png";
			marker        = new GMarker(new GLatLng(latlng[1], latlng[0]),{draggable: true, icon: newIcon});
			marker.pos    = i;
			
			GEvent.addListener(marker, "dragend", function(){
				eventMgr.moveRoutingMarker.fire(this.pos, this.getLatLng().lng(), this.getLatLng().lat());
			});		
			
			eventMgr.updateRoutingInputs.fire(marker.pos, latlng[0], latlng[1]);
			me.routingmarkers.push(marker);
			me.gmap.addOverlay(marker);
		}
	}
};

naviki.main.Map.prototype.enableDraggingMarker = function(type, e, me) {

	if(me.routingmarkers.length>0){
		for(var j=0;j<me.routingmarkers.length;j++){
			if(me.routingmarkers[j]!="null"){
				me.routingmarkers[j].enableDragging();
			}
		}
	}
	
	// enable dragging marker in google earth
	eventMgr.enableGeDraggingMarker.fire();
};

naviki.main.Map.prototype.disableDraggingMarker = function(type, e, me) {

	if(me.routingmarkers.length>0){
		for(var j=0;j<me.routingmarkers.length;j++){
			if(me.routingmarkers[j]!="null"){
				me.routingmarkers[j].disableDragging();
			}
		}
	}
	
	// disable dragging marker in google earth
	eventMgr.disableGeDraggingMarker.fire();	
};


/*##########################################################################
 *####################### get Ways by lat,lon ############################## 
 *##########################################################################
 */
naviki.main.Map.prototype.getWays = function(LatLng,uid){

	if(this.mapSearch==true){
	
		var myObj     = this;
		var nodeCount = this.tree.getNodeCount();
		var layerUIDs = new Array(uid);	
		
		var deltaX  = 20; 
		var deltaY  = 20;
		var point   = LatLng;
		var pointXY = this.gmap.fromLatLngToContainerPixel(point);
			
		var p1 = this.gmap.fromContainerPixelToLatLng(new GPoint(pointXY.x - deltaX, pointXY.y - deltaY));
		var p2 = this.gmap.fromContainerPixelToLatLng(new GPoint(pointXY.x + deltaX, pointXY.y - deltaY));
		var p3 = this.gmap.fromContainerPixelToLatLng(new GPoint(pointXY.x + deltaX, pointXY.y + deltaY));
		var p4 = this.gmap.fromContainerPixelToLatLng(new GPoint(pointXY.x - deltaX, pointXY.y + deltaY));
	
		var bbox = p1.lng() + " " + p1.lat() + "," + p2.lng() + " " + p2.lat() + "," + p3.lng() + " " + p3.lat() + "," +p4.lng() + " " + p4.lat() + "," + p1.lng() + " " + p1.lat();
			
		var address = "index.php?eID=tx_naviki_pi_map&actionId=getWaysTouchesWithBbox&bbox="+bbox+"&layerUIDs="+YAHOO.lang.JSON.stringify(layerUIDs);
		var oCallback = {
			success : function(o) {
				var response = YAHOO.lang.JSON.parse(o.responseText);
				var ways     = response['WAYS'];
				var links    = "";
				var file     = "";
				var title    = "";
				var uid;
				var pos;
					
				if(ways.length==1){
						
					myObj.showWay(ways[0][0]);
						
				}else if(ways.length>1){
						
					if(ways.length>5){
						links = "<div style='height:100px;overflow-y: auto;overflow-x: hidden;'>";
					}else{
						links = "<div style='height:"+(ways.length*15)+"px;overflow: hidden;'>";
					}
						
					for(var i=0;i<ways.length;i++){
							
						uid    = ways[i][0];
						title  = ways[i][1];
						if(title.length>25){
							title = title.substring(0,25) + "...";
						}
							
						if(ways[i][2]!=null){
							file   = ways[i][2];
							pos    = file.lastIndexOf("_");
							file   = file.substring(0,pos);
							links += "<a href='javascript:"+myObj.obj+".showWay("+uid+");'><div onmouseover='javascript:eventMgr.addHighlightOverlay.fire(\""+file+"\");' onmouseout='javascript:eventMgr.removeHighlightOverlay.fire();'><nobr>&nbsp;"+title+"&nbsp;</nobr></div></a>";
						}else{
							links += "<a href='javascript:"+myObj.obj+".showWay("+uid+");'><div><nobr>&nbsp;"+title+"&nbsp;</nobr></div></a>";
						}
					}
					links += "</div>";
					
					myObj.contextmenu.contextMenuShow(pointXY.x, pointXY.y, links, myObj.gmap);
				}else{
					myObj.layerClickAction(LatLng);
				}
			},
			failure : function(o) {
				myObj.layerClickAction(LatLng);
			},
			cache : false
		};	
		var getXML = YAHOO.util.Connect.asyncRequest("GET", address, oCallback);
	}
};

naviki.main.Map.prototype.showWay = function(uid){
	
	eventMgr.hideContextMenu.fire();

	if(this.config['wayViewTargetSite']!="" && typeof this.config['wayViewTargetSite']!='undefined'){
		window.location.href = "/" + this.config['wayViewTargetSite'] + uid;
	}else{
		eventMgr.clearRoutingRequest.fire();
		eventMgr.updateWayInfo.fire(uid);
		eventMgr.updateWayView.fire(uid);
	}
};

naviki.main.Map.prototype.getStops = function(LatLng){

	var myObj  = this;
	var x      = this.gmap.fromLatLngToContainerPixel(LatLng).x;
	var y      = this.gmap.fromLatLngToContainerPixel(LatLng).y;
	var width  = this.gmap.getSize().width;
	var height = this.gmap.getSize().height;
	var sw     = this.gmap.getBounds().getSouthWest();
	var ne     = this.gmap.getBounds().getNorthEast();
	var bbox   = sw.lng()+","+sw.lat()+","+ne.lng()+","+ne.lat();

	var parameter = "&URL=http://maps2.connect-info.net/mapserv?MAP=/data/umn/hannit/mapfiles/haltestellen_remoteJson.map";
	parameter    += "&LAYERS=haltestellenpunkte";
	parameter    += "&TRANSPARENT=TRUE";
	parameter    += "&FORMAT=png";
	parameter    += "&SERVICE=WMS";
	parameter    += "&VERSION=1.1.1";
	parameter    += "&REQUEST=GetFeatureInfo";
	parameter    += "&STYLES=";
	parameter    += "&EXCEPTIONS=application/vnd.ogc.se_xml";
	parameter    += "&SRS=EPSG:4326";
	parameter    += "&BBOX="+bbox;
	parameter    += "&X="+x;
	parameter    += "&Y="+y;
	parameter    += "&INFO_FORMAT=text/html";
	parameter    += "&QUERY_LAYERS=haltestellenpunkte";
	parameter    += "&FEATURE_COUNT=1";
	parameter    += "&WIDTH="+width;
	parameter    += "&HEIGHT="+height;
		
	var address   = "index.php?eID=tx_naviki_pi_map&actionId=getStops"+parameter;	
	
	var oCallback = {
		success : function(o) {
			var response = YAHOO.lang.JSON.parse(o.responseText);
			if(response['STATE']!="ERROR" && response['RESULT']!=null){
				myObj.showStop(response['RESULT'].stop,LatLng);
			}else{
				myObj.layerClickAction(LatLng);
			}
		},
		failure : function(o) {
			myObj.layerClickAction(LatLng);
		},
		cache : false
	};	
	var getXML = YAHOO.util.Connect.asyncRequest("GET", address, oCallback);		
};

naviki.main.Map.prototype.showStop = function(s,LatLng){

	var c = "<div class='hstcopyright'>";
	c += "<a href='" + s.copyright.url + "' target='_blank'>";
	c += "<img src='uploads/tx_naviki_domain_model_layer/" + this.stopsLayerIcon + "' border=0>";
	c += "</a>";
	c += "</div>";
	c += "<div class='hstname'>" + s.name + "</div>";

	if (YAHOO.lang.isArray(s.servicegroups.servicegroup)) {
		for ( var i in s.servicegroups.servicegroup) {
			if (isNaN(i))
				break;
//			c += "<div class='hstgroup'>" + s.servicegroups.servicegroup[i].name + "</div>";
			var z = s.servicegroups.servicegroup[i].services.service;
			c += this.getServices(z);
		}
	} else {
//		c += "<div class='hstgroup'>" + s.servicegroups.servicegroup.name + "</div>";
		c += this.getServices(s.servicegroups.servicegroup.services.service);
	}

	this.gmap.openInfoWindow(LatLng,"<div class='hstdiv'>" + c + "</div>");
};

naviki.main.Map.prototype.getServices = function(service) {

	var r = "";
    if (YAHOO.lang.isArray(service)) {
        for (var i = 0; i < service.length; i++) {
            r += "<div class='hstservice'><a href='" + service[i].url + "' target='_blank'>" + this.formatServiceLink(service[i].description) + "</a></div>";
        }
    } else {
        r += "<div class='hstservice'><a href='" + service.url + "' target='_blank'>" + this.formatServiceLink(service.description) + "</a></div>";
    }
    
    return r;
};

naviki.main.Map.prototype.formatServiceLink = function(text){

	if(text.search(/EFA/)!=-1){
		if(text.search(/ankommen/)!=-1){
			text = naviki.Lang.getLL('map_stops_layer_to');
		}else if(text.search(/abfahren/)!=-1){
			text = naviki.Lang.getLL('map_stops_layer_from');
		}
	}
	
	return text;
};

naviki.main.Map.prototype.layerClickAction = function(LatLng){
	if(this.selectedLayer.length>0){
		var layer = this.selectedLayer[0];
		this.selectedLayer.splice(0,1);
		switch(parseInt(layer.myType)){
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:	
				this.layerClickAction(LatLng);
				break;
//	        	this.getWays(LatLng,layer.mylabel);
//				break;
			case 6:
				this.getStops(LatLng);
				break;
			default:
				break;
		} 		
	}
};

naviki.main.Map.prototype.enableMapFunctions = function(type, e, me){
	me.mapSearch  = true;
	me.clickLayer = true;
};

naviki.main.Map.prototype.disableMapFunctions = function(type, e, me){
	me.mapSearch  = false;
	me.clickLayer = false;
};

/*##########################################################################
 *######################## Contextmenu object ############################## 
 *##########################################################################
 */
function ContextMenu(map){
	
	this.map   = map;
	this.coor  = new Object();
	this.links = new Object();
	this.x     = 0;
	this.y     = 0;

	var myObj  = this;
	
    /* create context menu for google map */
	this.contextmenudiv                  = document.createElement("div");
	this.contextmenudiv.id               = map.id+"ctxMenu";
	this.contextmenudiv.style.background = "#ffffff";
	this.contextmenudiv.style.border     = "1px solid #6A6E4D";
	this.contextmenudiv.style.position   = "absolute";
	this.contextmenudiv.style.visibility = "hidden";
	this.map.gmap.getContainer().appendChild(this.contextmenudiv);
	
	// listen for mousemove
	YAHOO.util.Event.on(document, 'mousemove', function(e){
		
		if(document.all){
			posx = window.event.clientX + document.documentElement.scrollLeft;
			posy = window.event.clientY + document.documentElement.scrollTop;
		}else{
			posx = e.pageX;
			posy = e.pageY;
		}
		
		var region = YAHOO.util.Dom.getRegion(myObj.map.id);
		if (posx < region.left || posx > (region.left + region.width) || posy < region.top || posy > (region.top + region.height)){
			eventMgr.hideContextMenu.fire();
		}
	});
	
    // listen for single rightclick
	map.rightClick = GEvent.addListener(map.gmap, 'singlerightclick', function(pixel,tile,overlay) {
		
		var link = "";
		var x    = pixel.x;
        var y    = pixel.y;
        var coor = myObj.map.gmap.fromContainerPixelToLatLng(new GPoint(x,y));
        
        myObj.x = x;
        myObj.y = y;
        
        myObj.coor['lat'] = coor.lat();
        myObj.coor['lng'] = coor.lng();
                
        if(overlay==null){

        	for (var key in myObj.links){
        		link += myObj.links[key];
        	}
        	
        	if(parseInt(myObj.map.config['waysNextToPoint'])==1){
        		link += "<a href='javascript:"+myObj.map.obj+".createBounds(###LAT###,###LNG###);'><div>&nbsp;"+ naviki.Lang.getLL('ways_nextto_point') + "&nbsp;</div></a>";
        	}
        	
        	if(link.length!=0){
	        	link = link.replace(/###LAT###/g,  myObj.coor['lat']);
	        	link = link.replace(/###LNG###/g,  myObj.coor['lng']);
	        	link = link.replace(/###ZOOM###/g, myObj.map.gmap.getZoom());
	
	        	myObj.contextMenuShow(x,y,link);
        	}
        
        }else{
         	// check, if the overlay is a imagemarker
    		for(var i=0;i<myObj.map.imagemarkers.length;i++){
    			if(overlay==myObj.map.imagemarkers[i]){
    				if(myObj.map.imagemarkers[i].draggingEnabled()==true){
    					link = "<a href='javascript:"+myObj.map.obj+".removeGeolocationImageByLink(\""+overlay.title+"\");'><div>&nbsp;"+ naviki.Lang.getLL('delete') + "&nbsp;</div></a>";
	    				myObj.contextMenuShow(x,y,link);
    				}
    				break;
    			}
    		}
        }
	});
	
	// register events
	eventMgr.hideContextMenu.subscribe(this.hideContextMenu,this);
	eventMgr.updateContextMenu.subscribe(this.updateContextMenu,this);
};	

ContextMenu.prototype.updateContextMenu = function(type,e,me){
	me.links[e[0]] = e[1];
};

ContextMenu.prototype.hideContextMenu = function(type,e,me){
	
	me.contextmenudiv.style.visibility="hidden";
	
	// for ge-plugin
	var iframeShim = document.getElementById(me.map.id + "ctxMenu_iframeShim");
	if(iframeShim!=null){
		me.map.gmap.getContainer().removeChild(iframeShim);
	}
};

// show contextmenu
ContextMenu.prototype.contextMenuShow = function(x,y,links){

	this.contextmenudiv.style.width  = "";
	this.contextmenudiv.style.height = "";
	this.contextmenudiv.innerHTML    = links;

	// calculate width and height of contextmenu
	var region = YAHOO.util.Dom.getRegion(this.map.id + "ctxMenu");
	this.contextmenudiv.style.width  = region.width + "px";
	this.contextmenudiv.style.height = (region.height+2) + "px";	
	
	var iframeShim     = document.getElementById(this.map.id + "ctxMenu_iframeShim"); 
	var contextmenudiv = document.getElementById(this.map.id + "ctxMenu");
	
	var width  = region.width;
	var height = region.height;
	
	if(iframeShim==null){
		// create an IFRAME shim for the contextmenu
		iframeShim                = document.createElement('iframe');
		iframeShim.id             = this.map.id + "ctxMenu_iframeShim";
		iframeShim.frameBorder    = 0;
		iframeShim.scrolling      = 'no';
		iframeShim.src            = (navigator.userAgent.indexOf('MSIE 6') >= 0) ? '' : 'javascript:void(0);';
		iframeShim.style.position = 'absolute';
		iframeShim.style.width    = width;
		iframeShim.style.height   = height;
			
		// set up z-orders
		contextmenudiv.style.zIndex = 10;
		iframeShim.style.zIndex     = 9;				
		this.map.gmap.getContainer().appendChild(iframeShim);
	}

	if(typeof x != "undefined" && typeof y != "undefined"){
		
	    if (x > this.map.gmap.getSize().width - width - 10) { x = this.map.gmap.getSize().width - width - 10; }
	    if (y > this.map.gmap.getSize().height - height - 10) { y = this.map.gmap.getSize().height - height - 10; }
	
		contextmenudiv.style.top  = y + "px";
		contextmenudiv.style.left = x + "px";
		
		iframeShim.style.top    = y + "px";
		iframeShim.style.left   = x + "px";
	}

	contextmenudiv.style.visibility = "visible";
	iframeShim.width  = width;
	iframeShim.height = height;
};

/*##########################################################################
 *################### YUI STUFF FOR TREEVIEW WIDGET ######################## 
 *##########################################################################
 */

/**
 * The check box marks a task complete.  It is a simulated form field 
 * with three states ...
 * 0=unchecked, 1=some children checked, 2=all children checked
 * When a task is clicked, the state of the nodes and parent and children
 * are updated, and this behavior cascades.
 *
 * @extends YAHOO.widget.TextNode
 * @constructor
 * @param oData    {object}  A string or object containing the data that will
 *                           be used to render this node.
 * @param oParent  {Node}    This node's parent node
 * @param expanded {boolean} The initial expanded/collapsed state
 * @param checked  {boolean} The initial checked/unchecked state
 * @param overlayUrl   {object}	 The map overlay object
 * @param map A Pointer to the Map Object
 */
naviki.main.MapTaskNode = function(oData, oParent, expanded, checked, overlay, map) {

	this.mylabel  = oData.mylabel;
	this.myType   = parseInt(oData.myType);
	if(typeof oData.haveWays!=undefined){
		this.haveWays = parseInt(oData.haveWays);
	}
	this.map      = map;

	naviki.main.MapTaskNode.superclass.constructor.call(this,oData,oParent,expanded);
    this.setUpCheck(checked || oData.checked);
	
    this.showOverlay = function() {
    	if(typeof overlay!="undefined"){
    		for(var i=0;i<overlay.length;i++){
    			this.map.addOverlay(overlay[i]);
    		}
    	}
    };

    this.removeOverlay = function() {
    	if(typeof overlay!="undefined"){
    		for(var i=0;i<overlay.length;i++){
    			this.map.removeOverlay(overlay[i]);
    		}
    	}
    };
};

naviki.main.MapTaskNode.override = {
	
	/**
     * True if checkstate is 1 (some children checked) or 2 (all children checked),
     * false if 0.
     * @type boolean
     */
    checked: false,

    /**
     * checkState
     * 0=unchecked, 1=some children checked, 2=all children checked
     * @type int
     */
    checkState: 0,

	/**
     * The node type
     * @property _type
     * @private
     * @type string
     * @default "TextNode"
     */
    _type: "TaskNode",
    
	taskNodeParentChange: function() {
        //this.updateParent();
    },
	
    setUpCheck: function(checked) {
        // if this node is checked by default, run the check code to update
        // the parent's display state
        if (checked && checked === true) {
            this.check();
        // otherwise the parent needs to be updated only if its checkstate 
        // needs to change from fully selected to partially selected
        } else if (this.parent && 2 === this.parent.checkState) {
             this.updateParent();
        }

        // set up the custom event on the tree for checkClick
        /**
         * Custom event that is fired when the check box is clicked.  The
         * custom event is defined on the tree instance, so there is a single
         * event that handles all nodes in the tree.  The node clicked is 
         * provided as an argument.  Note, your custom node implentation can
         * implement its own node specific events this way.
         *
         * @event checkClick
         * @for YAHOO.widget.TreeView
         * @param {YAHOO.widget.Node} node the node clicked
         */
        if (this.tree && !this.tree.hasEvent("checkClick")) {
            this.tree.createEvent("checkClick", this.tree);
        }

		this.tree.subscribe('clickEvent',this.checkClick);
        this.subscribe("parentChange", this.taskNodeParentChange);


    },

    /**
     * The id of the check element
     * @for naviki.main.MapTaskNode
     * @type string
     */
    getCheckElId: function() { 
        return "ygtvcheck" + this.index; 
    },

    /**
     * Returns the check box element
     * @return the check html element (img)
     */
    getCheckEl: function() { 
        return document.getElementById(this.getCheckElId()); 
    },

    /**
     * The style of the check element, derived from its current state
     * @return {string} the css style for the current check state
     */
    getCheckStyle: function() { 
        return "ygtvcheck" + this.checkState;
    },


   /**
     * Invoked when the user clicks the check box
     */
    checkClick: function(oArgs) {

		var node = oArgs.node;
		var target = YAHOO.util.Event.getTarget(oArgs.event);
		if (YAHOO.util.Dom.hasClass(target,'ygtvspacer')) {
			if (node.checkState === 0) {
	            node.check();
	        } else {
	            node.uncheck();
	        }

	        node.onCheckClick(node);
	        this.fireEvent("checkClick", node);
		    return false;
		}
    },
    
    //store active layer from GoogleMap
    store_settings: function(node,check){

    	if(parseInt(node.myType)!=5){
    	
	    	var myObj = this.map.myObj;
	    	
	    	if(myObj.have_fe_user){
	    		
	    		var nodeCount = myObj.tree.getNodeCount();
	    		var active    = "";
	    		
	    		if(check==1){
		    		for(var i=1;i<=nodeCount;i++){
		    			if(myObj.tree.getNodeByIndex(i).checked==true){
		    				active += this.tree.getNodeByIndex(i).mylabel + ",";
		    			}
		    		}
		    		active += node.mylabel;	
		    	}else{
		    		for(var i=1;i<=nodeCount;i++){
		    			if(myObj.tree.getNodeByIndex(i).checked==true && myObj.tree.getNodeByIndex(i)!=node){
		    				active += this.tree.getNodeByIndex(i).mylabel + ",";
		    			}
		    		}
		    		if(active.length>0){
		    			active = active.substr(0,active.length-1);
		    		}
		    	}
	    	
	    		var address = "index.php?eID=tx_naviki_pi_map&actionId=storeActiveLayer&activeLayer="+active;
	    		var oCallback = {
	    			success : function(o) {
	    			},
	    			failure : function(o) {
	    				alert("Sorry, no data found for that address!\n Here is the response: " + o);
	    			},
	    			cache : false
	    		};	
	    		var getXML = YAHOO.util.Connect.asyncRequest("GET", address, oCallback);
	    	}
    	}
    },

    /**
     * Override to get the check click event
     */
    onCheckClick: function(node) { 
        
    },

    /**
     * Refresh the state of this node's parent, and cascade up.
     */
    updateParent: function() { 
        var p = this.parent;

        if (!p || !p.updateParent) {
            return;
        }

        var somethingChecked = false;
        var somethingNotChecked = false;

        for (var i=0, l=p.children.length;i<l;i=i+1) {

            var n = p.children[i];

            if ("checked" in n) {
                if (n.checked) {
                    somethingChecked = true;
                    // checkState will be 1 if the child node has unchecked children
                    if (n.checkState === 1) {
                        somethingNotChecked = true;
                    }
                } else {
                    somethingNotChecked = true;
                }
            }
        }

        if (somethingChecked) {
            p.setCheckState( (somethingNotChecked) ? 1 : 2 );
        } else {
            p.setCheckState(0);
        }

        p.updateCheckHtml();
        p.updateParent();
    },

    /**
     * If the node has been rendered, update the html to reflect the current
     * state of the node.
     */
    updateCheckHtml: function() { 
        if (this.parent && this.parent.childrenRendered) {
            this.getCheckEl().className = this.getCheckStyle();
        }
    },

    /**
     * Updates the state.  The checked property is true if the state is 1 or 2
     * 
     * @param the new check state
     */
    setCheckState: function(state) { 
        this.checkState = state;
        this.checked = (state > 0);
    },

    /**
     * Check this node
     */
    check: function() {
    	this.store_settings(this,1); 
    	this.showOverlay();
        this.setCheckState(2);
     
        for (var i=0, l=this.children.length; i<l; i=i+1) {
            var c = this.children[i];
            if (c.check) {
                c.check();
            }
        }
        this.updateCheckHtml();
        this.updateParent();
    },

    /**
     * Uncheck this node
     */
    uncheck: function() {
    	this.store_settings(this,0); 
    	this.removeOverlay();
        this.setCheckState(0);
        for (var i=0, l=this.children.length; i<l; i=i+1) {
            var c = this.children[i];
            if (c.uncheck) {
                c.uncheck();
            }
        }
        this.updateCheckHtml();
        this.updateParent();
    },
    // Overrides YAHOO.widget.TextNode
    getContentHtml: function() {                                                                                                                                           
        var sb = [];                                                                                                                                                       
        sb[sb.length] = '<td';                                                                                                                                             
        sb[sb.length] = ' id="' + this.getCheckElId() + '"';                                                                                                               
        sb[sb.length] = ' class="' + this.getCheckStyle() + '"';                                                                                                           
        sb[sb.length] = '>';                                                                                                                                               
        sb[sb.length] = '<div class="ygtvspacer"></div></td>';                                                                                                             
                                                                                                                                                                           
        sb[sb.length] = '<td><span';                                                                                                                                       
        sb[sb.length] = ' id="' + this.labelElId + '"';                                                                                                                    
        if (this.title) {                                                                                                                                                  
            sb[sb.length] = ' title="' + this.title + '"';                                                                                                                 
        }                                                                                                                                                                  
        sb[sb.length] = ' class="' + this.labelStyle  + '"';                                                                                                               
        sb[sb.length] = ' >';                                                                                                                                              
        sb[sb.length] = this.label;                                                                                                                                        
        sb[sb.length] = '</span></td>';                                                                                                                                    
        return sb.join("");                                                                                                                                                
    }  
};

/*############################################################################
 *############################# draw mode ####################################
 *############################################################################
 */
function drawing(map,id,context){
	
	this.end      = naviki.Util.FILEADMIN_PATH + "img/pi_map/draw_end_marker_image.png";
	this.begin    = naviki.Util.FILEADMIN_PATH + "img/pi_map/draw_start_marker_image.png";
	this.between  = naviki.Util.FILEADMIN_PATH + "img/pi_map/draw_between_marker_image.png";
	this.map      = map;
	this.id       = id;
	this.markers  = new Array();
	this.buffer   = new Array();
	this.polyline = null;
	this.mode     = "none";
	this.wait     = false;
	this.file     = "";
	this.context  = context;
	this.tptext   = -1;
	this.minzoom  = 13;
	this.x;
	this.y;
	this.startMarker = null;
	this.endMarker   = null;

	eventMgr.enableDrawMode.subscribe(this.enableDrawMode, this);
	eventMgr.disableDrawMode.subscribe(this.disableDrawMode,this);
	eventMgr.loadDrawing.subscribe(this.loadDrawing,this);
	eventMgr.getDrawing.subscribe(this.getDrawing,this);
};

drawing.prototype.disableDrawMode = function(type, e, me){
	me.hideDrawMode();
	me.drawIsActive = false;
	eventMgr.enableMapFunctions.fire();
};

drawing.prototype.enableDrawMode = function(type, e, me){
	me.drawIsActive = true;
	me.showDrawMode();
	eventMgr.disableMapFunctions.fire();
};

drawing.prototype.showDrawMode = function(){	
	if(typeof this.drawIsActive!="undefined" && this.drawIsActive==true){
		var element = document.getElementById(this.id + "drawContainer");
		if(this.polyline != null){
			this.polyline.show();
		}
		if(element!=null){
			element.style.display = "";
		}else{
			this.initDraw();
		}
	}
};

drawing.prototype.hideDrawMode = function(){
	if(typeof this.drawIsActive!="undefined" && this.drawIsActive==true){
		var element = document.getElementById(this.id + "drawContainer");
		if(this.polyline != null){
			this.polyline.hide();
		}
		if(element!=null){
			element.style.display = "none";
		}
	}
};

drawing.prototype.initDraw = function(){
	
	var myObj      = this;
	var container  = document.createElement("p");
	var line       = document.createElement("p");
	var direction  = document.createElement("p");

	line.id         = this.id + "lineItem";
	line.title      = naviki.Lang.getLL('draw_line');
	direction.id    = this.id + "directionItem";
	direction.title = naviki.Lang.getLL('draw_road');
	container.id    = this.id + "drawContainer";

	YAHOO.util.Dom.addClass(container, 'drawContainer');
	YAHOO.util.Dom.addClass(line, 'lineItem-no');
	YAHOO.util.Dom.addClass(direction, 'directionItem-no');

	YAHOO.util.Event.on(line, 'click', function(e){
		myObj.tptext = 1;
		myObj.setButton("line");
	});
	YAHOO.util.Event.on(direction, 'click', function(e){
		myObj.tptext = 1;
		myObj.setButton("direction");
	});	
	
	YAHOO.util.Event.on(document.getElementById(this.id), 'mousemove', function(e){

		var region = YAHOO.util.Dom.getRegion(myObj.id);
		var x,y,text;
		
		if(document.all){
			x = window.event.clientX + document.documentElement.scrollLeft;
			y = window.event.clientY + document.documentElement.scrollTop;
		}else{
			x = e.pageX;
			y = e.pageY;
		}
		
		myObj.x = x-region.left + 10;
		myObj.y = y-region.top + 10;
		
		if(myObj.tptext>0){
			switch(myObj.tptext){
				case 1:
					if(myObj.markers.length==0){
						text = "<p style='margin:2px 2px 0 2px;'>"+naviki.Lang.getLL('draw_mousemove.0')+"</p>";
					}else{
						text = "<p style='margin:2px 2px 0 2px;'>"+naviki.Lang.getLL('draw_mousemove.1')+"</p>";
					}
					break;
				case 2:
					text = "<p style='margin:2px 2px 0 2px;'>"+naviki.Lang.getLL('draw_polyline')+"</p>";
					break;
				case 3:
					text = "<p style='margin:2px 2px 0 2px;'>"+naviki.Lang.getLL('draw_marker.0')+"<br>"+naviki.Lang.getLL('draw_marker.1')+"</p>";
					break;
			}
			myObj.context.contextMenuShow(myObj.x,myObj.y,text);
		}
	});	

	container.appendChild(line);
	container.appendChild(direction);
	this.map.getContainer().appendChild(container);
	
	if(typeof this.click=="undefined"){
		this.click = GEvent.addListener(this.map, "click", function(overlay,LatLon,overlayLatLon){
			if(!overlay && myObj.mode!="none") {
				if(myObj.checkZoom(LatLon) && myObj.wait==false){
					myObj.addMarker(LatLon,true);
				}
			}
		});
	}
	
	if(typeof this.zoom=="undefined"){
		this.zoom = GEvent.addListener(this.map, "zoomend", function(oldLevel,newLevel){
			if(newLevel>myObj.minzoom) {
				myObj.enableDraggingMarker();
			}else{
				myObj.disableDraggingMarker();
			}
		});
	}
	
	this.newPolyline([]);
	this.mgr = new MarkerManager(this.map);
};

drawing.prototype.setButton = function(button){
	
	var line      = document.getElementById(this.id + "lineItem");
	var direction = document.getElementById(this.id + "directionItem");

	switch(this.mode){
		case "line":
			YAHOO.util.Dom.replaceClass(line, 'lineItem-act', 'lineItem-no');
			break;
		case "direction":
			YAHOO.util.Dom.replaceClass(direction, 'directionItem-act', 'directionItem-no');
			break;
	}	
	
	switch(button){
		case "line":
			YAHOO.util.Dom.replaceClass(line, 'lineItem-no', 'lineItem-act');
			this.mode = "line";
			break;
		case "direction":
			YAHOO.util.Dom.replaceClass(direction, 'directionItem-no', 'directionItem-act');
			this.mode = "direction";
			break;
		
	}
};

drawing.prototype.newPolyline = function(points){

	this.wait = true;
	
	if(this.polyline!=null){
		GEvent.removeListener(this.polyline.mouseout);
		GEvent.removeListener(this.polyline.mouseover);
		GEvent.removeListener(this.polyline.click);
		GEvent.removeListener(this.polyline.lineupdated);
		this.map.removeOverlay(this.polyline);
	}	
	
	var myObj     = this;
	this.polyline = new GPolyline(points,'#ff0000', 5, 0.7);
	
	var mouseout = GEvent.addListener(this.polyline, "mouseout", function(){	
		myObj.tptext = 1;
	});

	var mouseover = GEvent.addListener(this.polyline, "mouseover", function(){	
		myObj.tptext = 2;
	});
	
	var click = GEvent.addListener(this.polyline, "click", function(LatLon){
		myObj.tptext = 3;
		if(myObj.checkZoom(LatLon) && myObj.wait==false){
			myObj.insertMarker(LatLon);			
		}
	});
	
	var lineupdated = GEvent.addListener(this.polyline, "lineupdated", function(){
		myObj.checkBuffer();		
	});
	
	
	this.polyline.mouseout    = mouseout;
	this.polyline.mouseover   = mouseover;
	this.polyline.click       = click;
	this.polyline.lineupdated = lineupdated;
	this.map.addOverlay(this.polyline);
	this.checkBuffer();
};

drawing.prototype.checkBuffer = function(){
	if(this.buffer.length>0){
		var job = this.buffer[0];
		this.buffer.splice(0,1);
		if(job.mode=="line"){
			this.drawLine(job.start,job.end,job.points);
		}else{
			this.drawDirection(job.start,job.end,job.points);
		}		
	}else{
		this.wait=false;
		this.enableDraggingMarker();
	}		
};

drawing.prototype.enableDraggingMarker = function(){
	for(var i=0;i<this.markers.length;i++){
		this.markers[i].enableDragging();
	}
};

drawing.prototype.disableDraggingMarker = function(){
	for(var i=0;i<this.markers.length;i++){
		this.markers[i].disableDragging();
	}	
};

drawing.prototype.addMarkerListener = function(marker){

	var myObj = this;
	
	marker.dragend =  GEvent.addListener(marker, "dragend", function(LatLon){
		myObj.dragMarker(this);
	});
	marker.click = GEvent.addListener(marker, "click", function(LatLon){
		myObj.tptext = 1;
		if(myObj.checkZoom(LatLon) && myObj.wait==false){
			myObj.removeMarker(this);
		}	
	});
	marker.mouseover = GEvent.addListener(marker, "mouseover", function(LatLon){
		myObj.tptext = 3;
	});
	marker.mouseout = GEvent.addListener(marker, "mouseout", function(LatLon){
		myObj.tptext = 1;
	});	
	
	return marker;
};

drawing.prototype.removeMarkerListener = function(marker){
	GEvent.removeListener(marker.dragend);
	GEvent.removeListener(marker.click);
	GEvent.removeListener(marker.mouseover);
	GEvent.removeListener(marker.mouseout);
};

drawing.prototype.addMarker = function(LatLon,draw){

	var length;	
	var marker    = new GMarker(LatLon,{draggable: true});
	marker        = this.addMarkerListener(marker);
	marker.title  = "MarkerFromDrawing";
	marker.pos    = this.markers.length;
	marker.mode   = this.mode;
	marker.enableDragging();
		
	this.markers.push(marker);	
	if(draw==true){
		this.updateMarker();
	}
	
	if(this.markers.length>1 && draw==true){
		start  = this.markers[this.markers.length-2].getLatLng();
		end    = this.markers[this.markers.length-1].getLatLng();
		this.drawObject(start,end,this.mode,[]);
	}

	if(this.markers.length==2){
		eventMgr.existDrawing.fire(true);
	}
};

drawing.prototype.insertMarker = function(LatLon){

	var polyline;
	var bbox;
	var start;
	var end;
	var marker;
	var index;
	var result = new Array();
	var points = new Array();
	
	start = this.markers[0].getLatLng();
	for(var j=1;j<this.markers.length;j++){
		end = this.markers[j].getLatLng();
		for(var k=0;k<this.polyline.getVertexCount();k++){
			if(start.lat()==this.polyline.getVertex(k).lat() && start.lng()==this.polyline.getVertex(k).lng()){
				break;
			}
		}
		for(var l=k;l<this.polyline.getVertexCount();l++){
			if(end.lat()==this.polyline.getVertex(l).lat() && end.lng()==this.polyline.getVertex(l).lng()){
				points.push(end);
				break;
			}else{
				points.push(this.polyline.getVertex(l));
			}
		}
		polyline = new GPolyline(points);
		bbox     = polyline.getBounds();
		if(bbox.containsLatLng(LatLon)){
			polyline.start = j-1;
			polyline.end   = j;
			result.push(polyline);
		}
		start  = end;
		points = new Array();
	}
	
	if(result.length>1){
		var old   = 100;
		var index = 0;
		var temp;
		var deltaLat;
		var deltyLon;
		var count;
		for(var i=0;i<result.length;i++){
			start = result[i].getVertex(0);
			for(var j=1;j<result[i].getVertexCount();j++){
				end  = result[i].getVertex(j);
				if(start.lat()!=end.lat() || start.lng()!=end.lng()){
					dist = start.distanceFrom(end);
					if(dist>20){
						deltaLat = start.lat() - end.lat();
						deltaLon = start.lng() - end.lng();
						count    = parseInt(dist/20);
						for(var k=0;k<count;k++){
							temp = new GLatLng(start.lat()-k*(deltaLat/count),start.lng()-k*(deltaLon/count));
							if(temp.distanceFrom(LatLon)<old){
								old   = temp;
								index = i; 
							}
						}							
					}else if(dist<old){
						old   = temp;
						index = i; 
					}
				}
				start = end;
			}
		}
		result = result[index];
	}else{
		result = result[0];
	}
	
	points   = new Array();
	marker   = this.markers[result.start];
	polyline = this.polyline;
	for(var j=0;j<polyline.getVertexCount();j++){
		if(marker.getLatLng().lat()==polyline.getVertex(j).lat() && marker.getLatLng().lng()==polyline.getVertex(j).lng()){
			points.push(polyline.getVertex(j));
			break;
		}else{
			points.push(polyline.getVertex(j));
		}
	}
	
	this.newPolyline(points);
	this.drawObject(this.markers[result.start].getLatLng(), LatLon, this.mode, []);

	points = new Array();
	marker = this.markers[result.end];
	for(var j=0;j<polyline.getVertexCount();j++){
		if(marker.getLatLng().lat()==polyline.getVertex(j).lat() && marker.getLatLng().lng()==polyline.getVertex(j).lng()){
			break;
		}
	}
	for(var i=j;i<polyline.getVertexCount();i++){
		points.push(polyline.getVertex(i));
	}
	
	this.drawObject(LatLon,marker.getLatLng(),marker.mode, points);
	
	
    var newicon   = new GIcon(G_DEFAULT_ICON);
    newicon.image = this.between;
	marker        = new GMarker(LatLon,{draggable: true, icon: newicon});
	marker        = this.addMarkerListener(marker);
	marker.title  = "MarkerFromDrawing";
	marker.pos    = result.end;
	marker.mode   = this.mode;
	marker.enableDragging();
	
	this.markers.splice(result.end,0,marker);
	this.updateMarker();
	
	for(var i=(result.end);i<this.markers.length;i++){
		this.markers[i].pos = i;
	}
/*	
	start = this.polyline.getVertex(1);
	for(var i=2;i<this.polyline.getVertexCount();i++){
		end = tthis.polyline.getVertex(i);
		deltaLat = start.lat() - end.lat();
		deltaLon = start.lng() - end.lng();
		
		m = deltaLat/deltaLon;
		b = start.lat()-m*start.lng();
		
		alert(LatLon.lat()+", "+(m*LatLon.lng()+b));
		start = end;
	}
*/	
};

drawing.prototype.removeMarker = function(marker){

	var prevMarker = null;
	var nextMarker = null;
	var points     = new Array();
	var polyline   = this.polyline;
	
	if(marker.pos>0){
		prevMarker = this.markers[marker.pos-1];
	}
	
	if(marker.pos<this.markers.length-1){
		nextMarker = this.markers[marker.pos+1];
	}

	this.removeMarkerListener(marker);
	this.markers.splice(marker.pos, 1);
	for(var k=0;k<this.markers.length;k++){
		this.markers[k].pos = k;
	}

	if(prevMarker!=null){
		for(var j=0;j<polyline.getVertexCount();j++){
			if(prevMarker.getLatLng().lat()==polyline.getVertex(j).lat() && prevMarker.getLatLng().lng()==polyline.getVertex(j).lng()){
				points.push(polyline.getVertex(j));
				break;
			}else{
				points.push(polyline.getVertex(j));
			}
		}
		this.newPolyline(points);
	}else{
		if(this.markers.length>=1){
			this.markers[0].setImage(this.begin);
		}
	}
	
	if(nextMarker!=null){
		for(var j=0;j<polyline.getVertexCount();j++){
			if(nextMarker.getLatLng().lat()==polyline.getVertex(j).lat() && nextMarker.getLatLng().lng()==polyline.getVertex(j).lng()){
				break;
			}
		}
		points = new Array();
		for(var i=j;i<polyline.getVertexCount();i++){
			points.push(polyline.getVertex(i));
		}
		if(prevMarker!=null){
			this.drawObject(prevMarker.getLatLng(), nextMarker.getLatLng(), nextMarker.mode, points);
		}else{
			this.newPolyline(points);
		}
	}else{
		if(this.markers.length>=2){
			this.markers[this.markers.length-1].setImage(this.end);
		}
	}
	
	if(prevMarker==null && nextMarker==null){
		this.newPolyline([]);		
	}
	
	if(this.markers.length<2){
		eventMgr.existDrawing.fire(false);
	}
	
	this.updateMarker();
};

drawing.prototype.updateMarker = function(){

	var marker;
	var temp = new Array();
	this.mgr.clearMarkers();

	if(this.markers.length>0){
		marker = this.markers[0];
		marker.getIcon().image = this.begin;
		if(this.startMarker!=null){
			this.map.removeOverlay(this.startMarker);
		}
		this.startMarker = marker;
		this.map.addOverlay(marker);		
	}else{
		this.startMarker = null;
	}
	
	if(this.markers.length>1){
		marker = this.markers[this.markers.length-1];
		marker.getIcon().image = this.end;
		if(this.endMarker!=null){
			this.map.removeOverlay(this.endMarker);
		}
		this.endMarker = marker;
		this.map.addOverlay(marker);
	}else{
		this.endMarker = null;
	}

	if(this.markers.length>2){
		for(var i=1;i<this.markers.length-1;i++){
			marker = this.markers[i];
			marker.getIcon().image = this.between;
			temp.push(marker);
		}
		this.mgr.addMarkers(temp, this.minzoom+1);
	}

	this.mgr.refresh();		
};

drawing.prototype.dragMarker = function(marker){

	var prevMarker = null;
	var nextMarker = null;
	var points     = new Array();
	var polyline   = this.polyline;
	
	if(marker.pos>0){
		prevMarker = this.markers[marker.pos-1];
	}
	
	if(marker.pos<this.markers.length-1){
		nextMarker = this.markers[marker.pos+1];
	}
	
	if(prevMarker!=null){
		for(var j=0;j<polyline.getVertexCount();j++){
			if(prevMarker.getLatLng().lat()==polyline.getVertex(j).lat() && prevMarker.getLatLng().lng()==polyline.getVertex(j).lng()){
				break;
			}else{
				points.push(polyline.getVertex(j));
			}
		}
		this.newPolyline(points);
		this.drawObject(prevMarker.getLatLng(), marker.getLatLng(), marker.mode, []);
	}
	
	if(nextMarker!=null){
		for(var j=0;j<polyline.getVertexCount();j++){
			if(nextMarker.getLatLng().lat()==polyline.getVertex(j).lat() && nextMarker.getLatLng().lng()==polyline.getVertex(j).lng()){
				break;
			}
		}

		points = new Array();
		for(var i=j;i<polyline.getVertexCount();i++){
			points.push(polyline.getVertex(i));
		}

		if(prevMarker!=null){
			this.drawObject(marker.getLatLng(), nextMarker.getLatLng(), nextMarker.mode, points);
		}else{
			this.newPolyline([]);			
			this.drawObject(marker.getLatLng(), nextMarker.getLatLng(), nextMarker.mode, points);	
		}
	}
	
	if(prevMarker==null && nextMarker==null){
		this.newPolyline([]);		
	}
};

drawing.prototype.drawObject = function(start,end,mode,points){
	
	var job = new Object();
	job.start  = start;
	job.end    = end;
	job.mode   = mode;
	job.points = points;
	
	if(this.wait==true || this.buffer.length>0){
		this.buffer.push(job);
		this.disableDraggingMarker();
	}else{
		this.wait=true;
		if(mode=="line"){
			this.drawLine(start,end,points);
		}else{
			this.drawDirection(start,end,points);
		}
	}
};

drawing.prototype.drawLine = function(start,end,points){

	var temp     = new Array();
	var deltaLat = start.lat() - end.lat();
	var deltaLon = start.lng() - end.lng();	
	var count    = parseInt(start.distanceFrom(end)/250);

	for(var i=0;i<this.polyline.getVertexCount();i++){
		temp.push(this.polyline.getVertex(i));
	}
	temp.push(start);
	temp.push(end);
	this.newPolyline(temp.concat(points));
};

drawing.prototype.drawDirection = function(start,end,points){
	var myObj = this;
	var dirn  = new GDirections();
	var temp  = new Array();
	var polyline;

	GEvent.addListener(dirn,"load", function() {
		polyline = dirn.getPolyline();
		for(var i=0;i<myObj.polyline.getVertexCount();i++){
			temp.push(myObj.polyline.getVertex(i));
		}
		temp.push(start);
		for(var i=0;i<polyline.getVertexCount();i++){
			temp.push(polyline.getVertex(i));
		}
		temp.push(end);	
		myObj.newPolyline(temp.concat(points));
	});
	dirn.loadFromWaypoints([start.toUrlValue(6),end.toUrlValue(6)],{getPolyline:true});	
};

drawing.prototype.loadDrawing = function(type, e, me){
	
	me.file    = e[1];
	me.request = true;
	var tracks = e[0];
	var points = new Array();
	var oldLat = 0;
	var oldLng = 0; 
	var tmp;
	var LatLon;

	me.setButton('line');
	me.tptext = 1;	
	me.mode   = "line";
	
	for(var j=0;j<me.markers.length;j++){
		me.removeMarkerListener(me.markers[j]);
		me.mgr.clearMarkers();
	}
	me.markers = new Array();

	for(var j=0;j<tracks.length;j++){
		for(var i=0;i<tracks[j].length;i++){
			tmp    = tracks[j][i].split(",");
			LatLon = new GLatLng(tmp[1],tmp[0]);
			if(LatLon.lat()!=oldLat || LatLon.lng()!=oldLng){
				me.addMarker(LatLon,false);
				points.push(LatLon);
				oldLat = LatLon.lat();
				oldLng = LatLon.lng();	
			}
		}
	}
	
	me.newPolyline(points);
	me.updateMarker();
	
	if(me.map.getZoom()<me.minzoom){
		me.disableDraggingMarker();
	}
};

drawing.prototype.getDrawing = function(type, e, me){
	
	var temp   = new Array();
	var points = new Array();
	var point;

	me.tptext     = 0;
	var line      = document.getElementById(me.id + "lineItem");
	var direction = document.getElementById(me.id + "directionItem");
	YAHOO.util.Dom.replaceClass(line, 'lineItem-act', 'lineItem-no');
	YAHOO.util.Dom.replaceClass(direction, 'directionItem-act', 'directionItem-no');
	
	for(var k=0;k<me.markers.length;k++){
		me.removeMarkerListener(me.markers[k]);
	}
	me.mgr.clearMarkers();
	me.map.removeOverlay(me.startMarker);
	me.map.removeOverlay(me.endMarker);
	

/*	
	for(var j=0;j<me.polyline.getVertexCount();j++){
		latlon    = me.polyline.getVertex(j);
		point     = new Object();
		point.lat = latlon.lat(); 
		point.lon =	latlon.lng();
		points.push(point);
	}
*/
		
	temp = me.addPointsToLine();
	for(var j=0;j<temp.length;j++){
		latlon    = temp[j];
		point     = new Object();
		point.lat = latlon.lat(); 
		point.lon =	latlon.lng();
		points.push(point);
	}
	
	if(points.length>0){
		eventMgr.storeDrawing.fire(points,me.file);
	}

	me.newPolyline([]);
	me.markers     = new Array();
	me.file        = "";
	me.startMarker = null;
	me.endMarker   = null;
	me.mode        = "none";
};

drawing.prototype.checkZoom = function(LatLon){
	
	if(this.map.getZoom()<this.minzoom+1){
		
		if(typeof this.dialog == "undefined"){
			
			var dialog_container = document.getElementById("naviki-dialogs");
			var dialogDiv = document.createElement("div");
			dialogDiv.id  = this.id+"_drawdialog";
			dialog_container.appendChild(dialogDiv);
			
			this.dialog = new naviki.main.ModalDialog(
					dialogDiv.id,   
					{ 	width      : "310px",  
						fixedcenter: true,  
						visible    : false,
						modal      : true,
						draggable  : true,
						zindex     : 4,
						close      : true,  
						constraintoviewport: true,
						buttons : [ { text:naviki.Lang.getLL('dialog_cancel'), handler: this.hideDialog},
						            { text:naviki.Lang.getLL('draw_dialog_zoomin')+"<br>", handler: this.zoomIn}
						          ] 
					}
			);
			this.dialog.myObj = this;
			this.dialog.setHeader(naviki.Lang.getLL('draw_dialog_header'));
			this.dialog.setBody(naviki.Lang.getLL('draw_dialog_body'));
			this.dialog.render();	
		}
		this.dialog.LatLon = LatLon;
		this.dialog.show();
		return false;
	}else{
		return true;
	}
};

drawing.prototype.hideDialog = function(){
	this.hide();
};

drawing.prototype.zoomIn = function(){
	this.myObj.map.setCenter(this.LatLon,this.myObj.minzoom+1); 
	this.hide();
};

drawing.prototype.addPointsToLine = function(){
	
	var points = new Array();
	var LatLon;
	var start;
	var end;
	var deltaLat;
	var deltaLon;
	var count;
	
	start = this.polyline.getVertex(0);
	for(var i=1;i<this.polyline.getVertexCount();i++){
		end = this.polyline.getVertex(i);
		deltaLat = start.lat() - end.lat();
		deltaLon = start.lng() - end.lng();	
		count    = parseInt(start.distanceFrom(end)/150);	
		points.push(start);
		if(count>2){
			for(var j=0;j<count;j++){
				LatLon = new GLatLng(start.lat()-j*(deltaLat/count),start.lng()-j*(deltaLon/count));
				points.push(LatLon);
			}
		}
		points.push(end);
		start = end;
	}

	return points;
};

