// YPGMapControl.js
// This file contains a wrapper class for the VEMap class exposing
// methods required by YPG for displaying maps and generating routes.
//
// To integrate this class include the following line of code in the head of
// the page that you want to add a VE Map to.
//
//<script type='text/javascript' src='<javascriptlibrary>/YPGMapControl.js'></script>
//
// where <javascriptlibrary> is the path of the directory containing the sites javascript.
//
// The following example shows an html page that displays a map, adds a customized pushpin
// indicating YPG's office, generates a route, and driving directions.  The MapResults Div holds the main
// map and the drivingDirections div displays the individual directions and maps specific to each direction.
//
//		<html xmlns="http://www.w3.org/1999/xhtml" >
//			<head>
//				<title>test.htm</title>
//				<link rel="stylesheet" type="text/css" href="http://www.yellowpages.ca/include/style.css" />
//				<script type='text/javascript' src='YPGMapControl.js'></script>
//				<script type='text/javascript'>
//
//					function initMap()
//					{
//						var map = new YPGMapControl("MapResults");
//						map.CreateAndLoadMap();
//						map.HideVEControls();
//						map.GetRoute("6 Chelton Drive, Richmond Hill, Ontario, L4E 4A9, Canada", "7 Beaverton Road North, Richmond Hill, Ontario, L4C 3J6, Canada");
//						map.DrivingDirectionsArea = "drivingDirections";
//						map.pushPinIcon = "questionLightYellow.gif";
//						map.AddLocation(43.790269, -79.233737, "Yellow Pages Group", "325 Milner Avenue", "Toronto", "Ontario", "M1B 5S8", "416.412.5702");
//
//					}
//				</script>
//			</head>
//			<body onload="initMap()">
//				<div id="MapResults" style="width:800px;height:400px; position:relative;"></div>
//				<div id="drivingDirections" style="width:800px;height:400px; position:relative;"></div>
//			</body>
//		</html>



//Inject the VE Map control tag into the page.
document.write("<script type='text/javascript' src='http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1&mkt=fr-FR'></script>");

// YPG VE Map Control
// This class wraps the VE Control and exposes methods to create, load, navigate and
// hide the VE Map controls.
// Constructor Parameter:   controlId   string  This is the id of the div element that
// the map is to be displayed in.
function YPGMapControl(controlId)
{
	//The map Id and the id of the div element that will hold the map.
	this.controlId = controlId;

	//This is the actual VEMap object.  It is accessable outside of the class but it is
	//preferrable to use the YPGMapControl methods as these are tailored to ypg's mapping
	//requirements.
	this.mapInstance = null;

	//This is the url of the image that will be used when a pushpin is added to the map
	//indicating a location of interest.
	this.pushPinIcon = null;

	//This is a VECustomIconSpecification to be applied to all pushpins being added
	//This can be overriden by passing the customIconSpecification parameter to AddLocation.
	this.customIconSpecification = null;

	//The unit of measure to be displayed on the map.
	this.distanceUnits = VEDistanceUnit.Kilometers;

	//This hides the intrinsic VE controls, displaying only the map.
	this.HideVEControls = function()
	{
		if (this.mapInstance != null)
		{
			this.mapInstance.HideDashboard();
		}
	}

	//This displays the intrinsic VE controls.
	this.ShowVEControls = function()
	{
		if (this.mapInstance != null)
		{
			this.mapInstance.ShowDashboard();
		}
	}

	//Moves the map to be centered on the given latitude and longitude and then
	//adjusts the zoom to the given level.
	this.SetCenterAndZoom = function(latLong, zoomLevel){
		if (this.mapInstance != null)
		{
			this.mapInstance.SetCenterAndZoom(latLong, zoomLevel);
		}
	}


	//Initializes the internal map instance and requests the appropriate tile set to be
	//displayed.
	//Parameters:   latLong A VELatLong representing the center of the map.
	//			  zoom	The zoom level at which the map is to be displayed.
	//			  style   The type of map to display (VEMapStyle enumeration)
	//			  fixed   Boolean value indicating whether the map is fixed (i.e. cannot
	//					  be navigated using the map control)
	//			  mode	Indicates whether 3D is enabled (VEMapMode enumeration)
	//			  showSwitch  Boolean value indicating whether the 2D/3D switch is visible
	this.CreateAndLoadMap = function(latLong, zoom, style, fixed, mode, showSwitch, clientToken)
	{
		this.mapInstance = new VEMap(controlId);
		if (clientToken != '') {
			this.mapInstance.SetClientToken(clientToken);
		}
		this.mapInstance.LoadMap(latLong, zoom, style, fixed, mode, showSwitch);
		this.mapInstance.SetScaleBarDistanceUnit(this.distanceUnits);
		this.AddCompassRose();
	}

	//Creates and injects the compass div that appears on the top right hand corner of the map
	//<div id="compass" style="background-color:transparent; z-index: 999; left: 720px; background-image: url(http://dev.cb.yp.ca/map/North_icon.gif); width: 20px; position: relative; top: 7px; height: 20px;"></div>
	this.AddCompassRose = function()
	{
		var targetMap = document.getElementById(controlId);
		var target = findPos(targetMap);
		var targetWidth = targetMap.style.width;

		var d = document.createElement( "DIV" );

		d.style.backgroundColor = 'transparent';
		d.style.zIndex = '999';
		d.style.right = '10px';
		d.style.top = '7px';
		d.style.backgroundImage = 'url(http://cb.yp.ca/map/North_icon.gif)';
		d.style.width = '18px';
		d.style.height = '25px';
		d.style.backgroundRepeat = 'no-repeat';
		d.style.position = 'absolute';
		targetMap.appendChild( d );
	}
	//Creates a new instance of the map.  This needs to be followed by the LoadMap call
	//to display a map.
	this.Create = function(){
		this.mapInstance = new VEMap(controlId);
	}

	//Loads the map and if provided sets the appropriate view.
	 //Parameters:   latLong A VELatLong representing the center of the map.
	//			  zoom	The zoom level at which the map is to be displayed.
	//			  style   The type of map to display (VEMapStyle enumeration)
	//			  fixed   Boolean value indicating whether the map is fixed (i.e. cannot
	//					  be navigated using the map control)
	//			  mode	Indicates whether 3D is enabled (VEMapMode enumeration)
	//			  showSwitch  Boolean value indicating whether the 2D/3D switch is visible
	this.LoadMap = function(latLong, zoom, style, fixed, mode, showSwitch){
		this.mapInstance.LoadMap(latLong, zoom, style, fixed, mode, showSwitch);
	}

	//Sets the Url to the image that is the custom Icon
	//Parameters:   shape   A VEShape for which the custom Icon is to be set
	//			  imageUrl	A Url to the image file.

	//Translate the dashboard into French
	this.DashboardTranslateFR = function()
	{
	}

	//Sets the Url to the image that is the custom Icon
	//Parameters:   shape   A VEShape for which the custom Icon is to be set
	//			  imageUrl	A Url to the image file.
	this.SetCustomIcon = function(shape, imageUrl)
	{
		if(shape != null)
		{
			if(imageUrl!=null &&imageUrl!='')
			{
				shape.SetCustomIcon(imageUrl);
			}
		}
	}


	//Adds a pushpin the the map
	//Parameter:	pushpin A VE shape to be added to the map.
	this.AddPushpin = function(pushPin)
	{
		if (this.mapInstance != null)
		{
			this.mapInstance.AddShape(pushPin);
		}
	}


	//Adds a location pushpin to the map with the details for the info box set
	//Parameters:   lat The latitude of the location
	//			  lon The longitude of the location
	//			  coyName The company name or a display name
	//			  address The address
	//			  city	The city
	//			  prov	The province
	//			  postalCode  The postal code
	//			  phone   The phone
	//			  customIconSpecification HTML or VECustomIconSpecification that overrides the customIcon and customIconSpecification properties of this class
	this.AddLocation = function(lat, lon, coyName, address, city, prov, postalCode, phone, customIconSpecification)
	{
		var newPin = null;
		if (this.mapInstance != null)
		{
			var newPin = new VEShape(VEShapeType.Pushpin, new VELatLong(lat, lon));
			newPin.SetTitle(coyName);
			var contactBlock = "";

			if (address != '') { contactBlock += address + "<br/>"; }
			if (city != '') { contactBlock += city + "<br/>"; }
			if (prov != '') { contactBlock += prov + "<br/>"; }
			if (postalCode != '') { contactBlock += postalCode + "<br/>"; }
			if (phone != '') { contactBlock += phone + "<br/>"; }

			if (contactBlock != '') { newPin.SetDescription(contactBlock); }

			if(customIconSpecification == null || customIconSpecification == 'undefined')
			{
				if(this.pushPinIcon != null)
				{
					this.SetCustomIcon(newPin, this.pushPinIcon);
				}
				if(this.customIconSpecification != null)
				{
				   this.SetCustomIcon(newPin, this.customIconSpecification);
				}
			}
			else
			{
				this.SetCustomIcon(newPin, customIconSpecification);
			}
			this.AddPushpin(newPin);
		}

	}

	//Adds multiple locations to the map
	//Parameter:	locations an array of locations.
	this.AddLocations = function(locations)
	{
		var lat;
		var lon;
		var coyName;
		var address;
		var city;
		var prov;
		var postalCode;
		var phone;
		var customIconSpecification;
		var pointArray = new Array();
		if (this.mapInstance != null){
			for (var i = 0; i<locations.length; i++)
			{
				lat = locations[i][0];
				lon = locations[i][1];
				coyName = locations[i][2];
				address = locations[i][3];
				city = locations[i][4];
				prov = locations[i][5];
				postalCode = locations[i][6];
				phone = locations[i][7];
				customIconSpecification =locations[i][8];
				this.AddLocation(lat, lon, coyName, address, city, prov, postalCode, phone, customIconSpecification);
				pointArray.push(new VELatLong(lat,lon));
			}
			if (pointArray.length>0){
				this.mapInstance.SetMapView(this.mapInstance.GetShapeLayerByIndex(0).GetBoundingRectangle());
			}
		}
	 }

	//Deletes all shapes in all layers, leaving empty layers behind
	this.DeleteAllShapes = function()
	{
			this.mapInstance.DeleteAllShapes();
	}

	//Deletes a VEShape Class object from any layer, including the base map layer.
	//Parameter:  shape  The VEShape to remove
	this.DeleteShape = function(shape)
	{
			this.mapInstance.DeleteShape(shape);
	}

	//Gets the direction manager used for V5 routing
	//Returns: _dm  The direction manager containing the V5 route pushpins
	this.Get_dm = function()
	{
			return this.mapInstance._dm;
	}
	//Finds a location, not really used at this stage but here if necessary.
	this.FindLocation = function(address, city, prov, postalCode)
	{
		var searchAddress = '';
		var what = null;
		var findType = null;
		var shapeLayer = null;
		var startIndex = null;
		var numberOfResults = null;
		var showResults = false;
		var createResults = false;
		var useDefaultDisambiguation = false;
		var setBestMapView = true;

		if (address != null && address != '')
		{
			searchAddress = searchAddress + address;
		}
		searchAddress = searchAddress + ', ';

		if (city != null && city != '')
		{
			searchAddress = searchAddress + city;
		}
		searchAddress = searchAddress + ', ';

		if (prov != null && prov != '')
		{
			searchAddress = searchAddress + prov;
		}
		searchAddress = searchAddress + ', ';

		if (postalCode != null && postalCode != '')
		{
			searchAddress = searchAddress + postalCode;
		}

		if (this.mapInstance!=null)
		{
			this.mapInstance.Find(what, searchAddress, findType, shapeLayer, startIndex, numberOfResults, showResults, createResults, useDefaultDisambiguation, setBestMapView, onGotFindResults);
		}
	}

	//Gets a route (V5)
	//Parameters:   start   VELatLong or string address of the starting location
	//			  end	 VELatLong or string address of the ending locations
	//			  units   VEDistanceUnits enum	{kilometers|miles}
	//			  routeType   VERouteType enum	{shortest|quickest}
	this.GetRoute = function(start, end, units, routeType, callback)
	{
		if (this.mapInstance != null)
		{
			if (callback == null) callback = onGotRoute;
			this.mapInstance.GetRoute(start, end, units, routeType, callback);
		}
	}

	//Gets a route (V6)
	//Parameters:   locations   An array of objects specifying the points through which the route must pass.
	//							The points can be either VELatLong Class objects or String objects.
	//			  options	 A VERouteOptions Class object specifying the routing options.
	this.GetDirections = function(locations, options)
	{
		options.DistanceUnit   = VERouteDistanceUnit.Kilometer;

		if (this.mapInstance != null)
		{
			this.mapInstance.GetDirections(locations,options);
		}
	}
	//Translates the route driving directions into French (V5)
	//Parameters:   route   A VERoute Class object returned from a V5 GetRoute call
	//Returns:	  route   A VERoute Class object returned from a V5 GetRoute call
	this.GetRouteTranslateFR = function(route)
	{
		var len = route.Itinerary.Segments.length;
			for(var i = 0; i < (len) ;i++)
			{
				route.Itinerary.Segments[i].Instruction = TranslateFR(route.Itinerary.Segments[i].Instruction);
			}
		return route;
	}
	//Translates the route driving directions into French (V6)
	//Parameters:   route   A VERoute Class object returned from a V6 GetDirections call
	//Returns:	  route   A VERoute Class object returned from a V6 GetDirections call
this.GetDirectionsTranslateFR = function(route)
	{
	   //clear original route pushpins
		map.DeleteAllShapes();

	   // Unroll route
	   var routeinfo="";
	   var steps = "";
	   var legs = route.RouteLegs;
	   var leg = null;
	   var legCount = 0;
	   var shape = null;

	   var	totalDistance = route.Distance;
		   	totalDistance = totalDistance.toFixed(1);
	   var	totalTime = route.Time;
	   		totalTime = totalTime*1000;

			//alert(time(totalTime));

			totalTime = time(totalTime);

	   // Get intermediate legs
		for(var i = 0; i < legs.length; i++)
		{
		   // Get this leg so we don't have to derefernce multiple times
		   leg = legs[i];  // Leg is a VERouteLeg object

		   // Unroll each intermediate leg
		   for(var j = 0; j < leg.Itinerary.Items.length; j ++)
		   {
			var turn = leg.Itinerary.Items[j];
			var turnDistance = turn.Distance;

			legCount = j+1;

			turnDistance = turnDistance.toFixed(1);

			turn = TranslateFR(turn.Text);  // turn is a VERouteItineraryItem object

			shape = new VEShape(VEShapeType.Pushpin,leg.Itinerary.Items[j].LatLong )
			if(legCount == 1)
			{
				shape.SetDescription(turn);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/mapicon_start.gif");
			}
			else if(legCount == leg.Itinerary.Items.length)
			{
				shape.SetDescription(turn);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/mapicon_end.gif");
			}
			else
			{
				shape.SetDescription(turn);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/RedCircle"+ legCount +".gif");
			}

			map.AddPushpin(shape);

			steps += GenerateResults([turn, turnDistance, totalDistance, totalTime], j, leg.Itinerary.Items.length);
		   }

		}

		routeinfo = steps;

	   var ourDiv=document.getElementById('drivingDirections');

	   	ourDiv.innerHTML = routeinfo;

		___lastRoute = route;
	//return route;
	}

	this.GetDirectionsEN = function(route)
	{
	   //clear original route pushpins
		map.DeleteAllShapes();

	  // Unroll route
	  var routeinfo="";
	  var steps = "";
	  var legs = route.RouteLegs;
	  var leg = null;
	  var legCount = 0;
	  var shape = null;

	  var	totalDistance = route.Distance;
		totalDistance = totalDistance.toFixed(1);
	  var	totalTime = route.Time;
	  totalTime = totalTime*1000;

		//alert(time(totalTime));

		totalTime = time(totalTime);

	   // Get intermediate legs
		for(var i = 0; i < legs.length; i++)
		{
		   // Get this leg so we don't have to derefernce multiple times
		   leg = legs[i];  // Leg is a VERouteLeg object

		   // Unroll each intermediate leg
		   for(var j = 0; j < leg.Itinerary.Items.length; j ++)
		   {
			var turn = leg.Itinerary.Items[j];
			var turnDistance = turn.Distance;

			legCount = j+1;

			turnDistance = turnDistance.toFixed(1);

			shape = new VEShape(VEShapeType.Pushpin,leg.Itinerary.Items[j].LatLong )
			if(legCount == 1)
			{
				shape.SetDescription(turn.Text);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/mapicon_start.gif");
			}
			else if(legCount == leg.Itinerary.Items.length)
			{
				shape.SetDescription(turn.Text);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/mapicon_end.gif");
			}
			else
			{
				shape.SetDescription(turn.Text);
				shape.SetCustomIcon("http://dev.virtualearth.net/mapcontrol/v6/i/bin/1.0.20070926140324.39/pins/RedCircle"+ legCount +".gif");
			}

			map.AddPushpin(shape);


			steps += GenerateResults([turn.Text, turnDistance, totalDistance, totalTime], j, leg.Itinerary.Items.length);
		   }
		}

		routeinfo = steps;

	   var ourDiv=document.getElementById('drivingDirections');

	   ourDiv.innerHTML = routeinfo;

	   ___lastRoute = route;

	//return route;
	}

	//Translates directions into French
	//Parameters:   itineraryText   The driving itinerary directions that need to be translated
	//Returns:	  itineraryText   The driving itinerary directions that need to be translated
	function TranslateFR(itineraryText)
	{
		itineraryText = itineraryText.replace(/At roundabout take exit number/gi, 'Au carrefour giratoire, prenez la sortie n&deg;');
		itineraryText = itineraryText.replace(/Exit roundabout at exit number/gi, 'Sortez du carrefour giratoire &agrave; la sortie n&deg;');

		itineraryText = itineraryText.replace(/Road name changes to/gi, 'Le nom de la rue devient');
		itineraryText = itineraryText.replace(/Turn is potentially restricted/gi, 'Il se peut que le virage soit interdit');
		itineraryText = itineraryText.replace(/Stop for toll booth/gi, 'Arr&ecirc;tez au poste de p&eacute;age');
		itineraryText = itineraryText.replace(/Check the time table/gi, 'Consultez l&rsquo;horaire');
		itineraryText = itineraryText.replace(/and then immediately bear/gi, 'et continuez imm&eacute;diatement vers');
		itineraryText = itineraryText.replace(/and then immediately turn/gi, 'et tournez imm&eacute;diatement');
		itineraryText = itineraryText.replace(/Enter roundabout and take/gi, 'Prenez le carrefour giratoire, puis prenez');
		itineraryText = itineraryText.replace(/Pass through 1 roundabout/gi, 'Traversez un carrefour giratoire');

		itineraryText = itineraryText.replace(/to stay on/gi, 'pour rester sur');
		itineraryText = itineraryText.replace(/on the right/gi, '&agrave; votre droite');
		itineraryText = itineraryText.replace(/on the left/gi, '&agrave; votre gauche');
		itineraryText = itineraryText.replace(/Gate access required/gi, 'Il vous faut un droit d&rsquo;acc&egrave;s');
		itineraryText = itineraryText.replace(/Road name changes/gi, 'Rue change de nom');
		itineraryText = itineraryText.replace(/and follow signs/gi, 'et suivez la signalisation');
		itineraryText = itineraryText.replace(/and then immediately/gi, 'puis imm&eacute;diatement');
		itineraryText = itineraryText.replace(/and then bear/gi, 'puis continuez');
		itineraryText = itineraryText.replace(/Take ramp toward/g, 'Prenez la bretelle vers');
		itineraryText = itineraryText.replace(/take ramp toward/g, 'prenez la bretelle vers');
		itineraryText = itineraryText.replace(/Exit roundabout at/gi, 'Sortez du carrefour giratoire &agrave;');
		itineraryText = itineraryText.replace(/Exit roundabout onto/gi, 'Sortez du carrefour giratoire vers');

		itineraryText = itineraryText.replace(/to stay/gi, 'pour rester');
		itineraryText = itineraryText.replace(/and then/gi, 'et ensuite');
		itineraryText = itineraryText.replace(/Keep straight/g, 'Continuez tout droit');
		itineraryText = itineraryText.replace(/keep straight/g, 'continuez tout droit');
		itineraryText = itineraryText.replace(/Keep left/g, 'Gardez la gauche');
		itineraryText = itineraryText.replace(/keep left/g, 'gardez la gauche');
		itineraryText = itineraryText.replace(/Keep right/g, 'Gardez la droite');
		itineraryText = itineraryText.replace(/keep right/g, 'gardez la droite');
		itineraryText = itineraryText.replace(/1st exit/gi, 'la 1<sup>re</sup> sortie');
		itineraryText = itineraryText.replace(/2nd exit/gi, 'la 2<sup>e</sup> sortie');
		itineraryText = itineraryText.replace(/3rd exit/gi, 'la 3<sup>e</sup> sortie');
		itineraryText = itineraryText.replace(/4th exit/gi, 'la 4<sup>e</sup> sortie');
		itineraryText = itineraryText.replace(/Local road\(s\)/gi, 'voie r&eacute;gionale');
		itineraryText = itineraryText.replace(/Toll road/gi, 'Route &agrave; p&eacute;age');
		itineraryText = itineraryText.replace(/Arrive At/gi, 'Arriv&eacute;e &agrave;');
		itineraryText = itineraryText.replace(/Depart from/gi, 'D&eacute;part de');
		itineraryText = itineraryText.replace(/and keep/gi, 'puis gardez');
		itineraryText = itineraryText.replace(/Turn back/gi, 'Faites demi-tour');
		itineraryText = itineraryText.replace(/Merge onto/gi, '&Agrave; la jonction, continuez sur / vers');
		itineraryText = itineraryText.replace(/Stay on/gi, 'Restez sur');
		itineraryText = itineraryText.replace(/At exit/gi, '&Agrave; la sortie n&deg;');
		itineraryText = itineraryText.replace(/Take ramp/g, 'Prenez la bretelle');
		itineraryText = itineraryText.replace(/take ramp/g, 'prenez la bretelle');
		itineraryText = itineraryText.replace(/Exit onto/gi, 'Sortez sur');
		itineraryText = itineraryText.replace(/Enter roundabout/gi, 'Prenez le carrefour giratoire');
		itineraryText = itineraryText.replace(/Pass through/gi, 'Traversez');
		itineraryText = itineraryText.replace(/At roundabout,/gi, 'Au carrefour giratoire,');

		itineraryText = itineraryText.replace(/\bnortheast\b/gi, 'nord-est');
		itineraryText = itineraryText.replace(/\bnorthwest\b/gi, 'nord-ouest');
		itineraryText = itineraryText.replace(/\bsoutheast\b/gi, 'sud-est');
		itineraryText = itineraryText.replace(/\bsouthwest\b/gi, 'sud-ouest');
		itineraryText = itineraryText.replace(/\bwest\b/gi, 'ouest');
		itineraryText = itineraryText.replace(/\bsouth\b/gi, 'sud');
		itineraryText = itineraryText.replace(/\beast\b/gi, 'est');
		itineraryText = itineraryText.replace(/\bnorth\b/gi, 'nord');
		itineraryText = itineraryText.replace(/LEFT/gi, '&agrave; gauche');
		itineraryText = itineraryText.replace(/RIGHT/gi, '&agrave; droite');
		itineraryText = itineraryText.replace(/STRAIGHT/gi, 'tout droit');
		itineraryText = itineraryText.replace(/Unknown/gi, 'Inconnu');
		itineraryText = itineraryText.replace(/Ferry/gi, 'Traversier');
		itineraryText = itineraryText.replace(/Entering/gi, 'Entr&eacute;e');
		itineraryText = itineraryText.replace(/\bfor\b/gi, 'pour');
		itineraryText = itineraryText.replace(/\bAt\b/gi, '&Agrave;');
		itineraryText = itineraryText.replace(/onto/gi, 'sur');
		itineraryText = itineraryText.replace(/exit/g, 'sortie');
		itineraryText = itineraryText.replace(/\bto\b/gi, 'vers');
		itineraryText = itineraryText.replace(/\bon\b/gi, 'sur');
		itineraryText = itineraryText.replace(/Turn/g, 'Tournez');
		itineraryText = itineraryText.replace(/turn/g, 'tournez');
		itineraryText = itineraryText.replace(/Return/gi, 'Retournez vers');
		itineraryText = itineraryText.replace(/Take/g, 'Prenez');
		itineraryText = itineraryText.replace(/take/g, 'prenez');
		itineraryText = itineraryText.replace(/toward/gi, 'vers');
		itineraryText = itineraryText.replace(/Exit/g, 'Sortie');
		itineraryText = itineraryText.replace(/Arrive/gi, 'Arriv&eacute;e');
		itineraryText = itineraryText.replace(/Bear/gi, 'Continuez');
		itineraryText = itineraryText.replace(/Ramp/gi, 'Bretelle');
		itineraryText = itineraryText.replace(/Depart/gi, 'D&eacute;part');
		itineraryText = itineraryText.replace(/\bContinue\b/gi, 'Continuez');
		itineraryText = itineraryText.replace(/Keep/g, 'Gardez');
		itineraryText = itineraryText.replace(/keep/g, 'gardez');
		itineraryText = itineraryText.replace(/Stay/gi, 'Restez');
		itineraryText = itineraryText.replace(/Start/gi, 'Commencez');
		itineraryText = itineraryText.replace(/\bthe\b/gi, '');
		itineraryText = itineraryText.replace(/\bW\b/gi, ' O ');
		itineraryText = itineraryText.replace(/Hwy/gi, 'Aut');
		itineraryText = itineraryText.replace(/roundabouts/gi, 'carrefours giratoires');

		return itineraryText;
	}
	//Move the center of the map
	//Parameters:   deltaX  change in x
	//			  deltaY  change in y
	this.Pan = function(deltaX, deltaY)
	{
		if (this.mapInstance != null)
		{
			this.mapInstance.Pan(deltaX, deltaY);
		}
	}

	//Set the location of the map center to the given latLong
	//Parameter:	latLong VELatLong
	this.SetCenter = function(latLong)
	{
		if (this.mapInstance !=null)
		{
			this.mapInstance.SetCenter(latLong);
		}
	}

	//Get the location of the map center to the given latLong
	this.GetCenter = function()
	{
		var center = null;
		if (this.mapInstance !=null)
		{
			center= this.mapInstance.GetCenter();
		}
		return center;
	}

	//Get the location of the map center to the given latLong
	this.GetZoomLevel = function()
	{
		var level = null;
		if (this.mapInstance !=null)
		{
			level= this.mapInstance.GetZoomLevel();
		}
		return level;
	}


}

//Callback Functions
//probably don't need this as the start and end locations of the GetRoute take address strings as well as
//lat/longs
function onGotFindResults (shapeLayer, findResults, locations, hasMoreResults)
{}

//a dummy function to use if no callback is wanted, same behavior as passing a null to the callback.
function onGotRouteNOP(){}

//handler for GetRoute, displays the results in a table.
//override this to specialize the route display for the different maps.
/*
function onGotRoute(route)
{
   ____lastRoute = route; */
   /*var  routeinfo="Route info:\n\n";
   routeinfo += "Total distance: ";
   routeinfo += route.Itinerary.Distance+" ";
   routeinfo += route.Itinerary.DistanceUnit+"\n";

   var steps="";
   var len = route.Itinerary.Segments.length;

   for(var i = 0; i<len ;i++)
   {
	  steps += GenerateResults(route,i,len);
   }

   routeinfo += "<table>"+steps + "</table>"; */
/*
   var  routeinfo="";
   var steps="";
   var len = route.Itinerary.Segments.length;

   for(var i = 0; i<len ;i++)
   {
	  steps += GenerateResults(route,i,len);
   }

   routeinfo = steps;

   var ourDiv=document.getElementById('drivingDirections');

   ourDiv.innerHTML = routeinfo;
   ___lastRoute = route;
} */

//Generates the specific markup for displaying the route directions
/*function GenerateResults(route, stepNumber, totalSteps){
   var results = "";
   var styleSwitch = "";



   if (stepNumber % 2 != 0)
   {
	   styleSwitch = "2";
   }

   if (totalSteps>0)
   {

		if(stepNumber == 0)
		{
			//create the markup for the header and first row of the table
			results = results + "<tr>";
			results = results + results,"	 <td style=\"border-top: 1px solid rgb(255, 226, 28); padding: 10px 0pt;\" colspan=\"2\">";
			results = results + results,"		 <table id=\"DrivingDetails\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
			results = results + "			 <tbody>";
			results = results + "				 <tr>";
			results = results + "					 <td class=\"directionsCell2\" colspan=\"2\"/>";
			results = results + "					 <td class=\"directionsCell2\" width=\"90%\">";
			results = results + "						 <strong>Directions</strong>";
			results = results + "					 </td>";
			results = results + "					 <td class=\"directionsCell2\" width=\"4%\">";
			results = results + "						 <strong>Map</strong>";
			results = results + "					 </td>";
			results = results + "				 </tr>";
			results = results + "		<tr>";
			results = results + "			<td class=\"directionsToFromCell\" width=\"4%\">";
			results = results + "				<strong>From</strong>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsLetterCell\" width=\"2%\">";
			results = results + "				<img width=\"20\" height=\"20\" alt=\"A\" src=\"http://www.yellowpages.ca/images/circA.png\"/>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsCell\">";
			results = results + ((stepNumber + 1) + ":" + route.Itinerary.Segments[stepNumber].Instruction + " (" + route.Itinerary.Segments[stepNumber].Distance + " " + route.Itinerary.DistanceUnit + ")");
			results = results + "			   <div id=\"ddmap" + stepNumber + "\" style=\"width:525px;height:214px; position:relative;\"></div>";
			results = results + "				<br/>";
			results = results + "				<img height=\"0\" name=\"map" + stepNumber +"\"/>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsMapLinkCell\">";
			results = results + "				<a id=\"text" + stepNumber + "\" onclick=\"GenerateDDMap(___lastRoute, " + stepNumber + ")\" >Map</a>";
			results = results + "			</td>";
			results = results + "		</tr>";

		}
		else if(stepNumber < totalSteps-1)
		{
			//create the markup of for steps 1 to n-1
			results = results + "		<tr>";
			results = results + "			<td class=\"directionsToFromCell" + styleSwitch + "\">";
			results = results + "				&nbsp;";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsLetterCell" + styleSwitch + "\">";
			results = results + "				&nbsp;";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsCell" + styleSwitch + "\">";
			results = results + ((stepNumber + 1) + ":" + route.Itinerary.Segments[stepNumber].Instruction + " (" + route.Itinerary.Segments[stepNumber].Distance + " " + route.Itinerary.DistanceUnit + ")");
			results = results + "			   <div id=\"ddmap" + stepNumber + "\" style=\"width:525px;height:214px; position:relative;\"></div>";
			results = results + "				<br/>";
			results = results + "				<img height=\"0\" name=\"map" + stepNumber + "\"/>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsMapLinkCell" + styleSwitch + "\">";
			results = results + "				<a id=\"text" + stepNumber + "\" onclick=\"GenerateDDMap(___lastRoute, " + stepNumber + ")\">Map</a>";
			results = results + "			</td>";
			results = results + "		</tr>";

		}
		 else if(stepNumber == totalSteps -1)
		{
			//create the markup for the last step in the directions and insert add summary info
			results = results + "		<tr>";
			results = results + "			<td class=\"directionsToFromCell" + styleSwitch + "\">";
			results = results + "				<strong>To</strong>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsLetterCell" + styleSwitch + "\">";
			results = results + "				<img width=\"20\" height=\"20\" alt=\"B\" src=\"http://www.yellowpages.ca/images/circB.png\"/>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsCell" + styleSwitch + "\">";
			results = results + ((stepNumber + 1) + ":" + route.Itinerary.Segments[stepNumber].Instruction + " (" + route.Itinerary.Segments[stepNumber].Distance + " " + route.Itinerary.DistanceUnit + ")");
			results = results + "			   <div id=\"ddmap" + stepNumber + "\" style=\"width:525px;height:214px; position:relative;\"></div>";
			results = results + "			</td>";
			results = results + "			<td class=\"directionsMapLinkCell" + styleSwitch + "\">";
			results = results + "				<a id=\"text" + stepNumber + "\" onclick=\"GenerateDDMap(___lastRoute, " + stepNumber + ")\">Map</a>";
			results = results + "			</td>";
			results = results + "		</tr>";
			results = results + "		<tr>";
			results = results + "			<td class=\"directionsCell\" colspan=\"4\">";
			results = results + "				<strong>Total Estimated Time : </strong>";
			results = results + route.Itinerary.Time;
			results = results + "			  <strong>Total Estimated Distance : </strong>";
			results = results + route.Itinerary.Distance + " " + route.Itinerary.DistanceUnit;
			results = results + "			</td>";
			results = results + "		 </tr>";
			results = results + "			</tbody>";
			results = results + "		</table>";
			results = results + "   </td>";
			results = results + "</tr>";

		}

		return results;
	}

}*/

//Work around for VE not yet having turn by turn maps.  When VE 6 releases with Maneuver maps
//change this method to utilize that functionality.  Currently it creates a new map and route
//then zooms in and centers on the area of the specific instruction.
//Parameters:   route   VERoute
//			  stepNumber  the current step
function GenerateDDMap(route, stepNumber)
{
	var ddMap = new YPGMapControl("ddmap" + stepNumber);
	var legs = route.RouteLegs;

	 // Get intermediate legs
		for(var i = 0; i < legs.length; i++)
		{
		   // Get this leg so we don't have to derefernce multiple times
		   leg = legs[i];  // Leg is a VERouteLeg object

		   // Unroll each intermediate leg
		  	try{
				___lastStepNumber = stepNumber;
				___lastCenter = leg.Itinerary.Items[stepNumber].LatLong;
				ddMap.CreateAndLoadMap(leg.Itinerary.Items[stepNumber].LatLong, 17, VEMapStyle.Road, true, null, false);
				ddMap.HideVEControls();
				___lastMap = ddMap;
				var routeShape = leg.Itinerary.Items[stepNumber].Shape;
				ddMap.AddPushpin(routeShape);

			}catch(ex){
				alert(ex.message);
			}
		}
}

//Opens the Turn By Turn map.
//TODO: fix behaviour
function OpenMapDiv(route)
{
	var stepNumber = ___lastStepNumber;
	var center = route.Itinerary.Segments[stepNumber].LatLong;
	var ddMap = ___lastMap;
	ddMap.SetCenterAndZoom(center, 17);
	var ourDiv = document.getElementById('ddmap' + stepNumber);
	//ourDiv.style.display = "block";
	//ourDiv.style.height = 214;
	var linkElement = document.getElementById('text' + stepNumber);
	linkElement.setAttribute('onclick', "CloseMapDiv(" + stepNumber + ")");
}

//Closes the Turn By Turn map.
//TODO: fix this behavior
function CloseMapDiv(stepNumber)
{
	var ourDiv = document.getElementById('ddmap' + stepNumber);
	//ourDiv.style.display = "none";
	//ourDiv.style.height = 0;
	var linkElement = document.getElementById('text' + stepNumber);
	linkElement.setAttribute('onclick', "GenerateDDMap(___lastRoute, " + stepNumber + ")");
}

//Verifies the browser is compliant.
IsBrowserVECompliant = function()
{
	//firefox
	var firefox_index = navigator.userAgent.indexOf(FIREFOX_AGENTID);
	if (firefox_index != -1)
	{
		var firefox_version = parseFloat(navigator.userAgent.substring(firefox_index + FIREFOX_AGENTID.length));
		return firefox_version >= 1.5;
	}

	//internet explorer
	var ie_index = navigator.userAgent.indexOf(IE_AGENTID);
	if (ie_index != -1)
	{
		var ie_version = parseFloat(navigator.userAgent.substring(ie_index + IE_AGENTID.length));
		return ie_version >= 6;
	}

	return false;
 }

 function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}


 //Global variables
 var ___lastCenter = null;
 var ___lastRoute = null;
 var ___lastStepNumber = 0;
 var ___lastMap = null;

function two(x) {return ((x>9)?"":"0")+x}
function three(x) {return ((x>99)?"":"0")+((x>9)?"":"0")+x}

function time(ms) {
var sec = Math.floor(ms/1000)
ms = ms % 1000

var min = Math.floor(sec/60)
sec = sec % 60
t = two(sec) + "sec"

var hr = Math.floor(min/60)
min = min % 60
t = two(min) + "min " + t

var day = Math.floor(hr/60)
hr = hr % 60
hr = two(hr)
if(hr != 00) { t = two(hr) + "h " + t }
if(day != 0) { t = day + "day " + t }

return t
}
