if (Estate.Brandweer == undefined) {
	Estate.Brandweer = {}
}

/**
 * @fileOverview Copy of standard Google maps code
 * @author Wouter Bos
 * @since 1.0 - 2010-02-23
 * @version 1.0 - 2010-03-23
 */

/*
TODO:
	- Stop using startlocation when multiple locations are loaded
	- Convert to google maps V3
	- When using xml locations, the script always uses config.mapConfig.zoom as default level even when multiple locations are loaded

 * Usage:
	// START JAVASCRIPT EXAMPLE 1 show one location
		Estate.Events.AddEvent (
			document.getElementsByTagName('input')[0],
			function(e) {
				var KeyID = (window.event) ? event.keyCode : e.which;
				if (KeyID == 13) {
					Estate.Brandweer.GoogleMaps.Route.GetRouteInGoogleMaps( 'Vredesplein 5, Waalwijk', document.getElementById('saddr').value );
					return false;
				}
			},
			"onkeypress"
		)
	// END JAVASCRIPT EXAMPLE 1 	
 */
 
/**
 * @namespace  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. It is possible to have multiple maps on one
 *             page. In that case: make sure you have already loaded the library.
 * @requires Google Maps
 * @see ESDN for related HTML and CSS
 * @since 1.0 - 2010-02-23
 * @version 1.0 - 2010-03-16
 * @constructor
 *   
 * @example
 * // Simple map with one marker
 *	var mapConfig = {
 *		mapId: 'Map',
 *		mapKeys: [
 *			['www.domain.com', 'insert gmap key here'],
 *			['.local', 'insert gmap key here']
 *		],
 *		startLocation: {
 *			lng: 5.09206,
 *			lat: 51.57459,
 *			zoom: 13,
 *			text: 'Estate Internet'
 *		}
 *	}
 *	
 *	oMap = new Estate.Brandweer.GoogleMaps( mapConfig, "oMap" )
 *	oMap.Init()
 *
 * @example
 * // Map with markers from an XML
 *	var mapConfig = {
 *		mapId: 'Map',
 *		mapKeys: {
 *			['www.domain.com', 'insert gmap key here'],
 *			['.local', 'insert gmap key here']
 *		},
 *		locationsUrl: '/scripts/data/googleMaps-locations.xml'
 *	}
 *	
 *	oMap = new Estate.Brandweer.GoogleMaps( mapConfig, "oMap" )
 *	oMap.Init()
 *
 */
Estate.Brandweer.GoogleMaps = (function() {
	/**
	* The gallery class
	* @class
	* @constructs
	*/
	var Class = function() {
		var tooltip
		var mouseX = 0
		var mouseY = 0

		var bounds
		var map;
		var xmlData;
		var aMarkers = new Array(0);
		var selectedMarker = {
			lat: 0,
			lng: 0
		};

		var markerCluster = {
			url: '/images/googlemaps/cluster.png',
			dimensions: {
				width: '35',
				height: '40'
			},
			anchor: {
				xPosition: 17,
				yPosition: 40
			}
		}


		var config = {
			instanceName: '',
			mapId: 'Map',
			mapKeys: [
				['brandweermwb.nl', 'ABQIAAAAwzwUIGbrJwzzTe8UohabdxRfFb3G2CTyGme_2BWmYIoO-bTYyBSLhDsC_NJ6MkYRT2pkLR3Un743XA'],
				['restyle.brandweermwb.com', 'ABQIAAAAwzwUIGbrJwzzTe8UohabdxTBV9EF37Bcv4uJ7769U6ZMDmUm3BSX049nhV6ru4eUAyL_s4z1EPGtrQ'],
				['sitecore.brandweermwb.local', 'ABQIAAAAwzwUIGbrJwzzTe8UohabdxQX3afS29aYyho3D2_ynv6IpEJdbxTESjV-bjuzMN20lgYcy-EQ2MRJ4A'],
				['brandweermwb.potemkin.estate.nl', 'ABQIAAAAwzwUIGbrJwzzTe8UohabdxTb4fyGJIuomfig27mHYdUTLZSebRSFR9Xm2cVF8iglKaHe4ZFBiODCiw']
			],
			mapConfig: {
				zoomControl: 'large',
				mapTypeControl: true,
				zoom: null,
				zoomBounds: {
					minimum: 1,
					maximum: 17
				}
			},
			startLocation: {
				lng: 5.09206,
				lat: 51.57459,
				zoom: 17,
				text: ''
			},
			centerMapLocation: {
				lng: undefined,
				lat: undefined
			},
			locationsUrl: '',
			markerImage: {
				url: '',
				dimensions: {
					width: '37',
					height: '31'
				},
				anchor: {
					xPosition: -1,
					yPosition: -1
				}
			},
			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.',
			markerCluster: "Cluster",
			mapControl: "#MapControls",
			showLocationType: ['Brandweerkazerne']
		}



		/* 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)

			Estate.Brandweer.GoogleMaps.Check.CheckConfig(config)
		}

		function getKey() {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);

			var url = document.location.href;
			for (var i = 0; i < config.mapKeys.length; i++) {
				if (url.indexOf(config.mapKeys[i][0]) >= 0) {
					return config.mapKeys[i][1]
				}
			}
			return ''
		}

		function mapKeysExists() {
			var error
			error = Estate.Check.ArgumentsCount(arguments.length, 0);
			if (error != "") throw new Error(error);

			if (getKey() == '' && document.location.href.indexOf('//localhost') < 0) {
				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("Cannot find an appropriate Google Maps key for this domain.");
			}

			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 showTooltip(marker) {
			jQuery(tooltip).html(marker.tooltip);
			//var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
			//var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
			//var anchor=marker.getIcon().iconAnchor;
			//var width=marker.getIcon().iconSize.width;
			//var height = 20
			//console.log(offset.y +' - '+ point.y +' - '+ anchor.y)
			//var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize( (offset.x - point.x - anchor.x + jQuery("#Map").offset().left + 30), Math.floor(offset.y - point.y -anchor.y + jQuery("#Map").offset().top + 30) )); 
			var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize( Math.floor(mouseX + 10), Math.floor(mouseY + 10) )); 
			pos.apply(tooltip);
			jQuery(tooltip).show();
		}
		
		function mapAddMarker(oGLatLng, locationText, configMarkerImage, locationsType, locationType, locationTypeIndex) {
			var newMarker = createMarker(oGLatLng, configMarkerImage);
			newMarker.LocationText = locationText;
			newMarker.LocationType = locationType;
			newMarker.LocationTypeIndex = locationTypeIndex;
			if (newMarker.LocationType == config.markerCluster) {
				newMarker.tooltip = locationText
			}
			map.addOverlay(newMarker);
			var newMarkerLatLng = newMarker.getLatLng()
			if (locationsType == "multiple locations") {
				GEvent.addListener(
					newMarker,
					"click",
					function() {
						if (newMarker.LocationType != config.markerCluster) {
							if (newMarker.LocationText != '') {
								newMarker.openInfoWindowHtml(newMarker.LocationText);
							}
							map.panTo(newMarkerLatLng);
							selectedMarker.lat = newMarkerLatLng.lat();
							selectedMarker.lng = newMarkerLatLng.lng();
						} else {
							showHideMarkers("", newMarker.LocationTypeIndex)
						}
					}
				);
			} else {
				selectedMarker.lat = newMarkerLatLng.lat();
				selectedMarker.lng = newMarkerLatLng.lng();
				if (locationText != '') {
					newMarker.openInfoWindowHtml(locationText);
				}
			}
			var newMarkerId = aMarkers.length
			if (typeof (aMarkers[newMarkerId]) != "undefined") {
				newMarkerId += 1;
			}					
			aMarkers[newMarkerId] = newMarker;
			
			if (newMarker.LocationType == config.markerCluster) {
				GEvent.addListener(aMarkers[newMarkerId],"mouseover", function() {
					showTooltip(aMarkers[newMarkerId]);
				});        
				GEvent.addListener(aMarkers[newMarkerId],"mouseout", function() {
					jQuery(tooltip).hide();
				});
			}
		}

		function setControls(argStepIndex) {
			var stepIndex = argStepIndex || 0
			var sideBarContent = '';
			var clusters = ['Ambulancepost', 'Brandweerkazerne', 'Gemeentehuis', 'Meldkamer', 'Politiebureau']

			jQuery(config.mapControl).html('')
			
			if (stepIndex == 0) {
				sideBarContent =	"<h2>Clusters</h2>" +
									"<p>Klik op een cluster om alle locaties te vinden als kazernes, ambulanceposten, etc.</p>"
				jQuery(config.mapControl).html(sideBarContent)
			} else if (stepIndex == 1) {
				sideBarContent =	"<a class='back tag_back' href='javascript:void(0)'>terug naar clusters</a>" +
									"<h2>Cluster <strong></strong></h2>" +
									"<div class='filters tag_filters'><p>Toon: "
				var checked
				for (var i = 0; i < clusters.length; i++) {
					if (setFilterDefault(clusters[i]) == true) {
						checked = "checked='checked'"
					} else {
						checked = ""
					}
					sideBarContent += "<label><input type='checkbox' "+ checked +" value='"+ clusters[i] +"'> " + clusters[i] + "</label>"
				}
				sideBarContent +=	"</p></div>"
				
				jQuery(config.mapControl).html(sideBarContent)
				jQuery(config.mapControl).find("a.tag_back").click(function() {
					setControls(0);
					showHideMarkers(config.markerCluster)
				})
				jQuery(config.mapControl).find(":checkbox").change( function() { filterMap() } )
			}
		}
		
		function setFilterDefault(locationType) {
			for (var i = 0; i < config.showLocationType.length; i++) {
				if (config.showLocationType[i] == locationType) {
					return true
					break
				}
			}
			return false
		}
		
		function filterMap() {
			if (jQuery(config.mapControl).find(":checkbox").size() > 0) {
				var selectedLocations = new Array()
				//var bounds = new GLatLngBounds();
				jQuery(config.mapControl).find(":checkbox:checked").each(function(index) {
					selectedLocations[index] = jQuery(this).val()
				})
				for (var i = 0; i < aMarkers.length; i++) {
					aMarkers[i].hide()
					for (var ii = 0; ii < selectedLocations.length; ii++) {
						if (aMarkers[i].LocationType == selectedLocations[ii]) {
							aMarkers[i].show()
							//bounds.extend(aMarkers[i].getLatLng());
							break
						}
					}
				}
				//zoomAndCenterOnAllMarkers(bounds);
			}
		}

		function filterMapInit(marker) {
			if (jQuery(config.mapControl).find(":checkbox").size() > 0) {
				var selectedLocations = new Array()
				jQuery(config.mapControl).find(":checkbox:checked").each(function(index) {
					selectedLocations[index] = jQuery(this).val()
				})
				marker.hide()
				for (var ii = 0; ii < selectedLocations.length; ii++) {
					if (marker.LocationType == selectedLocations[ii]) {
						marker.show()
						break
					}
				}
			}
		}

		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;
				markerIcon.iconSize = new GSize(configMarkerImage.dimensions.width, configMarkerImage.dimensions.height);
				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);
				}
				markerIcon.infoWindowAnchor = new GPoint(Math.floor(configMarkerImage.dimensions.width / 2), 0);
				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 setMarkerImage(locationType) {
			switch (locationType) {
				case "Ambulancepost":
					return "/images/googlemaps/ico-ambulancepost-kaart.png";
				case "Brandweerkazerne":
					return "/images/googlemaps/ico-brandweerkazerne-kaart.png";
				case "Gemeentehuis":
					return "/images/googlemaps/ico-gemeentehuis-kaart.png";
				case "Meldkamer":
					return "/images/googlemaps/ico-meldkamer-kaart.png";
				case "Politiebureau":
					return "/images/googlemaps/ico-politiebureau-kaart.png";
				case "Cluster":
					return "/images/googlemaps/ico-cluster-kaart.png";
				default:
					return "/images/googlemaps/ico-cluster-kaart.png";
			}
		}

		function loadExternalData(locationsUrl) {
			var error;
			error = Estate.Check.ArgumentsCount(arguments.length, 1);
			if (error != "") throw new Error(error);

			if (locationsUrl != '') {
				var point;
				var locationTextCollection;
				var location;
				bounds = new GLatLngBounds();
				var clusterChilds;
				var markerImage = {};
				Estate.Brandweer.GoogleMaps.Check.CheckURL(locationsUrl)
				GDownloadUrl(locationsUrl, function(data, responseCode) {
					xmlData = GXml.parse(data);
					if (xmlData.documentElement.childNodes.length > 0) {
						// Add clusters
						for (var i = 0; i < xmlData.documentElement.childNodes.length; i++) {
							Estate.Check.UpdateLiteral(markerImage, markerCluster);
							markerImage.url = "/images/googlemaps/ico-cluster-kaart.png"
							point = new GLatLng(parseFloat(xmlData.documentElement.childNodes[i].getAttribute("lat")), parseFloat(xmlData.documentElement.childNodes[i].getAttribute("lng")));
							bounds.extend(point);
							locationText = xmlData.documentElement.childNodes[i].getAttribute("title");
							mapAddMarker(point, locationText, markerImage, "multiple locations", xmlData.documentElement.childNodes[i].getAttribute("type"), i);

							if (xmlData.documentElement.childNodes[i].childNodes.length > 0) {
								clusterChilds = xmlData.documentElement.childNodes[i].getElementsByTagName("marker")
								// Add childs of clusters
								for (var ii = 0; ii < clusterChilds.length; ii++) {
									markerImage.url = setMarkerImage(clusterChilds[ii].getAttribute("type"))
									point = new GLatLng(parseFloat(clusterChilds[ii].getAttribute("lat")), parseFloat(clusterChilds[ii].getAttribute("lng")));
									bounds.extend(point);
									locationText = GXml.value(clusterChilds[ii].getElementsByTagName("description")[0].firstChild);
									//if (clusterChilds[ii].getAttribute("link").length > 0) {
									//	locationText += "<p><a href='" + clusterChilds[ii].getAttribute("link") + "'>Meer informatie</a></p>"
									//}
									mapAddMarker(point, locationText, markerImage, "multiple locations", clusterChilds[ii].getAttribute("type"), ii);
								}
							}
						}
					}
					showHideMarkers(config.markerCluster)
				});
			}
		}

		function showHideMarkers(locationType, clusterIndex) {
			error = Estate.Check.ArgumentsCount(arguments.length, [1, 2]);
			if (error != "") throw new Error(error);

			bounds = new GLatLngBounds();
			var clusterCount = -1
			var clusterTitle = ""
			var i

			if (locationType == config.markerCluster) {
				setControls(0)
			} else if (locationType != config.markerCluster) {
				setControls(1)
			}
			
			for (i = 0; i < aMarkers.length; i++) {
				if (aMarkers[i].LocationType == config.markerCluster) {
					clusterCount++
				}
				if (aMarkers[i].LocationType == config.markerCluster && clusterIndex == clusterCount) {
					clusterTitle = aMarkers[i].LocationText
					jQuery(config.mapControl).find("h2 strong").text(clusterTitle)
				}
				
				if (aMarkers[i].LocationType == config.markerCluster && clusterIndex == undefined) {
					aMarkers[i].inCluster = true
					aMarkers[i].show();
				} else if (aMarkers[i].LocationType != config.markerCluster && clusterIndex == clusterCount) {
					aMarkers[i].inCluster = true
					filterMapInit(aMarkers[i])
				} else {
					aMarkers[i].inCluster = false
					aMarkers[i].hide();
				}
			}
			var infoWindow = map.getInfoWindow()
			infoWindow.hide()

			for (i = 0; i < aMarkers.length; i++) {
				if (aMarkers[i].inCluster == true) {
					bounds.extend(aMarkers[i].getLatLng());
				}
			}
			zoomAndCenterOnAllMarkers();
		}

		function zoomAndCenterOnAllMarkers() {
			Estate.Events.AddEvent(
				window,
				function() {
					map.setCenter(bounds.getCenter());
				},
				"onresize"
			)

			map.setCenter(bounds.getCenter());
			if (typeof (config.mapConfig.zoom) == "number") {
				map.setZoom(config.mapConfig.zoom);
			} else {
				map.setZoom(map.getBoundsZoomLevel(bounds));
				Estate.Events.AddEvent(
					window,
					function() {
						map.setZoom(map.getBoundsZoomLevel(bounds));
						map.setCenter(bounds.getCenter());
					},
					"onresize"
				)
			}
		}

		function setCenter(startLocation) {
			var centerPoint = startLocation
			if (typeof (config.centerMapLocation.lng) != "undefined" && typeof (config.centerMapLocation.lat) != "undefined") {
				centerPoint = new GLatLng(config.centerMapLocation.lat, config.centerMapLocation.lng);
			}
			map.setCenter(centerPoint, config.startLocation.zoom);
		}

		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")
				var startLocation = new GLatLng(config.startLocation.lat, config.startLocation.lng);

				map = new GMap2(document.getElementById(config.mapId));
				map.setCenter(startLocation, config.startLocation.zoom);
				addControls()
				map.enableScrollWheelZoom();
				mapSetZoomBounds();

				if (config.locationsUrl != '') {
					loadExternalData(config.locationsUrl);
				} else {
					mapAddMarker(startLocation, config.startLocation.text, config.markerImage, "single location");
				}
			} else {
				alert(config.textBrowserIncompatible);
			}
		}



		/* Start public */
		/**
		* Creates Google maps object
		*
		* @since 1.0 - 2010-02-23
		* @version 1.0 - 2010-02-23
		* @param {Object} [newConfig] Configuration object.
		* @param {String} [newConfig.instanceName] The name of the instance that is going to be created. You *must* provide this value if you haven't already loaded the Google library
		* @param {String} [newConfig.mapId] The id of the div that should contain the map  
		* @param {String[]} [newConfig.mapKeys] Different keys per domain. Each array item is an array itself with a piece of the domain and the google maps key. A simple example: [ ['www.domain.com', 'gmap key'] ]
		* @param {String} [newConfig.mapConfig.zoomControl] The type of zoom control on the map. Options are: "large", "small", "smallest"
		* @param {Boolean} [newConfig.mapConfig.mapTypeControl] Adds buttons on the map to switch between different map layers
		* @param {Number} [newConfig.mapConfig.zoom] Overrides default behaviour. If you load multiple locations an autozoom is used. Static zoom level. If the value is not null, that zoom level overrides the auto zoom level.
		* @param {Number} [newConfig.mapConfig.zoomBounds.minimum] Minimum zoom level
		* @param {Number} [newConfig.mapConfig.zoomBounds.maximum] Maximum zoom level
		* @param {Number} [newConfig.startLocation.lng] The longitude for a single location
		* @param {Number} [newConfig.startLocation.lat] The latitude for a single location
		* @param {Number} [newConfig.startLocation.zoom] The zoom for a single location
		* @param {Number} [newConfig.startLocation.text] The text in the text balloon
		* @param {String} [newConfig.centerMapLocation.lng] The longitude for the map center for a single location
		* @param {String} [newConfig.centerMapLocation.lat] The latitude for the map center for a single location 
		* @param {String} [newConfig.locationsUrl] The location of the XML with multiple locations
		* @param {String} [newConfig.markerImage.url] The url of the marker image of the location
		* @param {String} [newConfig.markerImage.dimensions.width] The width of the marker image
		* @param {String} [newConfig.markerImage.dimensions.height] The height of the marker image 
		* @param {String} [newConfig.markerImage.anchor.xPosition] x-position in the image where it should position on the position
		* @param {String} [newConfig.markerImage.anchor.yPosition] y-position in the image where it should position on the position
		* @param {String} [newConfig.routeNoDestination] Alerts user that no location is selected, so it's not possible to calculate a route 
		* @param {String} [newConfig.textLoading] Text that the user sees while the route is loading.
		* @see ESDN for related HTML and CSS
		* @example
		* var popupConfig = {
		*     animationSpeed: 250
		* }
		* var popup = new Estate.Popup(popupConfig);
		* popup.Open();
		*/
		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);
			
			jQuery("form:eq(0)").append("<div id='Tooltip' class='tooltip'>242</div>")
			tooltip = document.getElementById('Tooltip')
			jQuery(tooltip).css("cursor", "default")
			jQuery(tooltip).css("display", "none")
			jQuery(tooltip).css("position", "absolute")
			jQuery(tooltip).css("top", "0px")
			jQuery(tooltip).css("border", "1px solid #B2B2B2")
			jQuery(tooltip).css("padding", "2px 5px")
			jQuery(tooltip).css("white-space", "nowrap")
			jQuery(tooltip).css("background", "#ffffff")

			jQuery("#Map").mousemove(function(e){
				mouseX = e.pageX
				mouseY = e.pageY
			   }); 
			
			/**
			* Creates the Google maps and shows it on the page
			* @since 1.0 - 2010-02-23
			* @version 1.0 - 2010-02-23
			* @example
			* instance.Init()
			*/
			this.Init = function() {
				if (isLibraryLoaded() == false) {
					loadGoogleMapsLibrary();
				} else {
					Estate.Events.AddEvent(document, GUnload, "onunload")
					createMap();
				}
			},

			/**
			* Reloads external data through a new config object
			* @since 1.0 - 2010-02-23
			* @version 1.0 - 2010-02-23
			* @param
			* @example newConfig {Object} newConfig Holds new config object with at least a new URL to the XML
			* instance.LoadExternalData(newConfig)
			*/
			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()
				map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
				loadExternalData(config.locationsUrl)
			},

			/**
			* Center map on a specific marker that was loaded from the external XML 
			* @since 1.0 - 2010-02-23
			* @version 1.0 - 2010-02-23
			* @param
			* @example newConfig {Number} index The index of the item in the XML
			* instance.Goto(5)
			*/
			this.Goto = function(index) {
				var error
				error = Estate.Check.ArgumentsCount(arguments.length, 1);
				if (error != "") throw new Error(error);
				error = Estate.Check.VariableType(index, "number");
				if (error != "") throw new Error(error);

				map.panTo(aMarkers[index].getLatLng())
				aMarkers[index].openInfoWindowHtml(aMarkers[index].LocationText);
			},

			/**
			* Get route to the selected marker 
			* @since 1.0 - 2010-02-23
			* @version 1.0 - 2010-02-23
			* @param {String} routeId The id of the box the route will be loaded in. 
			* @param {String} startLocation The address of the start location. This is normally a value you get from a input form field.
			* @example 
			* instance.GetRoute("divId", "Fratershof 16, Oss")
			*/
			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.Brandweer.GoogleMaps.Route.Init(routeId, startLocation, map, selectedMarker.lat, selectedMarker.lng)

				return false
			}
		}
		/* End public */
	} ()

	return Class;
})();






/**
 * @namespace Methods for generating routes
 * @see ESDN for related HTML and CSS
 * @since 1.0 - 2010-02-23
 * @version 1.0 - 2010-02-23
 */
Estate.Brandweer.GoogleMaps.Route = ( function() {
	var routePanel;

	
	
	/* Start public */
	return {
	/**
	 * Generates route
	 *
	 * @since 1.0 - 2010-02-23
	 * @version 1.0 - 2010-02-23
	 * @param {String} routeId The Id of the element in which the route information will be loaded
	 * @param {String} startLocation The address of the start of the route
	 * @param {Object} map An instance of Estate.Brandweer.GoogleMaps
	 * @param {Number|String} lat The latitude of the destination 
	 * @param {Number|String} lng The longitude of the destination
	 * @example
	 * Estate.Brandweer.GoogleMaps.Route.Init("routeId", "Fratershof 16, Oss", oMap, 51.0, 51,0)
	 */
	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.Brandweer.GoogleMaps.Route.ShowStatusError );
        	directions.clear()
			directions.load("from: "+ startLocation +" to: " + lat + ", " + lng);
		},

		/**
		 * Handles error if Google maps cannot generate route
		 * @private
		 */
		ShowStatusError: function() {
			alert('Route kan niet geladen worden. Misschien heeft u geen geldig adres ingevoerd.')
			Estate.CSSTools.AddClass( routePanel, "displayNone" )
		},

		/**
		 * Loads route in the Google maps website in a new window
		 * @param {String} destinationAddress The address of the arrival location
		 * @param {String} startAddress The address of the start location
		 * @example
		 * Estate.Brandweer.GoogleMaps.Route.GetRouteInGoogleMaps()
		 */
		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")
		}
	}
	/* End public */
})();






/**
 * @namespace Some helper functions for checking
 * @ignore
 * @since 1.0 - 2010-02-23
 * @version 1.0 - 2010-02-23
 */
Estate.Brandweer.GoogleMaps.Check = ( function() {
	function httpRequest() {
		var obj;
		if (window.XMLHttpRequest) obj= new XMLHttpRequest(); 
		else if (window.ActiveXObject){
			try{
				obj= new ActiveXObject('MSXML2.XMLHTTP.3.0');
			}
			catch(er){
				try{
					obj= new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(er){
					obj= false;
				}
			}
		}
		return obj;
	}

	/* Start public */
	return {
		// Does some basic checking to see if the config variable is correct
		CheckConfig: function( config ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( config, "object" );
			if ( error != "" ) throw new Error( error );
			
			error = Estate.Check.ElementById( config.mapId );
			if ( error != "" ) throw new Error( error );			
			error = Estate.Check.VariableType( config.startLocation.lng, "number" );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( config.startLocation.lat, "number" );
			if ( error != "" ) throw new Error( error );
		},
		
		// Checks if an URL exists. This is used to check if the path to the XML is valid
		CheckURL: function( locationsUrl ) {
			var oHttpRequest = new httpRequest();
			oHttpRequest.open("HEAD", locationsUrl, false);
			oHttpRequest.send(null);		
			if (oHttpRequest.status != 200) {
				throw new Error( "Received an " + oHttpRequest.status +"-error while loading the URL '"+ locationsUrl +"'" )
			}
		}
	/* End public */
	}
})();

