var myGeoEngine = Class.create();

myGeoEngine.prototype=
{
	initialize:function()
	{
		this.myMap = null;
		// default engine is openstreetmap
		this.myEngine = "OSM";
		this.layerVectors = null;
	},
	init:function()
	{
		var lat=50.3;
		var lon=8.5;
		var zoom=13;
		
		switch(this.myEngine)
		{
			case "google":
				// only if the google-api is proper called in the header of the html-page, this works!
				if (typeof google != 'undefined')
				{
					// create a good google map for the div "map"
					this.myMap = new google.maps.Map2($("map"));
					this.myMap.addControl(new GLargeMapControl());
					this.myMap.addControl(new GMapTypeControl());
					this.myMap.setCenter(new GLatLng(lat, lon), zoom, G_NORMAL_MAP);
				}
				break;
				
			case "OSM":
				this.myMap = new OpenLayers.Map ("map", {
						controls:[
						    new OpenLayers.Control.Navigation(),
						    new OpenLayers.Control.PanZoomBar(),
						    new OpenLayers.Control.Attribution()],
						maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
						maxResolution: 156543.0399,
						numZoomLevels: 19,
						units: 'm',
						projection: new OpenLayers.Projection("EPSG:900913"),
						displayProjection: new OpenLayers.Projection("EPSG:4326")
					    } );
					    
				// Define the map layer
				// Note that we use a predefined layer that will be
				// kept up to date with URL changes
				// Here we define just one layer, but providing a choice
				// of several layers is also quite simple
				// Other defined layers are OpenLayers.Layer.OSM.Mapnik, OpenLayers.Layer.OSM.Maplint and OpenLayers.Layer.OSM.CycleMap
				layerTilesAtHome = new OpenLayers.Layer.OSM.Osmarender("Osmarender");
				this.myMap.addLayer(layerTilesAtHome);
				
				var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), this.myMap.getProjectionObject());
				
				this.myMap.setCenter (lonLat, zoom);
				
				// add a layer for markers
				this.layerMarkers = new OpenLayers.Layer.Markers("Markers");
				// add a layer for polylines
				this.layerVectors = new OpenLayers.Layer.Vector("Vectors");
				
				this.myMap.addLayers([this.layerMarkers, this.layerVectors]);
				break;
			default:
				break;
		}
	},
	// Here you may switch the engine from "google" to "OSM" ( OpenStreetMap)
	setEngine:function(anEngine)
	{
		this.myEngine = anEngine;
		this.init();
	},
	// return the engine-object directly
	map:function()
	{
		return this.myMap;
	},
	// creates a marker, engine-depending
	createMarker:function(aPosition, aIcon)
	{
		switch(this.myEngine)
		{
			case "google":
				return new GMarker(aPosition, aIcon);
				break;
			case "OSM":
				return new OpenLayers.Marker(aPosition, aIcon);
				break;
			default:
				return null;
		}
	},
	/** creates an icon, engine-depending
	 * @parameter string
	 */
	createIcon:function(anIconName, anIcon_X, anIcon_Y, 
	                            anShadowIconName, anShadowIcon_X, anShadowIcon_Y)
	{
		var anIcon;
		
		switch(this.myEngine)
		{
			case "google":
				// a new Icon for a user
				anIcon = new GIcon();
				anIcon.image = anIconName; 
				anIcon.shadow = anShadowIconName; 
				anIcon.iconSize = new GSize(anIcon_X,anIcon_Y);
				anIcon.shadowSize = new GSize(anShadowIcon_X,anShadowIcon_Y);
				// set the anchor to the middle of the icon
				anIcon.iconAnchor = new GPoint(20,22);
				anIcon.infoWindowAnchor = new GPoint(20,20);
				break;
				
			case "OSM":
				var size = new OpenLayers.Size(anIcon_X,anIcon_Y);
				var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
				anIcon = new OpenLayers.Icon(anIconName,size,offset);
				break;
			
			default:
				break;
		}
		return anIcon;
	},
	addMarker:function(aMarker)
	{
		switch(this.myEngine)
		{
			case "google":
				this.myMap.addOverlay(aMarker);
				break;
				
			case "OSM":
				this.layerMarkers.addMarker(aMarker);
				break;
			
			default:
				break;
		}
	},
	changeMarker:function(aMarker, aPosition)
	{
		switch(this.myEngine)
		{
			case "google":
				aMarker.setPoint(aPosition);
				break;
				
			case "OSM":
				aMarker.lonlat = aPosition;
				this.layerMarkers.redraw();
				break;
			
			default:
				break;
		}
	},
	createLatLong:function(aLatitude, aLongitude)
	{
		switch(this.myEngine)
		{
			case "google":
				return new GLatLng(aLatitude, aLongitude);
				break;
				
			case "OSM":
				return new OpenLayers.LonLat(aLongitude, aLatitude).transform(new OpenLayers.Projection("EPSG:4326"), this.myMap.getProjectionObject());
				break;
				
			default:
				return null;
				break;
		}
	},
	// adding a polyline out of an array of points
	addPolyLine:function(pointsArray)
	{
		switch(this.myEngine)
		{
			case "google":
				this.myMap.clearOverlays();
				var myPolyLine = new GPolyline(pointsArray,"#0000ff",3);
				this.myMap.addOverlay(myPolyLine);
				
				// center and zoom to the bounding box
				this.myMap.setCenter(myPolyLine.getBounds().getCenter(), this.myMap.getBoundsZoomLevel(myPolyLine.getBounds()));
				break;
				
			case "OSM":
				this.layerVectors.destroyFeatures();
				// add this point-array as an layer to the map
				// but convert it before into the OSM-geometry-points
				var points = [];
				for (var i=0; i < pointsArray.length; i++)
				{
					point = new OpenLayers.Geometry.Point(pointsArray[i].lon, pointsArray[i].lat);
					points.push(point);
				}
				var geometry = new OpenLayers.Geometry.LineString(points);
				var feature = new OpenLayers.Feature.Vector(geometry, null, 
				{
					strokeColor: "#0033ff",
					strokeOpacity: 0.7,
					strokeWidth: 3
				});
				this.layerVectors.addFeatures([feature]);
				
				// center and zoom to the bounding box
				this.myMap.setCenter(geometry.getBounds().getCenterLonLat(), this.myMap.zoomToExtent(geometry.getBounds()));
				break;
				
			default:
				return null;
				break;
		}
	}
}

