﻿
HumanReadable = {
	geocoderAccuracy: {
		0: "locatie onbekend",
		1: "land",
		2: "provincie",
		3: "gemeente",
		4: "stad",
		5: "postcode",
		6: "straat",
		7: "kruising",
		8: "adres",
		9: "gebouw"
	},
	geocoderErrors: {
		200: "Success",
		400: "Ongeldige aanvraag",
		500: "Serverfout (Google Maps server)",
		601: "Coordinaten kloppen niet",
		602: "Er kan geen adres gevonden worden",
		603: "Er kan geen adres gevonden worden",
		604: "Geen route tussen deze punten",
		610: "De Google Maps-key is ongeldig",
		620: "Adresinformatie is te vaak opgevraagd"
	}
}

function buildMarkerLink(color, letter) {
	var prepend = document.location.pathname.toLowerCase().match("desktopmodules") != null ? "../" : "";
	return prepend + "images/icons/" + color + "_Marker" + letter + ".png";
}

function googleMapMarker(Parent) {
	this.parent = Parent;
}

googleMapMarker.prototype = {
	parent: null,
	actualMarker: null,
	isSet: false,
	isTracked: true,
	icon: null,
	gicon: null,
	idLetter: "A",
	Name: "",
	eventUnhook: null,
	tredsID: 0,
	setIcon: function(iconstring) {
		this.icon = iconstring;
		if (iconstring != null)
			this.gicon = new GIcon(G_DEFAULT_ICON, iconstring);
		else
			this.gicon = G_DEFAULT_ICON;
		if (this.actualMarker != null)
			this.actualMarker.setImage(this.gicon.image);
	},
	setMarkerLocation: function(latlong) {
		if (this.actualMarker == null) {
			if (this.icon != null)
				this.gicon = new GIcon(G_DEFAULT_ICON, this.icon);
			else
				this.gicon = G_DEFAULT_ICON;
			this.parent.map.addOverlay(this.actualMarker = new GMarker(latlong, this.gicon));
			var This = this;
			this.eventUnhook = GEvent.addListener(this.actualMarker, "click", function() {
				This.click();
			});
		}
		else
			this.actualMarker.setLatLng(latlong);
		this.isSet = true;
	},
	click: function() {
		this.parent.focusMarker(this);
	},
	unload: function() {
		if (this.eventUnhook != null)
			GEvent.removeListener(this.eventUnhook);
		if (this.actualMarker != null)
			this.parent.map.removeOverlay(this.actualMarker);
	}
}

function GoogleMap(mapElement, kaderElement, Settings, wijzigmodus) {
	var This = this;
	this.controls = [];
	this.Settings = Settings;
	this.kaderDiv = kaderElement;
	this.geohtml = "";
	this.melding();
	this.wijzigmodus = wijzigmodus;
	this.markers = [];
	this.gpsmarkers = [];
	this.gpsDevices = [];
	this.deviceStates = [];

	if (mapElement == null)
		return;

	if (GBrowserIsCompatible()) {
		this.map = new GMap2(mapElement);
		this.map.enableScrollWheelZoom();
		this.map.enableContinuousZoom();

		// GMenuMapTypeControl - kaart selectie dropdown control
		// GNavLabelControl - Geintegreerde kaart-geocoder
		if (Settings.toonOverzichtsKaart) {
			var control = new GOverviewMapControl();
			this.controls.push(control);
			this.map.addControl(control);
		}

		if (Settings.showMapTypeControl) {
			var control = new GMapTypeControl();
			this.controls.push(control);
			this.map.addControl(control);
		}

		if (Settings.toonSchaal) {
			var control = new GScaleControl();
			this.controls.push(control);
			this.map.addControl(control);
		}

		if (Settings.control) {
			var control = eval("new " + Settings.control + "()");
			this.controls.push(control);
			this.map.addControl(control);
		}

		var control = this.butans = new GMarkerCustomControl(this);
		this.controls.push(control);
		this.map.addControl(control);
		this.map.setMapType(eval(Settings.defaultMapView));
		if (Settings.magSlepen)
			this.map.enableDragging();
		else
			this.map.disableDragging();

		for (i = 0; i < Settings.markers.length; ++i) {
			markinfo = Settings.markers[i];
			_marker = this.markers[markinfo.name] = new googleMapMarker(this);
			_marker.setIcon(buildMarkerLink(Settings.markerStatic, markinfo.idLetter));
			_marker.isTracked = markinfo.isTracked;
			_marker.idLetter = markinfo.idLetter;
			_marker.Name = markinfo.name;

			if (markinfo.tredsID != 0) {
				_marker.tredsID = markinfo.tredsID;
				this.gpsDevices.push(markinfo.tredsID);
				this.gpsmarkers[markinfo.tredsID] = _marker;
				_marker.setIcon(buildMarkerLink(Settings.markerOffline, markinfo.idLetter));
			}

			if (markinfo.hasStatic)
				_marker.setMarkerLocation(new GLatLng(markinfo.latitude, markinfo.longitude));
			this.butans.addMarker(_marker);
		}

		if (Settings.centerOnMarkers)
			this.centerMap();
		else this.map.setCenter(new GLatLng(Settings.lengtegraad, Settings.breedtegraad), Settings.zoom);

		if (Settings.toonGPSlocatie != undefined) {
			switch (Settings.toonGPSlocatie.toLowerCase()) {
				case "tekstkader":
					this.showKader = true;
					break;
				case "tekstballon":
					this.showBallon = true;
					break;
			}
		}

		if (Settings.toonGPSmarker == true) {
			var createGPS = function() {
				if (This.createGPSClient())
					return;
				setTimeout(createGPS, 500);
			};

			if (this.showKader || this.showBallon) {
				this.geocoder = new GClientGeocoder();
				createGPS();
			}
			//this.GPSInfoReceived({ Latitude: Settings.lengtegraad, Longitude: Settings.breedtegraad });
			//this.geoteller = 999;
		}

		if (Sys) {
			this.aspAjaxUnloader = function() {
				This.unload();
				Sys.WebForms.PageRequestManager.getInstance().remove_pageLoading(This.aspAjaxUnloader);
			}
			Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(this.aspAjaxUnloader);
		}

		if (Settings.selectedMarker)
			this.focusMarker(this.markers[Settings.selectedMarker]);
	}

	this.init = false;
}

GoogleMap.prototype = {
	focusedMarker: null,
	butans: null,
	init: true,
	map: null,
	marker: null,
	geocoder: null,
	mapmanager: null,
	pline: null,
	//geoteller: 10,
	geoinfo: null,
	geohtml: null,
	Settings: null,
	showBallon: false,
	showKader: false,
	controls: null,
	aspAjaxUnloader: null,
	kaderDiv: null,
	deviceStates: null,
	gpsDevices: null,
	gpsmarkers: null,
	markers: null,
	selectedMarker: null,
	gpsClient: null,
	wijzigmodus: false,
	klikeventhandler: null,
	mousemoveeventhandler: null,

	focusMarker: function(marker) {
		if (this.focusedMarker != null) {
			this.focusedMarker.setIcon(
				buildMarkerLink(
					this.focusedMarker.tredsID == 0 ?
						this.Settings.markerStatic : this.deviceStates[this.focusedMarker.tredsID] ? this.Settings.markerOnline : this.Settings.markerOffline,
					this.focusedMarker.idLetter));
		}
		if (this.focusedMarker == marker) {
			this.focusedMarker = null;
			this.geohtml = "";
			this.melding();
		} else {
			this.focusedMarker = marker;
			marker.setIcon(buildMarkerLink(this.Settings.markerSelected, marker.idLetter));
		}
		this.butans.updateFocus();
		this.centerMap();

		if (this.focusedMarker != null && marker.actualMarker != null) {
			var This = this;
			if (this.geocoder != null)
				this.geocoder.getLocations(marker.actualMarker.getLatLng(), function(response) { This.showAddress(response); });
			else This.showAddress("");
		}
	},
	createGPSClient: function() {
		if (!window.TReDS)
			return false;
		var This = this;
		if (this.gpsClient != null)
			return true;
		this.gpsClient = window.createNewGPSClient();
		if (this.gpsDevices != null)
			while (this.gpsDevices.length > 0)
			this.gpsClient.RegisteredDeviceIDs.push(this.gpsDevices.pop());
		this.gpsClient.GPSEvent = function(source, args) { This.GPSInfoReceived(args); };
		this.gpsClient.StateChangeEvent = function(source, args) { This.DeviceStateReceived(args); };
		window.TReDS.RegistreerGPSClient(this.gpsClient);
		return true;
	},
	DeviceStateReceived: function(apparaat) {
		this.deviceStates[apparaat.DeviceID] = apparaat.State;
		if (this.gpsmarkers[apparaat.DeviceID] != this.focusedMarker)
			this.gpsmarkers[apparaat.DeviceID].setIcon(
				buildMarkerLink(apparaat.State ? this.Settings.markerOnline : this.Settings.markerOffline, this.gpsmarkers[apparaat.DeviceID].idLetter)
		);
	},
	GPSInfoReceived: function(gpsPositie) {
		var This = this;
		var latlong = new GLatLng(gpsPositie.Latitude, gpsPositie.Longitude);
		this.gpsmarkers[gpsPositie.DeviceID].setMarkerLocation(latlong);
		this.centerMap();
		if (this.focusedMarker != null && this.focusedMarker.tredsID == gpsPositie.DeviceID && this.geocoder != null)
			this.geocoder.getLocations(latlong, function(response) { This.showAddress(response); });
		/*
		if (this.marker == null) {
		this.marker = new GMarker(latlong, new GIcon(G_DEFAULT_ICON));
		this.map.addOverlay(this.marker);
		} else
		this.marker.setLatLng(latlong);
		*/
		//this.map.panTo(latlong);
		//if (this.Settings.ToonRoute)
		//	this.setPolyline(latlong);
		//if (this.geocoder != null)
		//	this.geocoder.getLocations(latlong, function(response) { This.showAddress(response); });
	},
	centerMap: function() {
		var set = 0;
		var bounds = new GLatLngBounds();
		if (this.focusedMarker != null && this.focusedMarker.isSet) {
			bounds.extend(this.focusedMarker.actualMarker.getLatLng());
			set = 1;
		}
		else for (markerID in this.markers)
			if (this.markers[markerID].isSet && this.markers[markerID].isTracked) {
			bounds.extend(this.markers[markerID].actualMarker.getLatLng());
			++set;
		}
		var ratio = 0.05;
		var ne = bounds.getNorthEast();
		var sw = bounds.getSouthWest();
		var latsize = ne.lat() - sw.lat();
		var lngsize = ne.lng() - sw.lng();
		bounds.extend(new GLatLng(ne.lat() + latsize * ratio, ne.lng() + lngsize * ratio));
		bounds.extend(new GLatLng(sw.lat() - latsize * ratio, sw.lng() - lngsize * ratio));
		if (this.init) {
			if (set > 0)
				this.map.setCenter(bounds.getCenter(), set > 1 ? this.map.getBoundsZoomLevel(bounds) - 0 : this.Settings.zoom);
			else
				this.map.setCenter(new GLatLng(this.Settings.lengtegraad, this.Settings.breedtegraad), this.Settings.zoom);
		} else {
			if (set > 1)
				this.map.setZoom(this.map.getBoundsZoomLevel(bounds) - 0);
			if (set > 0)
				this.map.panTo(bounds.getCenter());
		}
	},
	setPolyline: function(latLong) {
		if (this.pline == null) {
			var point = new Array();
			point.push(latLong);
			this.pline = new GPolyline(point, "#FF0000");
			this.map.addOverlay(this.pline);
		} else {
			this.pline.insertVertex(this.pline.getVertexCount(), latLong);
			if (this.pline.getVertexCount() > 10)
				this.pline.deleteVertex(0);
		}
	},
	showAddress: function(response) {
		if (response == "") {
			this.toonGeoLocatie(this.Settings.markertekst);
			return;
		}
		if (!response || response.Status.code != 200) {
			this.geohtml = HumanReadable.geocoderErrors[response.Status.code];
			this.melding(this.geohtml);
		} else {
			this.geoinfo = response;
			var place = response.Placemark[0];
			var coordinaten = response.name.split(",");
			if (this.Settings.markertekst == null || this.Settings.markertekst == "") {
				this.geohtml = "<b>Positie: </b> " + coordinaten[0] + ", " + coordinaten[1] +
											 "<br/><b>Adres: </b> " + place.address + "<br/><b>Nauwkeurigheidsniveau</b>: " + HumanReadable.geocoderAccuracy[place.AddressDetails.Accuracy];
			} else {
				this.geohtml = this.Settings.markertekst;
				this.geohtml = this.geohtml.replace("{breedtegraad}", coordinaten[0]);
				this.geohtml = this.geohtml.replace("{lengtegraad}", coordinaten[1]);
				this.geohtml = this.geohtml.replace("{adres}", place.address.replace(", Nederland", ""));
				this.geohtml = this.geohtml.replace("{nauwkeurigheid}", HumanReadable.geocoderAccuracy[place.AddressDetails.Accuracy]);
			}
			this.toonGeoLocatie(this.geohtml);
		}
	},
	toonGeoLocatie: function(tekst) {
		if (this.showBallon) {
			if (this.focusedMarker != null)
				this.focusedMarker.actualMarker.openInfoWindowHtml(tekst);
		}
		if (this.showKader)
			this.melding(tekst);
	},
	melding: function(tekst) {
		if (this.kaderDiv != null) {
			if (tekst != undefined)
				this.kaderDiv.innerHTML = tekst;
			this.kaderDiv.style.display = this.kaderDiv.innerHTML.length == 0 || this.focusedMarker == null ? "none" : "block";
		}
	},
	unload: function() {
		if (window.TReDS && this.gpsClient) {
			window.TReDS.VerwijderGPSClient(this.gpsClient);
			this.gpsClient.GPSEvent = null;
			this.gpsClient = null;
			this.kaderDiv = null;
		}
		//if (this.klikeventhandler != undefined)
		//	GEvent.removeListener(this.klikeventhandler)
		//if (this.mousemoveeventhandler != undefined)
		//	GEvent.removeListener(this.mousemoveeventhandler)
		for (id in this.markers)
			this.markers[id].unload();
		for (var i = 0; i < this.controls.length; ++i)
			this.map.removeControl(this.controls[i]);
	}
}

function GMarkerCustomControl(parent) {
	this.gpsParent = parent;
	this.markers = new Array();
	this.focusd = new Array();
	this.ignoreNext = false;
}

GMarkerCustomControl.prototype = new GControl();
GMarkerCustomControl.prototype.initialize = function(map) {
	var This = this;
	var container = document.createElement("div");
	container.style.backgroundColor = "white";
	container.style.border = "1px solid black";
	container.style.padding = "2px";
	container.style.marginBottom = "3px";
	container.style.display = "none";
	GEvent.addDomListener(container, "mouseover", function() { This.setOpacity(100); });
	GEvent.addDomListener(container, "mouseout", function(e) {
		try {
			node = e.toElement;
			while (node != null) {
				if (node == container)
					return;
				node = node.parentNode;
			}
			//if(e.toElement.parentNode == e.fromElement)
			//  return;
		} catch (err) { }
		This.setOpacity(This.gpsParent.Settings.markerListOpacity);
	});
	map.getContainer().appendChild(container);
	this.container = container;
	this.setOpacity(this.currentOpacity = this.gpsParent.Settings.markerListOpacity);
	return container;
};

GMarkerCustomControl.prototype.setOpacity = function(opacity) {
	if (opacity == 100) {
		this.container.style.filter = "";
		this.container.style.opacity = "";
	} else {
		this.container.style.filter = "alpha(opacity=" + opacity + ")";
		this.container.style.opacity = opacity / 100;
	}
	this.currentOpacity = opacity;
}

GMarkerCustomControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(2, this.gpsParent.Settings.toonSchaal ? 38 : 0));
}

GMarkerCustomControl.prototype.addMarker = function(managedMarker) {
	var This = this;
	this.markers.push(managedMarker);
	var butan = document.createElement("div");
	butan.marker = managedMarker;
	butan.style.backgroundColor = managedMarker.isTracked ? "yellow" : "white";
	butan.style.border = "1px solid #6B6B6B";
	butan.style.padding = "2px";
	butan.style.paddingLeft = "4px";
	butan.style.paddingRight = "2em";
	butan.style.margin = "2px";
	butan.style.position = "relative";
	butan.style.cursor = "pointer";
	this.container.style.display = "block";
	var txt = document.createElement("span");
	txt.appendChild(document.createTextNode(managedMarker.idLetter + (managedMarker.idLetter != "" && managedMarker.Name != "" ? ": " : "") + managedMarker.Name));
	butan.appendChild(txt);
	this.container.appendChild(butan);
	var focus = document.createElement("img");
	focus.style.backgroundColor = this.gpsParent.focusedMarker == managedMarker ? "red" : "white";
	focus.style.position = "absolute";
	focus.style.right = "2px";
	focus.style.border = "1px solid #6B6B6B";
	focus.style.height = "1em";
	focus.style.width = "1em";
	focus.style.margin = "0px";
	focus.style.marginLeft = "5px";
	focus.style.marginRight = "1px";
	focus.style.cursor = "pointer";
	butan.appendChild(focus);
	GEvent.addDomListener(butan, "click", function() { This.persBUTAN(this, this.marker); });
	GEvent.addDomListener(focus, "click", function() { This.setFocus(this, this.parentNode.marker); });
	this.focusd.push(focus);
}

GMarkerCustomControl.prototype.updateFocus = function() {
	for (var i = 0; i < this.focusd.length; ++i)
		this.focusd[i].style.backgroundColor = this.gpsParent.focusedMarker == this.focusd[i].parentNode.marker ? this.gpsParent.Settings.markerSelected : "white";
	this.setOpacity(this.currentOpacity);
}

GMarkerCustomControl.prototype.persBUTAN = function(butan, marker) {
	if (this.ignoreNext) {
		this.ignoreNext = false;
		return;
	}
	marker.isTracked = !marker.isTracked;
	butan.style.backgroundColor = marker.isTracked ? "yellow" : "white";
	this.gpsParent.centerMap();
}

GMarkerCustomControl.prototype.setFocus = function(butan, marker) {
	this.ignoreNext = true;
	this.gpsParent.focusMarker(marker);
	//if(this.gpsParent.focusedMarker == marker)
	//	this.gpsParent.focusedMarker = null;
	//else
	//	this.gpsParent.focusedMarker = marker;
	//this.updateFocus();
	//for(var i = 0; i < this.focusd.length; ++i)
	//	this.focusd[i].style.backgroundColor = "white";
	//butan.style.backgroundColor = this.gpsParent.focusedMarker == marker? "red" : "white";
	//butan.style.backgroundColor = this.gpsParent.focusedMarker == marker? "red" : "white";
}
