Source: maps/limbs/LimbMarkerPlacesFactory.js


/**
 * @class
 * Manages {lucid.maps.limbs.Limb}s for a set of markers.
 * This class will create the google.maps.Marker instance on the map as well as the associated LIMB.
 *
 * @constructor
 * @param {lucid.maps.limbs.LimbMarkerPlacesFactoryOptions} options  The factory options.
 */
lucid.maps.limbs.LimbMarkerPlacesFactory = function( options )
{
	lucid.maps.limbs.LimbMarkerFactory.apply( this, [options] );
	
	var super_ = { zoomToAll: this.zoomToAll,
	               add: this.add,
	               addCustomised: this.addCustomised };
	
	// The zoom level used when the user clicks for info on a place.
	// This is only used when the map is zoomed out to show all places.
	// If the user has zoomed in to a custom zoom level then their custom zoom is preserved in that instance.
	var selectPlaceZoomLevel;
	var zoomedToAll;
	
	
	// This initialise function is called at the end of the constructor.
	function init()
	{
		selectPlaceZoomLevel = (typeof options.zoomLevelWhenSelected === "undefined") ? 16 : options.zoomLevelWhenSelected;
		zoomedToAll = false;
		
		google.maps.event.addListener( options.map, "zoom_changed", handleZoomChanged );
	}
	
	
	function handleZoomChanged()
	{
		// The map is now at a user-chosen zoom level.
		zoomedToAll = false;
	}
	
	function configurePlacesMarker( limb, placeReference )
	{
		if (typeof placeReference !== "undefined")
		{
			limb.getTarget().placeReference = placeReference;
		}
	}
	
	/**
	 * Add a new marker and a LIMB to the map.
	 * The map instance and label styling are set in the options passed into the manager's constructor.
	 * 
	 * @param {google.maps.LatLng} position  The location to be marked.
	 * @param {string} title  The name/title of the location. Used as the title of the marker created on the map.
	 * @param {string} [placeReference]  Optionally associated the marker with a place using the place reference.
	 * @return {lucid.maps.limbs.Limb}  The limb that has been created.
	 */
	this.add = function( position, title, placeReference )
	{
		var limb = super_.add.apply( this, [position, title] );
		
		configurePlacesMarker( limb, placeReference );
		
		return limb;
	};
	
	/**
	 * Add a new marker and a LIMB to the map.
	 * The map instance and label styling are set in the options passed into the manager's constructor.
	 * 
	 * @param {google.maps.MarkerOptions} customisedMarkerOptions  Selected settings of the marker to be overriden from the options passed into the constructor.
	 * @param {lucid.maps.limbs.LimbOptions} customisedLimbOptions  Selected settings of the LIMB to be overriden from the options passed into the constructor.
	 * @param {string} [placeReference]  Optionally associate the marker with a place using the place reference.
	 * @return {lucid.maps.limbs.Limb}  The limb that has been created.
	 */
	this.addCustomised = function( customisedMarkerOptions, customisedLimbOptions, placeReference )
	{
		if (typeof customisedMarkerOptions.clickHandlerFactory === "undefined")
		{
			customisedMarkerOptions.clickHandlerFactory = defaultClickHandlerFactory;
		}
		
		var limb = super_.addCustomised.apply( this, [customisedMarkerOptions, customisedLimbOptions] );
		
		configurePlacesMarker( limb, placeReference );
		
		return limb;
	};

	function defaultClickHandlerFactory( marker )
	{
		return function()
		{
			if (zoomedToAll === true)
			{
				if (selectPlaceZoomLevel != null)
				{
					options.map.setZoom( selectPlaceZoomLevel );
				}
				// else: the zoom is turned off
			}
			// else: keep the map at the user-chosen zoom level
			
			if (typeof options.infoBox === "undefined")
			{
				options.map.setCenter( marker.getPosition() );
			}
			// else: The info box will appear when the marker is clicked.
			//       Let the map be centred around the info box.
		}
	}
	
	/**
	 * Zoom and pan the map so that all markers are in view.
	 * You can optionally specify additional locations to be included in the map view by setting LatLng in the options parameter.
	 *
	 * @param {object} zoomOptions
	 * @param {google.maps.LatLng[]} [zoomOptions.additionalLocations]  Locations, in addition to the markers, which should be kept in view when the map view is changed.
	 */
	this.zoomToAll = function( zoomOptions )
	{
		super_.zoomToAll.apply( this, [zoomOptions] );
		
		zoomedToAll = true;
	};
	
	
	init();
};


/**
 * @type {object}
 * @augments lucid.maps.limbs.LimbMarkerFactoryOptions
 * @property {number} [zoomLevelWhenSelected]  The zoom level to be used when a marker is clicked.
 *                                             Set this to null if you do not want the zoom to change.
 *                                             Defaults to 16 if not defined.
 */
lucid.maps.limbs.LimbMarkerPlacesFactoryOptions = {};