/*
* Summary:
* Estate.GoogleMaps returns an object that you can use to create a Google map.
* you provide the object with a configuration object. You can choose to either
* add a single location (by setting the config object) or a bunch of locations
* by providing an URL to an xml file. If both are supplied the xml file rules
* out the single location.
* 
* Usage:
// START HTML
<div id="map"></div>
<div id="route"></div>
		
<asp:TextBox ID="saddrWatermark" runat="server" TabIndex="100" ValidationGroup="route"></asp:TextBox>
<ajaxToolkit:TextBoxWatermarkExtender runat="server" TargetControlID="saddrWatermark" WatermarkText="Bv. Beursplein 5, Amsterdam" />
<input type="button" value="Bereken route" tabindex="101" validationgroup="route" onclick="Estate.GoogleMaps.Route.GetRoute()" />
// END HTML
	
// START JAVASCRIPT EXAMPLE 1 show one location
var mapConfig = {
mapId: 'map',
mapKeys: {
published: '[keystring]',
ontwikkelOnline: '[keystring]',
ontwikkelLocal: '[keystring]'
},
startLocation: {
lng: 5.09206,
lat: 51.57459,
zoom: 13,
text: 'Estate Internet'
}
}
		
Estate.Events.AddEvent(
window,
function() {
oMap = new Estate.GoogleMaps( mapConfig, "oMap" )
oMap.Init()
},
"onload"
)
// END JAVASCRIPT EXAMPLE 1 
	
// START JAVASCRIPT EXAMPLE 2 show multiple locations
var mapConfig = {
mapId: 'map',
mapKeys: {
published: '[keystring]',
ontwikkelOnline: '[keystring]',
ontwikkelLocal: '[keystring]'
},
locationsUrl: '/scripts/data/googleMaps-locations.xml',
}
		
Estate.Events.AddEvent(
window,
function() {
oMap = new Estate.GoogleMaps( mapConfig, "oMap" )
oMap.Init()

oMap2 = new Estate.GoogleMaps( mapConfig2, "oMap2" )
oMap2.Init()
},
"onload"
)
// END JAVASCRIPT EXAMPLE 2

// START JAVASCRIPT EXAMPLE 3: show route
// Javascript: set click event on submit button
Estate.GoogleMaps.Route.GetRoute()
// ASP.NET codebehind: set enter event on textbox
ClientScript.RegisterOnSubmitStatement(Me.GetType(), "submit", "return Estate.GoogleMaps.Route.GetRoute();")
// END JAVASCRIPT EXAMPLE 3
*/
Estate.GoogleMaps = (function() {
	var Class = function() {
		/* START PRIVATE */
		var map;
		var mgrOptions = { maxZoom: 12 };
		var markers = [];
		var selectedMarker = {
			lat: 0,
			lng: 0
		};
		var config = {
			instanceName: '',
			mapId: 'map',
			mapKeys: {
				published: 'ABQIAAAABhsGdFqRSZLtKMbwb0G6lRS0nA7aFcGPxhdAysLbj-5ppIhPEhTtkkynmkqDi-Gj7IY7IUMBawU2cw',
				ontwikkelOnline: 'ABQIAAAABhsGdFqRSZLtKMbwb0G6lRSYXvHlgCc05Uq_VtbIwHDB8MGLWBSnn-dte0D0HuxCHkFbhGc5_LvCDg',
				ontwikkelLocal: 'ABQIAAAAG5WUaecVNzLY9j5mq4mcghRZTrm1GtmLAkijwR04PrkluHZfdBQUWQTcXl4lJL1kK8YpMIXYsGuncA',
				fallback: 'ABQIAAAAwzwUIGbrJwzzTe8UohabdxRl-GQNXsR9AaQxfhYXa6OzFRFLkBSTVJ51rEwEh2XBTV8U9rE4Z_7j7Q',
				local: 'ABQIAAAAbkoIvuYAMaGoR1QIMP5TYhSCjl7-nQ3Zm1mCDdShEvo-jO_MahSrm3gjLHjKYaX4HYGov6fcy6qZXA'
			},
			mapConfig: {
				zoomControl: 'large',
				mapTypeControl: true,
				zoomBounds: {
					minimum: 7,
					maximum: 17
				},
				zoomScrollwheel: false
			},
			startLocation: {
				lng: 5.05543,
				lat: 51.66361,
				zoom: 11,
				text: ''
			},
			locationsUrl: '',
			markerImage: {
				url: '',
				dimensions: {
					width: '37',
					height: '31'
				},
				anchor: {
					xPosition: -1,
					yPosition: -1
				}
			},
			routeId: "route",
			routeNoDestination: "Selecteer eerst een bestemming voordat u een route kunt berekenen",
			textLoading: 'Bezig met laden kaart...',
			textBrowserIncompatible: 'Uw browser ondesteunt geen Google Maps of is zodanig ingesteld dat het niet ondersteunt.'
		}



		/* start getters, setters and checkers */
		function SetConfig(newConfig, instanceName) {
			var error
			error = Estate.Check.ArgumentsCount(arguments.length, [1, 2]);
			if (error != "") throw new Error(error);

			config.instanceName = instanceName;
			Estate.Check.UpdateLiteral(config, newConfig)
		}

		function GetKey() {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);

			if (document.location.href.indexOf("ontwikkel.estate.nl") > 0 || document.location.href.indexOf("potemkin.estate.nl") > 0) {
				return config.mapKeys.ontwikkelLocal;
			} else if (document.location.href.indexOf("82.201.123.97") > 0) {
				return config.mapKeys.fallback;
			} else if (document.location.href.indexOf("galaxy.estate.nl") > 0 || document.location.href.indexOf("odyssey.estate.nl") > 0) {
				return config.mapKeys.ontwikkelOnline;
			} else if (document.location.href.indexOf("://casade") > 0) {
				return config.mapKeys.local;
			} else {
				return config.mapKeys.published;
			}
		}

		function MapKeysExists() {
			var error
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);

			if (config.mapKeys.published == '') {
				return false;
			}
			if (config.mapKeys.ontwikkelOnline == '') {
				return false;
			}
			if (config.mapKeys.ontwikkelLocal == '') {
				return false;
			}
			return true
		}

		function IsLibraryLoaded() {
			if (typeof (GBrowserIsCompatible) == 'undefined') {
				return false;
			}
			return true;
		}
		/* end getters, setters and checkers */



		function LoadGoogleMapsLibrary() {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);
			if (MapKeysExists() == false) {
				throw new Error("Google Maps library not loaded and cannot be loaded dynamically.");
			}

			var script = document.createElement("script");
			script.type = "text/javascript";
			script.src = "http://maps.google.com/maps?file=api&v=2.x&key=" + GetKey() + "&async=2&callback=" + config.instanceName + ".Init";
			document.body.appendChild(script);


		}

		function MapAddMarker(oGLatLng, locationText, configMarkerImage, locationsType) {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 4);
			if (error != "") throw new Error(error);

			var newMarker = CreateMarker(oGLatLng, configMarkerImage);
			newMarker.markertype = configMarkerImage.type;
			markers.push(newMarker);
			map.addOverlay(newMarker);

			var newMarkerLatLng = newMarker.getLatLng()
			selectedMarker.lat = newMarkerLatLng.lat()
			selectedMarker.lng = newMarkerLatLng.lng()
			if (locationsType == "multiple locations") {
				GEvent.addListener(
					newMarker,
					"click",
					function() {
						switch (configMarkerImage.clickaction) {
							case 'clickPlaats':
								config.locationsUrl = "/sitecore/content/Global-Content/Plaatsen.aspx?scitem=" + configMarkerImage.scitem;
								map.clearOverlays()
								LoadExternalData(config.locationsUrl)
								var plaatsId = configMarkerImage.scitem;
								plaatsId = plaatsId.replace(/[^\w|\d]/gi, "");
								Casade.PopupMap.ClickMapPlaats(jQuery("#plaats" + plaatsId));
								break;
							case 'clickWijk':
								config.locationsUrl = "/sitecore/content/Global-Content/Plaatsen.aspx?scitem=" + configMarkerImage.scitem;
								map.clearOverlays();
								LoadExternalData(config.locationsUrl);
								var plaatsId = configMarkerImage.parentitem;
								plaatsId = plaatsId.replace(/[^\w|\d]/gi, "");
								jQuery("#def" + plaatsId).load("/sitecore/content/Global-Content/Plaatsen.aspx?a=1&scitem=" + configMarkerImage.scitem)
								break;
							default:
								var myTitel = "<h2 class=\"heading5\">" + configMarkerImage.titel + "</h2>";
								var mySubTitel = "<h3><img src=\"" + configMarkerImage.icon + "\" alt=\"" + configMarkerImage.type + "\">&nbsp;" + configMarkerImage.type + "</h3>";
								if (locationText != "") {
									map.openInfoWindowHtml(newMarker.getLatLng(), "<div class='infoWindowLarge'>" + myTitel + mySubTitel + locationText + "</div>", {maxWidth:300} );
								}
								else {
									map.openInfoWindowHtml(newMarker.getLatLng(), "<div class='infoWindowDefault'>" + myTitel + mySubTitel + "</div>", {maxWidth:300} );
								}
								break;
						}
					}
				);
			} else {
				if (locationText != '') {
					newMarker.openInfoWindowHtml(locationText);
				}
			}
		}

		function CreateMarker(oGLatLng, configMarkerImage) {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 2);
			if (error != "") throw new Error(error);

			var newMarker;
			if (configMarkerImage.url != '') {
				// Create custom marker if available
				var markerIcon = new GIcon();
				markerIcon.image = configMarkerImage.url;
				if (configMarkerImage.dimensions) {
					markerIcon.iconSize = new GSize(configMarkerImage.dimensions.width, configMarkerImage.dimensions.height);
					markerIcon.infoWindowAnchor = new GPoint(Math.floor(configMarkerImage.dimensions.width / 2), 0);
				}
				else {
					markerIcon.infoWindowAnchor = new GPoint(16, 39);
				}
				if (configMarkerImage.anchor) {

					if (configMarkerImage.anchor.xPosition >= 0 && configMarkerImage.anchor.yPosition >= 0) {
						markerIcon.iconAnchor = new GPoint(configMarkerImage.anchor.xPosition, configMarkerImage.anchor.yPosition);
					} else {
						markerIcon.iconAnchor = new GPoint(Math.floor(configMarkerImage.dimensions.width / 2), configMarkerImage.dimensions.height);
					}
				} else {
					markerIcon.iconAnchor = new GPoint(16, 39);
				}

				return new GMarker(oGLatLng, markerIcon);
			} else {
				return new GMarker(oGLatLng);
			}
		}

		function MapSetZoomBounds() {
			var mapTypes = map.getMapTypes();
			for (var i = 0; i < mapTypes.length; i++) {
				mapTypes[i].getMinimumResolution = function() { return config.mapConfig.zoomBounds.minimum; }
				mapTypes[i].getMaximumResolution = function() { return config.mapConfig.zoomBounds.maximum; }
			}
		}

		function LoadExternalData(locationsUrl) {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 1);
			if (error != "") throw new Error(error);
			markers = [];
			if (locationsUrl != '') {
				var point;
				var locationTextCollection;
				var location;
				var bounds = new GLatLngBounds();
				GDownloadUrl(locationsUrl, function(data, responseCode) {
					var xml = GXml.parse(data);
					var niveau = xml.documentElement.getElementsByTagName("niveau");
					var kaartniveau = '';
					if (niveau.length > 0) {
						kaartniveau = niveau[0].getAttribute("kaartniveau")
		}
	
					var markers = xml.documentElement.getElementsByTagName("marker");
					for (var i = 0; i < markers.length; i++) {
						var lat = parseFloat(markers[i].getAttribute("lat"));
						var lng = parseFloat(markers[i].getAttribute("lng"));
						var myClickaction = markers[i].getAttribute("clickaction");
						var locationText = GXml.value(markers[i].getElementsByTagName("locationText")[0]);
						if (!(isNaN(lat) || isNaN(lng))) {
							point = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
							bounds.extend(point);
							if ((('wijk' == kaartniveau) && (myClickaction != 'clickWijk')) || ('wijk' != kaartniveau)) {


								markerText = markers[i].getAttribute("icon");

								if (markerText == '') {
									markerText = config.markerImage;
								}
								else {
									markerText = {
										url: '' + markerText,
										scitem: markers[i].getAttribute("scitem"),
										parentitem: markers[i].getAttribute("parentitem"),
										clickaction: markers[i].getAttribute("clickaction"),
										titel: markers[i].getAttribute("titel"),
										type: markers[i].getAttribute("type"),
										icon: markers[i].getAttribute("informatieicon")
									};
								}
								if ("showinfo" == markers[i].getAttribute("clickaction")) {
									locationText = GXml.value(markers[i].getElementsByTagName("omschrijving")[0]);
									locationText = locationText.replace(/<!\[CDATA\[/, "");
									locationText = locationText.replace(/\]\]>/, "");
								}
								MapAddMarker(point, locationText, markerText, "multiple locations");
							}
						}

						var Polyline = markers[i].getElementsByTagName("polyline")[0];
						if (Polyline) {
							var PolyPoints = [];
							var polypoint;
							var strpolypoint = "";
							for (var cnt = 0; cnt < Polyline.getElementsByTagName("point").length; cnt++) {
								polypoint = GLatLng.fromUrlValue(GXml.value(Polyline.getElementsByTagName("point")[cnt]))

								if ('wijk' == kaartniveau) {
									PolyPoints.push(polypoint);
								}
								strpolypoint = strpolypoint + " | " + polypoint;
								bounds.extend(polypoint);
							}
							var mypolyline = new GPolyline(PolyPoints, "#cc9933", 5);
							map.addOverlay(mypolyline);
						}
						var wijkInfo = markers[i].getElementsByTagName("wijkinfo")[0];
						if (('wijk' == kaartniveau) && wijkInfo) {
							jQuery("#OverlayWijk").show();
							var wijkInfo = {
								titel: markers[i].getAttribute("titel"),
								wijkcijfer: wijkInfo.getAttribute("wijkcijfer"),
								eengezinswoningen: wijkInfo.getAttribute("eengezinswoningen"),
								etagewoningenZonderLift: wijkInfo.getAttribute("etagewoningenZonderLift"),
								etagewoningenMetLift: wijkInfo.getAttribute("etagewoningenMetLift"),
								seniorenwoningen: wijkInfo.getAttribute("seniorenwoningen"),
								huurwoningen: wijkInfo.getAttribute("huurwoningen"),
								koopwoningen: wijkInfo.getAttribute("koopwoningen"),
								wijkomschrijving: GXml.value(wijkInfo.getElementsByTagName("omschrijving")[0])
							}
							FillWijkOmschrijving(wijkInfo);
						}



					}
					jQuery("#OverlayWijk").css("left", "-210px");
					jQuery("#HidePanel").removeClass("hidePanelFoldOut");
					jQuery("#HidePanel").addClass("hidePanelFoldOut");
					if ('wijk' == kaartniveau) {
						jQuery("#OverlayWijk").show();
					}
					else {
						jQuery("#OverlayWijk").hide();
						jQuery("#Info").hide();


					}
					ZoomAndCenterOnAllMarkers(bounds);
				});
			}
		}

		function FillWijkOmschrijving(wijkInfo) {
			var wijkcijfers = jQuery("#wijkcijfers")
			wijkcijfers.empty();
			if (wijkInfo.eengezinswoningen) {
				wijkcijfers.append("<tr><th scope=\"row\">" + wijkInfo.eengezinswoningen + "</th><td>eengezinswoningen</td></tr>");
			}
			if (wijkInfo.etagewoningenZonderLift) {
				wijkcijfers.append("<tr><th scope=\"row\">" + wijkInfo.etagewoningenZonderLift + "</th><td>eengezinswoningen</td></tr>");
			}
			if (wijkInfo.etagewoningenMetLift) {
				wijkcijfers.append("<tr><th scope=\"row\">" + wijkInfo.etagewoningenMetLift + "</th><td>eengezinswoningen</td></tr>");
			}
			if (wijkInfo.seniorenwoningen) {
				wijkcijfers.append("<tr><th scope=\"row\">" + wijkInfo.seniorenwoningen + "</th><td>eengezinswoningen</td></tr>");
			}
			var divHuurkoopverhouding = jQuery("#huurkoopverhouding");
			var divHuurkoopverhoudingLabel = jQuery("#huurkoopverhoudinglabel");
			divHuurkoopverhouding.empty();
			if (wijkInfo.huurwoningen || wijkInfo.koopwoningen) {
				if (parseInt("0" + wijkInfo.huurwoningen, 10) == 0) {
					verhouding = 0;
				} else {
					if (parseInt("0" + wijkInfo.koopwoningen, 10) == 0) {
						verhouding = 100;
					} else {
						hw = parseInt("0" + wijkInfo.huurwoningen, 10);
						verhouding = parseInt((hw * 100) / (parseInt("0" + wijkInfo.huurwoningen, 10) + parseInt("0" + wijkInfo.koopwoningen, 10)), 10);
					}
				}
				divHuurkoopverhouding.append("<div style=\"width: " + verhouding + "%\">" + verhouding + "%&nbsp;</div>");
				divHuurkoopverhouding.css("display", "block");
				divHuurkoopverhoudingLabel.css("display", "block");
			} else {
				divHuurkoopverhouding.css("display", "none");
				divHuurkoopverhoudingLabel.css("display", "none");
			}
			var divInfocontent = jQuery("#infocontent");
			divInfocontent.empty();
			wijkInfo.wijkomschrijving = wijkInfo.wijkomschrijving.replace(/<!\[CDATA\[/, "");
			wijkInfo.wijkomschrijving = wijkInfo.wijkomschrijving.replace(/\]\]>/, "");
			if (wijkInfo.wijkomschrijving) {
				divInfocontent.append("<h2 class=\"heading12\">" + wijkInfo.titel + "</h2>")
				divInfocontent.append(wijkInfo.wijkomschrijving)
			}


		}

		function ZoomAndCenterOnAllMarkers(bounds) {
			map.setZoom(map.getBoundsZoomLevel(bounds));
			map.setCenter(bounds.getCenter());

			Estate.Events.AddEvent(
				window,
				function() {
					map.setZoom(map.getBoundsZoomLevel(bounds));
					map.setCenter(bounds.getCenter());
				},
				"onresize"
			)
		}

		function AddControls() {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);


			if (typeof (config.mapConfig.zoomControl) == "string") {
				switch (config.mapConfig.zoomControl) {
					case "large":
						map.addControl(new GLargeMapControl());
						break;
					case "small":
						map.addControl(new GSmallMapControl());
						break;
					case "smallest":
						map.addControl(new GSmallZoomControl());
						break;
				}
			}
			if (typeof (config.mapConfig.mapTypeControl) == "boolean") {
				if (config.mapConfig.mapTypeControl == true) {
					map.addControl(new GMapTypeControl());
				}
			}
		}

		function CreateMap() {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);

			if (GBrowserIsCompatible()) {
				Estate.Events.AddEvent(window, GUnload, "onunload")
				map = new GMap2(document.getElementById(config.mapId));
				if (config.startLocation) {
					var startLocation = new GLatLng(config.startLocation.lat, config.startLocation.lng);
					map.setCenter(startLocation, config.startLocation.zoom);
				} else {
					map = new GMap2(document.getElementById(config.mapId));
				}


				AddControls()
				if (typeof (config.mapConfig.zoomScrollwheel) == "boolean") {
					if (config.mapConfig.zoomScrollwheel == true) {
						map.enableScrollWheelZoom();
					}
				}
				MapSetZoomBounds();

				if (config.locationsUrl != '') {
					LoadExternalData(config.locationsUrl);
				} else {
					MapAddMarker(startLocation, config.startLocation.text, config.markerImage, "single location");
				}
			} else {
				alert(config.textBrowserIncompatible);
			}
		}
		/* END PRIVATE */



		/* START PUBLIC */
		return function(newConfig, instanceName) {
			var error
			error = Estate.Check.ArgumentsCount(arguments.length, 2);
			if (error != "") throw new Error(error);
			error = Estate.Check.LiteralUpdatable(config, newConfig);
			if (error != "") throw new Error(error);

			SetConfig(newConfig, instanceName);

			this.Init = function() {
				if (IsLibraryLoaded() == false) {
					LoadGoogleMapsLibrary();
				} else {
					Estate.Events.AddEvent(document, GUnload, "onunload")
					CreateMap();
				}
			},

			this.LoadExternalData = function(newConfig) {
				var error
				error = Estate.Check.ArgumentsCount(arguments.length, 1);
				if (error != "") throw new Error(error);
				error = Estate.Check.VariableType(newConfig, "object");
				if (error != "") throw new Error(error);
				error = Estate.Check.VariableType(newConfig.locationsUrl, "string");
				if (error != "") throw new Error(error);
				if (config.locationsUrl == '') {
					throw new Error("URL string is empty!")
				}

				SetConfig(newConfig)
				map.clearOverlays()
				LoadExternalData(config.locationsUrl)
			},

			this.SetSimpleZoom = function(zoomLevel) {
				var error
				error = Estate.Check.ArgumentsCount(arguments.length, 1);
				if (error != "") throw new Error(error);
				error = Estate.Check.VariableType(zoomLevel, "number");
				if (error != "") throw new Error(error);

				map.setZoom(zoomLevel)
			},
			this.ToggleType = function(markertype) {

				for (var m = 0; m < markers.length; m++) {
					if (markertype == markers[m].markertype) {
						if (markers[m].isHidden()) {
							markers[m].show()
						}
						else {
							markers[m].hide()
						}
						//						alert(markers[m].isHidden());							
					}

				}


			},

			this.GetRoute = function(routeId, startLocation) {
				var error
				error = Estate.Check.ArgumentsCount(arguments.length, 2);
				if (error != "") throw new Error(error);
				error = Estate.Check.ElementById(routeId);
				if (error != "") throw new Error(error);
				error = Estate.Check.VariableType(startLocation, "string");
				if (error != "") throw new Error(error);

				if (selectedMarker.lat == 0 || selectedMarker.lng == 0) {
					alert(config.routeNoDestination)
				}

				map.closeInfoWindow()
				Estate.GoogleMaps.Route.Init(routeId, startLocation, map, selectedMarker.lat, selectedMarker.lng)

				return false
			}
		}
		/* END PUBLIC */
	} ()

	return Class;
})();






/* Code for makeing a route */
Estate.GoogleMaps.Route = (function() {
	/* START PRIVATE */
	var routePanel;
	/* END PRIVATE */



	/* START PUBLIC */
	return {
		Init: function(routeId, startLocation, map, lat, lng) {
			var error
			error = Estate.Check.ArgumentsCount(arguments.length, 5);
			if (error != "") throw new Error(error);
			error = Estate.Check.ElementById(routeId);
			if (error != "") throw new Error(error);

			_routeId = routeId
			routePanel = document.getElementById(routeId);
			routePanel.innerHTML = ""
			Estate.CSSTools.RemoveClass(routePanel, "displayNone")
			var directions = new GDirections(map, routePanel);
			GEvent.addListener(directions, "error", Estate.GoogleMaps.Route.ShowStatusError);
			directions.clear()
			directions.load("from: " + startLocation + " to: " + lat + ", " + lng);
		},

		ShowStatusError: function() {
			alert('Route kan niet geladen worden. Misschien heeft u geen geldig adres ingevoerd.')
			Estate.CSSTools.AddClass(routePanel, "displayNone")
		},

		GetRouteInGoogleMaps: function(destinationAddress, startAddress) {
			window.open("http://maps.google.nl/maps?daddr=" + escape(destinationAddress) + "&geocode=&dirflg=&saddr=" + escape(startAddress) + "&f=d&sspn=0.010732,0.022488&ie=UTF8")
		}
	}
})();

