/*
 * Copyright (c) 2009, webvariants GbR, http://www.webvariants.de
 * 
 * Diese Datei steht unter der MIT-Lizenz. Der Lizenztext befindet sich in der 
 * beiliegenden LICENSE Datei und unter:
 * 
 * http://www.opensource.org/licenses/mit-license.php
 * http://de.wikipedia.org/wiki/MIT-Lizenz 
 * 
 */

/**
 * Google Mapper (JS)
 * 
 * Die Klasse WV15_GMapper erzeugt eine Google Map anhand einer speziellen, 
 * objektorientierten Datenstruktur, welche per PHP erzeugt und als JSON
 * an diese Klasse gesendet wird. Ziel ist es, die komplizierte API von 
 * Google zu abstrahieren und dabei den dynamisch generierten JavaScript-Output
 * zu minimieren.
 * 
 * @author     Gregor Aisch
 * @copyright  webvariants GbR, www.webvariants.de
 * 
 */

function WV15_GMapper(data) { 
	this._data = data;
	this._map = null;
	this._bounds = null;
}

WV15_GMapper.prototype.run = function() {
	var data = this._data;
	
	if (GBrowserIsCompatible()) {
		this._map = new GMap2(document.getElementById(data.mapId));
		var map = this._map;
		if (data.mapTypes) {
			if (data.mapTypes.selectedMapType) map.setMapType(eval(data.mapTypes.selectedMapType));
		}
		
		if (data.kmlFiles) {
			for (var i=0;i<data.kmlFiles.length;i++) {
				var geoXml = new GGeoXml(data.kmlFiles[i]);
				map.addOverlay(geoXml);
			}
		}
		
		map.setCenter(new GLatLng(parseFloat(data.mapCenter.lat), parseFloat(data.mapCenter.lng)), parseInt(data.mapZoom));
		
		if (data.mapBounds) {
			_bounds = new GLatLngBounds();
			_bounds.extend(new GLatLng(data.mapBounds[0].lat, data.mapBounds[0].lng));
			_bounds.extend(new GLatLng(data.mapBounds[1].lat, data.mapBounds[1].lng));
			map.setZoom(map.getBoundsZoomLevel(_bounds));
			map.setCenter(_bounds.getCenter());
		}
		
		if (data.marker) {
			for (i=0;i<data.marker.length;i++) {
				var mo = {};
				mo.icon = new GIcon();
				
				if (data.marker[i].icon) {
						if (data.marker[i].icon.image) {
						mo.icon.image = data.marker[i].icon.image;
					}
					mo.icon.iconAnchor = new GPoint(data.marker[i].icon.anchor.x, data.marker[i].icon.anchor.y);
				}
				if (data.marker[i].shadow) {
					mo.icon.shadow = data.marker[i].shadow.image;
					mo.icon.infoShadowAnchor = new GPoint(data.marker[i].shadow.anchor.x, data.marker[i].shadow.anchor.y);
				} 
				if (data.marker[i].window) {
					mo.icon.infoWindowAnchor = new GPoint(data.marker[i].window.anchor.x, data.marker[i].window.anchor.y);						
				}
				var m = new GMarker(new GLatLng(data.marker[i].coordinates.lat, data.marker[i].coordinates.lng), mo);
				m.wv_content = data.marker[i].window.content;
				if (data.marker[i].window) {
					if (data.marker[i].window.type == 'html') {
						GEvent.bind(m, "click", m, this.markerClick);
					 }
				}
				map.addOverlay(m);
			}
		}
		if (data.controls && map.setUI) {
			map.removeControl(new GMapTypeControl());
			map.removeControl(new GHierarchicalMapTypeControl());
			
			var customUI = map.getDefaultUI();
			customUI.controls.largemapcontrol3d = data.controls.largeMapControl3D;
			customUI.controls.smallzoomcontrol3d = data.controls.smallZoomControl3D;
			customUI.controls.maptypecontrol = data.controls.mapTypeControl;
			customUI.controls.menumaptypecontrol = data.controls.menuMapTypeControl;
			customUI.controls.scalecontrol = data.controls.scaleControl;
			
			if (data.controls.largeMapControl) map.addControl(new GLargeMapControl());
			if (data.controls.smallMapControl) map.addControl(new GSmallMapControl ());
			if (data.controls.smallZoomControl) map.addControl(new GSmallZoomControl());
			if (data.controls.hierarchicalMapTypeControl) map.addControl(new GHierarchicalMapTypeControl());
			if (data.controls.overviewMapControl) map.addControl(new GOverviewMapControl ());

			if (data.mapTypes) {
				customUI.maptypes.normal = data.mapTypes.normal;
				customUI.maptypes.satellite = data.mapTypes.satellite;
				customUI.maptypes.hybrid = data.mapTypes.hybrid;
				customUI.maptypes.physical = data.mapTypes.physical;
			}
			
			map.setUI(customUI);
		}

	}
}

WV15_GMapper.prototype.markerClick = function(point) {
	this.openInfoWindowHtml(this.wv_content);
}

WV15_GMapper.prototype.showRoute = function(fromAddress, toAddress, detailsContainer, statusContainer, onComplete) {
	if (!this._gdir) {
		this._routeDetails = detailsContainer;
		this._routeStatus = statusContainer;
		this._routeComplete = onComplete;
		this._gdir = new GDirections(this._map, detailsContainer);
		GEvent.bind(this._gdir, "load", this, this.showRouteComplete);
		GEvent.bind(this._gdir, "error", this, this.showRouteError);
	}
	this._gdir.load("from: " + fromAddress + " to: " + toAddress, { "locale": 'de' });
}

WV15_GMapper.prototype.showRouteComplete = function() {
	if (this._gdir) {
		this._routeStatus.update('<p>Der Anfahrtsweg wurde berechnet und wird in einem neuen Fenster geöffnet.</p>');
		// prototype depency
		this._routeDetails.show();
		window.setTimeout(this._routeComplete, 500);
	}
}

WV15_GMapper.prototype.showRouteError = function() {
	this._routeDetails.hide();
	var gdir = this._gdir; 
	if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
		this._routeStatus.update("<p>Für die eingegebene Adresse wurde keine geografische Position gefunden. Die Ursache könnte darin liegen, dass die Adresse noch sehr neu ist oder einfach ein Tippfehler vorliegt. Sie könnten versuchen die Adresse genauer zu definieren (z.B. indem Sie die Postleitzahl hinzufügen o.ä.).</p>") ;
	else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
		this._routeStatus.update("<p>A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.</p>") ;
	else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
		this._routeStatus.update("<p>The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.</p>");
//  else if (gdir.getStatus().code == G_UNAVAILABLE_ADDRESS)  <--- Doc bug... this is either not defined, or Doc is wrong
//     alert("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + gdir.getStatus().code);
	else if (gdir.getStatus().code == G_GEO_BAD_KEY)
		this._routeStatus.update("<p>The given key is either invalid or does not match the domain for which it was given.</p>") ;
	else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
	   this._routeStatus.update("<p>A directions request could not be successfully parsed.</p>");
	else     
	this._routeStatus.update("<p>Ein unbekannter Fehler ist aufgetreten.</p>");

}
