﻿/**
 * GoogleMap class
 * Places a Google map with several options, among which displaying of route directions
 *
 * @author Klaas Dieleman, <klaas[AT]efocus.nl>
 * @since 26 jun 2010
 * @version 1.1
 * @copyright eFocus
 *
 * @uses jQuery 1.4.2, <http://www.jquery.com>
 *
 * @param jQuery-object; DOM-element in which to place Google map
 * @param object; options for customizing the layout of the map
 *
 */
function GoogleMap(placeHolder, options){
	
	if (GBrowserIsCompatible() && placeHolder.jquery && placeHolder.length > 0) {
	
		// get only the first DOM element within the given jquery object
		this.placeHolder = placeHolder.get(0);
		
		this.options = {
			addressToShow	: '',
			zoomLevel		: 14,
			mapType			: G_NORMAL_MAP,
			onGetDirections	: null
		};
		
		// implement given options
		if(typeof(options) == 'object') {
			for(i in this.options) {
			
				if(options[i] != undefined) {
					this.options[i] = options[i];
				}
			}
		}
	
		this.initialize();
		
	} else {
	
		return false;
	
	}
	
};

GoogleMap.prototype = {
	
	/**
	 * declares the GoogleMap and Geocoder from the Google API
	 */
	initialize: function() {
		
		this.map = new GMap2(this.placeHolder);
		new GClientGeocoder().getLatLng(this.options.addressToShow, jQuery.proxy(this.geoCoderCallback, this));
		
	},
	
	/**
	 * private method which handles the response from the Geocoder
	 *
	 * @param object; GPoint object of requested address
	 */
	geoCoderCallback: function(response) {
		
		// if Google can't find a valid address, center map on lat/long 0,0 and zoom out
		if(!response) {
			var response = new GLatLng(0,0);
			this.options.zoomLevel = 1;
		}
		
		this.showAddress(response);
		
	},
	
	/**
	 * private method which centers the map on the given address and places a marker
	 *
	 * @param object; GPoint object of requested address
	 */
	showAddress: function(point) {

		this.map.setCenter(point, this.options.zoomLevel);
		var marker = new GMarker(point);
			
		this.map.removeMapType(G_PHYSICAL_MAP);
		this.map.setMapType(this.options.mapType);
		this.map.addControl(new GLargeMapControl3D());
		this.map.addControl(new GMapTypeControl());
		this.map.addOverlay(marker);
			
	},
	
	/**
	 * function which triggers optional callback function onGetDirections(blnResult)
	 *
	 * @param boolean; true if Google returns valid directions, false if any error occurs
	 */
	onGetDirectionsHandler: function(blnResult) {
		if(this.options.onGetDirections) this.options.onGetDirections(blnResult);
	},
	
	/**
	 * public method which show a route on the map and textual directions for that route
	 *
	 * @param jQuery-object; DOM-element in which to place the textual directions
	 * @param string; starting address for route
	 * @param string; optional finishing address for route. If none given,
	 *                the currently shown address on the map is used.
	 */
	showDirections: function(placeHolder, fromAddress, toAddress) {
		
		if (placeHolder && placeHolder.jquery && placeHolder.length > 0) {
		
			// get only the first DOM element within the given jquery object
			placeHolder = placeHolder.get(0);
			toAddress = toAddress || this.options.addressToShow;
			if(!this.directions) this.directions = new GDirections(this.map, placeHolder);
			
			GEvent.addListener(this.directions, 'error', jQuery.proxy(function(event){
				GEvent.clearListeners(this.directions);
				this.onGetDirectionsHandler(false);
			}, this));
			
			GEvent.addListener(this.directions, 'load', jQuery.proxy(function(){
				GEvent.clearListeners(this.directions);
				this.onGetDirectionsHandler(true);
			}, this));
			
			this.directions.load('from: ' + fromAddress + ' to: ' + toAddress, {'locale': 'nl_NL'});
			
		} else {
		
			return false;
			
		}
	
	}
	
}