/**
* @class
* Controls behaviour for showing directions to a central destination from various travel points (a.k.a a "how to find us" map).
*
* The controller is configured with options for creating markers, limbs and directions.
*
* Transport links (origins of travel to the destination) are then added using the addTransportLink method. Custom
* travel options can be supplied to override the default options that were set via the constructor, allowing
* each transport link to use a different icon, travel mode, etc.
*
* @constructor
* @param {lucid.maps.limbs.DirectionsControllerOptions} options Options for the default behaviour of this controller.
*/
lucid.maps.limbs.DirectionsController = function( options )
{
var map;
var limbMarkerFactory;
var directionsRenderer;
// This initialise function is called at the end of the constructor.
function init()
{
map = options.map;
var markerOptions = { clickHandlerFactory: defaultClickHandlerFactory };
if (typeof options.markerOptions !== "undefined")
{
lucid.maps.limbs.applyMarkerOptions( markerOptions, options.markerOptions );
}
var limbOptions = { syncClick: true };
if (typeof options.limbOptions !== "undefined")
{
lucid.maps.limbs.applyLimbOptions( limbOptions, options.limbOptions );
}
var factoryOptions = { map: map,
markerOptions: markerOptions,
limbOptions: limbOptions };
limbMarkerFactory = new lucid.maps.limbs.LimbMarkerFactory( factoryOptions );
var directionsRendererOptions = { map: map,
hideRouteList: true,
routeIndex: 0,
draggable: false,
preserveViewport: false,
suppressMarkers: true,
suppressInfoWindows: true };
directionsRenderer = new google.maps.DirectionsRenderer( directionsRendererOptions );
}
/**
* @param {lucid.maps.limbs.TransportLinkOptions} travelOptions Options to override the default options passed into the factory's constructor.
* @returns {lucid.maps.limbs.Limb} The LIMB that was created for the new travel point.
*/
this.addTransportLink = function( travelOptions )
{
var customisedMarkerOptions = (typeof travelOptions.markerOptions === "undefined") ? {} : travelOptions.markerOptions;
var customisedLimbOptions = (typeof travelOptions.limbOptions === "undefined") ? {} : travelOptions.limbOptions;
var limb = limbMarkerFactory.addCustomised( customisedMarkerOptions, customisedLimbOptions );
var marker = limb.getTarget();
// Build-up the directions options from the raw defaults, the factory defaults and the options passed into this function.
// Attach those options to the marker so they can be accessed from the marker's click handler.
marker.directionsOptions = { origin: marker.getPosition(),
provideRouteAlternatives: false };
if (typeof options.directionOptions !== "undefined")
{
lucid.maps.limbs.applyDirectionsOptions( marker.directionsOptions, options.directionOptions );
}
if (typeof travelOptions.directionOptions !== "undefined")
{
lucid.maps.limbs.applyDirectionsOptions( marker.directionsOptions, travelOptions.directionOptions );
}
return limb;
};
/**
* @param {google.maps.Marker} marker The marker to create a click-handler for.
* @return {function} A function that handles the click on that marker.
*/
function defaultClickHandlerFactory( marker )
{
return function()
{
// TODO Raise pre event
hidePreviousRoute();
zoomToRoute( marker.getPosition(), marker.directionsOptions.destination );
new google.maps.DirectionsService().route( marker.directionsOptions, showRoute );
// TODO Raise waiting event
};
}
function hidePreviousRoute()
{
directionsRenderer.setMap( null );
}
function zoomToRoute( origin, destination )
{
var routeBounds = new google.maps.LatLngBounds();
routeBounds = routeBounds.extend( origin );
routeBounds = routeBounds.extend( destination );
map.fitBounds( routeBounds );
}
function showRoute( directions, status )
{
if (status == google.maps.DirectionsStatus.OK)
{
directionsRenderer.setDirections( directions );
directionsRenderer.setMap( map );
}
// TODO Raise post event
}
init();
};
/**
* @type {object}
* @property {google.maps.MarkerOptions} [markerOptions] Settings for the travel-point marker.
* @property {lucid.maps.limbs.LimbOptions} [limbOptions] Settings for the travel-point LIMB.
* @property {google.maps.DirectionsRequest} [directionOptions] Settings for the directions/route from this travel-point to the destination.
*/
lucid.maps.limbs.TransportLinkOptions = {};
/**
* @type {object}
* @augments lucid.maps.limbs.TransportLinkOptions
* @property {google.maps.Map} map The map that will show the travel points and directions.
*/
lucid.maps.limbs.DirectionsControllerOptions = {};