// -----------------------------------------------------------------------
// C L A S S   DKGoogleMap
// -----------------------------------------------------------------------

var DKGOOGLEMAP_API_LOADED = false;
var DKGOOGLEMAP_GOOGLE_API_VERSION = '2.113';
var DKGOOGLEMAP_SRC = 'http://maps.google.com/maps?file=api&amp;v=' + DKGOOGLEMAP_GOOGLE_API_VERSION;

var DKGOOGLEMAP_DEFAULT_LATITUDE = '47.07412615053965';
var DKGOOGLEMAP_DEFAULT_LONGITUDE = '15.439953804016113';
var DKGOOGLEMAP_DEFAULT_ZOOMLEVEL = 14;

function DKGoogleMap() {
	this.map = null;
	this.geocoder = null;
	this.gdir = null;
	this.gdir_language = null;
	this.apiKeyMap = {};
	this.addedMarkers = [];
}


DKGoogleMap.prototype.registerApiKey = function(domain, apiKey) {
	this.apiKeyMap[domain] = apiKey;
}


DKGoogleMap.prototype.init = function() {
	var loc = document.location.host;
	if (this.apiKeyMap[loc] && DKGOOGLEMAP_API_LOADED == false) {
		document.write('<script type="text/javascript" src="' + DKGOOGLEMAP_SRC + '&amp;key=' + this.apiKeyMap[loc] + '"><\/script>\n');
		DKGOOGLEMAP_API_LOADED = true;
	} else {
		alert('error: no api key found for domain ' + loc);
	}
}


DKGoogleMap.prototype.loadMap = function(mapContainerId, centerOnLat, centerOnLng, centerOnZoomLevel, enableScrollWheelZoom) {
	if (GBrowserIsCompatible()) {
		this.map = new GMap2(document.getElementById(mapContainerId));
		this.geocoder = new GClientGeocoder();
		centerOnZoomLevel = parseInt(centerOnZoomLevel);
		if ((typeof(centerOnLat) === 'undefined' || !centerOnLat) && (typeof(centerOnLng) === 'undefined' || !centerOnLng) && !centerOnZoomLevel) {
			// Graz is default: 47.07412615053965, Lng: 15.439953804016113
			centerOnLat = DKGOOGLEMAP_DEFAULT_LATITUDE;
			centerOnLng = DKGOOGLEMAP_DEFAULT_LONGITUDE;
			centerOnZoomLevel = DKGOOGLEMAP_DEFAULT_ZOOMLEVEL;
		}
		this.map.setCenter(new GLatLng(parseFloat(centerOnLat), parseFloat(centerOnLng)), centerOnZoomLevel);
		var _oldUnloadStuff = window.onunload;
		window.onunload = function() {
			if (_oldUnloadStuff) {
				_oldUnloadStuff();
			}
			GUnload();
		}
		if (typeof(enableScrollWheelZoom) === 'undefined' || enableScrollWheelZoom) {
			this.enableScrollWheelZoom();
		}
	}
}


DKGoogleMap.prototype.enableScrollWheelZoom = function(continuousZoom) {
	this.map.enableScrollWheelZoom();
	if (continuousZoom == true) {
		this.map.enableContinuousZoom();
	}
	// adding hook in IE (prevent page scroll)
	this.map.getContainer().onmousewheel = function(e) {
		if (!e) {
			e = window.event
		}
		if (e.preventDefault) {
			e.preventDefault()
		}
		e.returnValue = false;
	}
	// adding hook in FireFox and opera (prevent page scroll)
	GEvent.addDomListener(this.map.getContainer(), "DOMMouseScroll", this.map.getContainer().onmousewheel);
}

DKGoogleMap.prototype.getCenter = function() {
	return this.map.getCenter();
}

DKGoogleMap.prototype.geocode = function(searchStr, callbackFunc) {
	if (typeof(this.geocoder) === 'undefined') {
		alert('Error: Geocoder is not initialized!');
		return;
	}
	if (typeof(callbackFunc) === 'undefined') {
		//Default callback function: simple add marker
		var _tmpMap = this.map;
		callbackFunc = function(point) {
			if (!point) {
				alert(searchStr + " konnte nicht gefunden werden.");
			} else {
				var _tmpMarker = new GMarker(point);
				_tmpMap.addOverlay(_tmpMarker);
				GEvent.addListener(_tmpMarker, "click", function() {
					var p = _tmpMarker.getPoint();
					_tmpMarker.openInfoWindowHtml(searchStr + "\nLat: " + p.lat() + "\nLng: " + p.lng());
				});
			}
		}
	}
	if (typeof(searchStr) !== 'undefined' && typeof(callbackFunc) !== 'undefined') {
		this.geocoder.getLatLng(searchStr, callbackFunc);
	}
}

DKGoogleMap.prototype.addMarker = function(point, markerOptions) {
	if (typeof(markerOptions) === 'undefined') {
		markerOptions = {};
	}
	if (typeof(point) !== 'undefined') {
		var _tmpMarker = new GMarker(point, markerOptions);
		this.map.addOverlay(_tmpMarker);
		this.addedMarkers.push(_tmpMarker);
		return _tmpMarker;
	}
}

DKGoogleMap.prototype.addMapLocationMarker = function(point, title, tooltip, text, markerOptions) {
	if (typeof(markerOptions) === 'undefined') {
		markerOptions = {};
	}
	if (typeof(tooltip) !== 'undefined' && tooltip) {
		markerOptions.title = tooltip;
	} else if (typeof(title) !== 'undefined' && title) {
		markerOptions.title = title;
	}
	var marker = new GMarker(point, markerOptions);
	if (typeof(text) !== 'undefined' && text) {
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml(text);
		});
	}
	this.map.addOverlay(marker);
	this.addedMarkers.push(marker);
	return marker;
}

DKGoogleMap.prototype.centerOnMarkerBoundingBox = function() {
	if (typeof(this.addedMarkers) !== 'undefined' && this.addedMarkers.length > 0) {
		if (this.addedMarkers.length == 1) {
			this.map.setZoom(12);
			this.map.panTo(this.addedMarkers[0].getPoint());
		} else {
			var bbox = new GLatLngBounds();
			for (var i=this.addedMarkers.length; i--; ) {
				bbox.extend(this.addedMarkers[i].getPoint());
			}
			var zl = this.map.getBoundsZoomLevel(bbox);
			zl = zl > 0 ? zl - 1 : zl;
			this.map.setZoom(zl);
			this.map.panTo(bbox.getCenter());
		}
	}	
}


DKGoogleMap.prototype.clearMap = function() {
	this.map.clearOverlays();
}


DKGoogleMap.prototype.clearOverlays = function() {
	return this.map.clearOverlays();
}

DKGoogleMap.prototype.removeOverlay = function(overlay) {
	return this.map.removeOverlay(overlay);
}

DKGoogleMap.prototype.addOverlay = function(overlay) {
	return this.map.addOverlay(overlay);
}

DKGoogleMap.prototype.closeInfoWindow = function() {
	return this.map.closeInfoWindow();
}


DKGoogleMap.prototype.initDirections = function(attachToMap, directionPanelId, lang) {
	if (this.map == null) {
		alert('Map must be initialized before using "DKGoogleMap.initDirections(...)"!\nUse: DKGoogleMap.loadMap(...);');
		return;
	}
	if (typeof(attachToMap) == 'undefined') {
		attachToMap = false;
	}
	if (typeof(lang) === 'undefined' || !lang) {
		lang = 'de';
	}
	if (this.gdir == null) {
		this.gdir = new GDirections((attachToMap ? this.map : null), (typeof(directionPanelId)!='undefined' ? document.getElementById(directionPanelId) : null));
		GEvent.bind(this.gdir, "load", this, this.handleGDirOnLoad);
		this.gdir_language = lang;
		if (this.gdir_language.toLowerCase() == 'de') {
			GEvent.bind(this.gdir,"error",this,this.handleGDirErrorsDE);			
		} else {
			GEvent.bind(this.gdir,"error",this,this.handleGDirErrorsEN);
		}
	}
}


DKGoogleMap.prototype.loadDirectionStrings = function(fromAddress, toAddress) {
	if (this.gdir != null) {
		this.map.clearOverlays();
		this.gdir.load("from: "+fromAddress+" to: "+toAddress, {"locale":this.gdir_language});
	}
}


DKGoogleMap.prototype.loadDirectionFromWaypoints = function(startPoint, endPoint, betweenPointsArr) {
	// Graz: Lat: 47.07412615053965, Lng: 15.439953804016113     -> startPoint = 'Graz@47.07412615053965,15.439953804016113';
	// Wien: Lat: 48.209206, Lng: 16.372778
	// Saalfelden: Lat: 47.424690305619905, Lng: 12.856879234313965
	if (this.gdir != null) {
		if (typeof(betweenPointsArr) === 'undefined') {
			betweenPointsArr = [];
		}
		betweenPointsArr.unshift(startPoint);
		betweenPointsArr.push(endPoint);
		if (betweenPointsArr.length >= 2) { //at least 2 points are necessary
			this.map.clearOverlays();
			this.gdir.loadFromWaypoints(betweenPointsArr, {"locale":this.gdir_language});
			//DEMO call: this.gdir.loadFromWaypoints(['Graz@47.07412615053965,15.439953804016113','Saalfelden@47.424690305619905,12.856879234313965','Wien@48.209206,16.372778'],{"locale":this.gdir_language});
		} else {
			alert('Error: Cannot calculate route with ' + betweenPointsArr.length + ' locations.\nAt least 2 locations are necessary!');
		}
	}
}


DKGoogleMap.prototype.handleGDirOnLoad = function() {
	this.map.addOverlay(this.gdir.getPolyline());
}


DKGoogleMap.prototype.handleGDirErrorsEN = function() {
	alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.");
	return;
	if (this.gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS) {
		alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + this.gdir.getStatus().code);
	} else if (this.gdir.getStatus().code == G_GEO_SERVER_ERROR) {
		alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + this.gdir.getStatus().code);
	} else if (this.gdir.getStatus().code == G_GEO_MISSING_QUERY) {
		alert("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.\n Error code: " + this.gdir.getStatus().code);
	} else if (this.gdir.getStatus().code == G_GEO_BAD_KEY) {
		alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + this.gdir.getStatus().code);
	} else if (this.gdir.getStatus().code == G_GEO_BAD_REQUEST) {
		alert("A directions request could not be successfully parsed.\n Error code: " + this.gdir.getStatus().code);
	} else {
		alert("An unknown error occurred.\n Error code: " + this.gdir.getStatus().code);
	}
}


DKGoogleMap.prototype.handleGDirErrorsDE = function() {
	alert("Die gesuchte Adresse konnte leider nicht gefunden werden. Vielleicht handelt es sich um eine neue Adresse, die noch nicht von unserem System erfasst wurde.");
}


// returns the pixel(x,y) coords (in MAP DIV) according to the current map settings
// returns a GPoint obj
DKGoogleMap.prototype.getPoint = function(latlng) {
	return this.map.fromLatLngToDivPixel(latlng);
}


DKGoogleMap.prototype.hideMapCopyright = function() {
	if (this.map != null) {
		var element = this.map.getContainer();
		if (typeof(element) != 'undefined') {
			var fiLstEL = element.firstChild;
			if (typeof(fiLstEL) != 'undefined') {
				var nextEL = fiLstEL.nextSibling;
				if (typeof(nextEL) != 'undefined') {
					// hiding map data copyright
					// ATTENTION if hiding -> problems with: openInfoWindow...
					nextEL.style.display = 'none';
				}
				nextEL = nextEL.nextSibling;
				if (typeof(nextEL) != 'undefined') {
					// hiding google icon
					nextEL.style.display = 'none';
				}
			}
		}
	}
}


DKGoogleMap.prototype.loadLargeMapControl = function() {
	if (this.map != null) {
		this.map.addControl(new GLargeMapControl());
	}
}


DKGoogleMap.prototype.loadSmallMapControl = function() {
	if (this.map != null) {
		this.map.addControl(new GSmallMapControl());
	}
}


DKGoogleMap.prototype.loadSmallZoomControl = function() {
	if (this.map != null) {
		this.map.addControl(new GSmallZoomControl());
	}
}


DKGoogleMap.prototype.loadMapTypeControl = function() {
	if (this.map != null) {
		this.map.addControl(new GMapTypeControl());
	}
}


DKGoogleMap.prototype.loadScaleControl = function() {
	if (this.map != null) {
		this.map.addControl(new GScaleControl());
	}
}


DKGoogleMap.prototype.loadOverviewControl = function() {
	if (this.map != null) {
		this.map.addControl(new GOverviewMapControl());
	}
}


DKGoogleMap.prototype.loadControl = function(loadLargeMap, loadSmallMap, loadMapType, loadSmallZoom, loadScale, loadOverview) {
	if (loadLargeMap) this.loadLargeMapControl();
	if (loadSmallMap) this.loadSmallMapControl();
	if (loadMapType) this.loadMapTypeControl();
	if (loadSmallZoom) this.loadSmallZoomControl();
	if (loadScale) this.loadScaleControl();
	if (loadOverview) this.loadOverviewControl();
}

// -----------------------------------------------------------------------
