﻿// Javascript File
// version 1.0

/* Byrom mapping
	Note : requires latest MS mapping script (http://dev.virtualearth.net/mapcontrol/v4/MapControl.js at time of writing)
*/

function Dummy(arg) {
	var x = 2;
};
 
	
var	ByromMaps = new Object();
var ByromMap = null;
	
function ByromMappingOnLoad() {
	ByromMap = new ByromMaps.Mapping('myMap');
};

function ByromMappingGetRouteFromPage() {
	ByromMap.getRoute(document.getElementById('fromDropDownList').selectedIndex, document.getElementById('toDropDownList').selectedIndex  );
};

function ByromMappingTabFromChanged(tabs) {
	ByromMap.setRouteTabFromChanged(tabs._activeTabIndex + 1);
};

function ByromMappingOnChangeMapStyle() {
	ByromMap.onChangeMapStyle();
};
function ByromMappingOnInitMode() {
	ByromMap.onInitMode();
};

function ByromMappingOnGetInfo() {
	ByromMap.startGetPositionInfo('infodata');
	setTimeout(ByromMappingOnGetInfo, 500);
};

function ByromMappingOnNo3DInstalled() {
	ByromMap.no3DInstalled();
};





/**************	tour  *************/
function ByromMappingNextTourItem() {
	ByromMap.setNextTourItem();
};

function ByromMappingTourStart() {
	ByromMap.tourStart();
};
function ByromMappingTourStop() {
	ByromMap.tourStop();
};

function ByromMappingOnChangeView(arg) {
	// ByromMap.onChangeView();
	setTimeout(ByromMappingOnChangeViewDelayed, 100);
};

function ByromMappingOnChangeViewDelayed() {
	ByromMap.onChangeView();
};	

/**************	tour (end of) *************/


function ByromMappingOnGotRoute(route) {
	ByromMap.onGotRoute(route);
};	

function ByromMappingTabToChanged(tabs) {
	ByromMap.setRouteTabToChanged(tabs._activeTabIndex + 1);
};

function ByromMappingShowInfoBox(displayId) {
	ByromMap.showInfoBoxByDisplayId(displayId);
};



ByromMaps.Mapping = function(mapId) {
		/// <summary>
		/// creates a new mapping object in the Div id mapId
		/// </summary>
		/// <param name="mapId" type="Sys.UI.DomElement" DomElement="true" mayBeNull="false" />
		/// <returns />
			   
		// Public Properties
		
		
		// Properties
		this._isInitialising = null;
		this._mapID = null;
		this._map = null;
		this._iconStyle = null;		//Icon style class name
		this._titleStyle = null;	//Title style class name
		this._previewStyle = null;	//Preview style class name
		this._pointDataId = null;	//id of element containing xml pushpin point data 
		this._pointData = null;		//xml pushpin point data  (should we use json ?)
		this._xmlDoc = null;
		this._xmlHttp = null;
		this._layers = null;		//collection(props, airp, venues) of collection of points
		this._nodes = null;		//collection of nodeId pointers to layer nodes
		this._routeDirectionsElementId = null;	//	id of div for route information to be poked into
		this._routeDirectionsToggleId = null;	//	button for ajax collapsing container extender
		this._routeDirectionsContentId = null;	//	directions text container
		this._routeRouteFinderContentId = null;		//	route finder/panel container
		this._routeRouteFinderToggleId = null;		//	route finder/panel toggle control id
		this._routeChooseDisplayId = null;			//	choose display tab heading (to click) 
		this._routeSelectedNodeIdFrom = null;	//	route selected nodeId from
		this._routeSelectedNodeIdTo = null;		//	route selected nodeId to
		this._routeFinderContentAlreadyDisplayed = null;	//	initial display only
		this._indexOfpushpinType = null;		//	currently populating index of route from/to tab
		//	map style id's
		this._mapMode2DId = null;
		this._mapMode3DId = null;
		this._mapModeIds = null;
		this._mapStyleRoadsId = null;
		this._mapStyleAerialId = null;
		this._mapStyleHybridId = null;
		this._mapStyleBirdseyeId = null;
		this._mapStyleIds = null;	
		this._tourShowPopups = null;
		this._tourAlwaysSetTourStyleId = null;
		this._tourShowPopupsId = null;
		//	internationalised text
		this._textStep = null;
		this._textTotal = null;
		this._textDistance = null;
		this._textDirection = null;
		this._textStartAt = null; 
		this._textArriveAt = null;
		this._textFromTo = null;
		this._textTotalDistance = null;
		this._textTotalTime = null;
		this._textViaQuickestRoute = null;
		this._textViaShortestRoute = null;
		this._textHoursMinutesSeconds = null;
		this._textMinutesSeconds = null;
		this._textSeconds = null;
		this._textSetFrom = null;
		this._textSetTo = null;
		this._textGetRoute = null;
		this._textRouteFromHere = null;
		this._textRouteToHere = null;
		
		// Public Properties
		this.Map = null;

		// Variables
		this._latitudeMin = null;
		this._longitudeMin = null;
		this._latitudeMax = null;
		this._longitudeMax = null;	
		this._count = null;  
		this._routePushpinTypeNameFrom = null;
		this._routeSelectedIndexFrom = null;
		this._routePushpinTypeNameTo = null;
		this._routeSelectedIndexTo = null;
		this._routeType = null;
		this._routeDistanceUnit = null;
		this._routePushpinFrom = null;
		this._routePushpinTo = null;
		this._tourIndex = null;
		this._nextTourItemShape = null;
		this._nextTourItemShapeId = null;
		this._nextTourItemDelayMilliseconds = null;
		this._tourInProgress = null;
		this._changedMapModeTime = null;
		this._routeOptions = null;
		this._tourAltitude = null;
		this._tourMapMode = null;
		this._tourMapStyle = null;
		this._tourPitch = null;
		this._tourZoomLevel = null;
		this._tourAreDefaultsApplied = null;
		this._tourAreDefaultsAppliedAlways = null;
		this._no3DInstalledInProgress = null;
		
		// Delegates
		this._clickNextHandler = null;
		this._clickPreviousHandler = null;
		this._tickHandler = null;
		this._imageLoadedHandler = null;
		
		// Setup
		this.initialize(mapId);	
};

ByromMaps.Mapping.prototype = { 
	initialize : function(mapId) {
		///<summary>
		/// Initialize the map
		/// </summary>
		/// <returns />	  
		/* debugger; */
		
		this._isInitialising = true;
		
		//	various server created client element id's
		//TODO:	get these clientIds from server 
		this._routeDirectionsElementId = 'mapRouteDirectionsText';
		this._routeDirectionsToggleId = "ctl00_ctl00_c_c_mapRouteDirectionsCollapseToggleImage";	
		this._routeDirectionsContentId = "ctl00_ctl00_c_c_mapRouteDirectionsContentPanel";	
		this._routeRouteFinderToggleId = "ctl00_ctl00_c_c_mapCollapseToggleImage";
		this._routeRouteFinderContentId = "ctl00_ctl00_c_c_mapRouteFinderContentPanel";
		this._routeChooseDisplayId = "__tab_ctl00_ctl00_c_c_TabContainer1_TabPanel2";
		this._pointDataId = "ctl00_ctl00_c_c_mapPointsHiddenField";	//TODO:	un hard code this ?
		this._treeViewId = "ctl00_ctl00_c_c_TabContainer1_TabPanel2_pointsTreeView";	//	used to get id of contained checkboxes
		//	map styles id's
		this._mapMode2DId = "ctl00_ctl00_l_l_mapDimensionsRadioButtonList_0";
		this._mapMode3DId = "ctl00_ctl00_l_l_mapDimensionsRadioButtonList_1";
		this._mapModeIds = new Array(this._mapMode2DId, this._mapMode3DId);
		this._mapStyleRoadsId = "ctl00_ctl00_l_l_mapContourRadioButtonList_0";
		this._mapStyleAerialId = "ctl00_ctl00_l_l_mapContourRadioButtonList_1";
		this._mapStyleHybridId = "ctl00_ctl00_l_l_mapContourRadioButtonList_2";
		this._mapStyleBirdseyeId = "ctl00_ctl00_l_l_mapContourRadioButtonList_3";
		this._mapStyleIds =  new Array(this._mapStyleRoadsId, this._mapStyleAerialId, this._mapStyleHybridId, this._mapStyleBirdseyeId);
		this._tourAlwaysSetTourStyleId = "ctl00_ctl00_c_c_TabContainer1_TabPanel3_alwaysSetTourStyleCheckBox";
		this._tourShowPopupsId = "ctl00_ctl00_c_c_TabContainer1_TabPanel3_showPopupsCheckBox";
		
		
		this._mapID = mapId;
		this._latitudeMin = 9999999999;
		this._longitudeMin = 9999999999;
		this._latitudeMax = -9999999999;
		this._longitudeMax = -9999999999;	  
		this._count = 0;  
		this._iconStyle = 'mapPushpinIcon'; //Icon style class name
		this._titleStyle = 'mapPushpinTitle';  //Title style class name
		this._previewStyle = 'mapPushpinPreview'; //Preview style class name
		this._layers = [];
		this._nodes = [];		
		this._routePushpinTypeNameFrom = 1;
		this._routeSelectedIndexFrom = [];
		this._routePushpinTypeNameTo = 3;
		this._routeSelectedIndexTo = [];
		this._routeType = VERouteType.Quickest;
		this._routeDistanceUnit = VEDistanceUnit.Miles;
		this._routeFinderContentAlreadyDisplayed = false;
		this._nextTourItemDelayMilliseconds = 3000;
		this._tourInProgress = false;
		this._no3DInstalledInProgress = false;
		
		this._tourAltitude = 349366.375017299;
		this._tourMapMode = VEMapMode.Mode3D;
		this._tourMapStyle = VEMapStyle.Hybrid;	//VEMapStyle.Aerial;
		this._tourPitch = -37.6793510986965;
		this._tourZoomLevel = 8;
		this._tourAreDefaultsApplied = false;
		this._tourAreDefaultsAppliedAlways = Byrom.getButtonValue(this._tourAreDefaultsAppliedAlwaysId, false);
		this._tourShowPopups = Byrom.getButtonValue(this._tourShowPopupsId, true);
		//	internationalised text
		this._textStep = "Step";
		this._textTotal = "Total";
		this._textDistance = "Distance";
		this._textDirection = "Direction";
		this._textStartAt = "Start at ";
		this._textArriveAt = "Arrive at ";
		this._textFromTo = "From <B>{0}</B> to <B>{1}</B>";
		this._textTotalDistance = "Total distance: ";	//	charAt(5)
		this._textTotalTime = "Total Time: ";
		this._textViaQuickestRoute = "Via quickest route";
		this._textViaShortestRoute = "Via shortest route";
		this._textHoursMinutesSeconds = "{0} hour(s), {1} minute(s), {2} second(s)";
		this._textMinutesSeconds = "{0} minute(s), {1} second(s)";
		this._textSeconds = "{0} second(s)";
		this._textSetFrom = "Set from";
		this._textSetTo = "Set to";
		this._textGetRoute = "Get Route";
		this._textRouteFromHere = "Route from here";
		this._textRouteToHere = "Route to here";
			
		var pointDataElement = document.getElementById(this._pointDataId);	
		this._pointData = pointDataElement.value;	
		pointDataElement.value = "";			//	blank this - xml data causes security problems on post back - its not needed anyway
		
		if (window.XMLHttpRequest)
		{
			this._xmlHttp = new XMLHttpRequest()
		}
		// code for IE
		else if (window.ActiveXObject)
		{
			this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
		}
		
		if (window.ActiveXObject)	// code for IE
		{
			this._xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
			this._xmlDoc.async=false;
			/*this._xmlDoc.load("note.xml");
			getmessage();*/	
		}	
		else 
		{
			this._xmlDoc=document.implementation.createDocument("","",null);
			/*this._xmlDoc.load("note.xml");
			this._xmlDoc.onload=getmessage;*/
		}
		
		this._map = new VEMap(this._mapID);
		this._map.LoadMap();
		this._map.AttachEvent('onmodenotavailable', ByromMappingOnNo3DInstalled);		//	this.no3DInstalled);
		
		this._map.HideDashboard();	//	default layer panel
		// this._map.ShowFindControl();
		this.loadXmlString(this._pointData);	//	must be SYNC not async
		
		this.addPushpinsWithXml();
		this._routePushpinTypeNameFrom = 2;	//	default tabs
		this._routeSelectedNodeIdFrom = this._routeSelectedIndexFrom[this._routePushpinTypeNameFrom];
		this._routePushpinTypeNameTo = 1;
		this._routeSelectedNodeIdTo = this._routeSelectedIndexTo[this._routePushpinTypeNameTo];
		this.deleteRoute();	//	unset any displayed icons
		
		this.setTreeClicks();
		
		//	public properties
		this.Map = this._map ;
		
		// events
		this._map.AttachEvent("onchangeview", ByromMappingOnChangeView);
		this._map.AttachEvent("oninitmode", ByromMappingOnInitMode);
		this._map.AttachEvent("onchangemapstyle", ByromMappingOnChangeMapStyle);
		
		this._isInitialising = false;
		
	},
	
	setTourShowPopups: function(value)	
	{
		this._tourShowPopups = value;
	},
	setTourAreDefaultsAppliedAlways: function(value)	
	{
		this._tourAreDefaultsAppliedAlways = value;
	},
	startGetPositionInfo: function(id)	
	{
		var info = "";
		/*
		info += "GetAltitude=" + this._map.GetAltitude().toString();
		info += "<br/>GetMapMode=" + this._map.GetMapMode().toString();
		info += "<br/>GetMapStyle=" + this._map.GetMapStyle().toString();
		//info += "<br/>GetMapView=" + this._map.GetMapView().toString();
		info += "<br/>GetPitch=" + this._map.GetPitch().toString();
		info += "<br/>GetZoomLevel=" + this._map.GetZoomLevel().toString();
		*/
		/*
		this._routePushpinTypeNameTo = 1;
this._routeSelectedIndexTo = [];
this._routeSelectedNodeIdTo
*/

		info += "<br/> Fr id=" + this._routeSelectedNodeIdFrom + "  (index=" + this._routePushpinTypeNameFrom + ")";
		//info += "<br/>   ar index=" + this._routePushpinTypeNameFrom;
		for(var indexOfFrom in this._routeSelectedIndexFrom)
			info += "<br/>   ar (" + indexOfFrom + ")value=" + this._routeSelectedIndexFrom[indexOfFrom];
		
		info += "<br/>";
		info += "<br/> To id=" + this._routeSelectedNodeIdTo + "  (index=" + this._routePushpinTypeNameTo + ")";
		//info += "<br/>   ar index=" + this._routePushpinTypeNameTo;
		for(var indexOfTo in this._routeSelectedIndexTo)
			info += "<br/>   ar (" + indexOfTo + ")value=" + this._routeSelectedIndexTo[indexOfTo];
		
		var elem = document.getElementById(id);
		if (elem)
			elem.innerHTML = info;
	},
	getPositionInfo: function(id)	
	{
		var info = "";
		info += "GetAltitude=" + this._map.GetAltitude().toString();
		info += "<br/>GetMapMode=" + this._map.GetMapMode().toString();
		info += "<br/>GetMapStyle=" + this._map.GetMapStyle().toString();
		//info += "<br/>GetMapView=" + this._map.GetMapView().toString();
		info += "<br/>GetPitch=" + this._map.GetPitch().toString();
		info += "<br/>GetZoomLevel=" + this._map.GetZoomLevel().toString();
		
		
		var elem = document.getElementById(id);
		if (elem)
			elem.innerHTML = info;
	},
	onInitMode: function()	/* changed dimensions mode (2D or 3D)  */
	{
		this._map.HideInfoBox();
		this._map.HideDashboard();	//	default layer panel
		this._changedMapModeTime = new Date();
		this.tourStop();
	},
	onChangeMapStyle: function()	/* changed map style (roads, aeriel..) */
	{
		//	if just changed to 3D AND changed styl too then map is inconsistent in displaying pushpins so just refresh them
		//alert('onChangeMapStyle');
		if (this._changedMapModeTime != null && (this._map.GetMapMode() == VEMapMode.Mode3D))
		{
			if (((new Date()).getTime() - this._changedMapModeTime.getTime()) < 60000 )	//	less than 60 seconds have passed since changed to 3D
			{
				//alert('refreshing on style change');
				for(var nodeIndex in this._nodes)	/* refresh each node */
				{
					pin = this._nodes[nodeIndex];
					if (pin.PinType == 1 && pin.Visible)	//	leaf node (can be displayed on map
						this.setPushpinVisiblityRefresh(pin, pin.Visible, true)
				}
			}
		}
		this._changedMapModeTime = null;
	},
	showInfoBoxByDisplayId: function(displayId)
	{
		if (!this._tourInProgress)
		{
			var pin = this.getPinByDisplayId(displayId);
			if (pin)	
			{
				this._nextTourItemShapeId = pin.ShapeId;
				this._nextTourItemShape = this._map.GetShapeByID(pin.ShapeId);
				var latLong = new VELatLong(pin.Latitude, pin.Longitude);
				this._map.HideInfoBox();
				if (pin.Visible)	
				{
					if (this.isLatLongOnMap(latLong))
						this._map.ShowInfoBox(this._nextTourItemShape);
					else
					{
						//var panTo = latLong;
						//var panTo = this._map.GetCenter()
						var panTo = this.getPanToLatLongOnMap(latLong);
						this._map.SetCenter(panTo);
						this._map.ShowInfoBox(this._nextTourItemShape);
						//this._map.PanToLatLong(panTo);
					}
				}
			}
		}
	},
	getPanToLatLongOnMap: function(latLong)
	{
		//	move centre so 'latLong' is visible
		var pix = this._map.LatLongToPixel(latLong);
		var centrePix = this._map.LatLongToPixel(this._map.GetCenter());
		var panToPix = new VEPixel(centrePix.x, centrePix.y);
		var margin = 40;
		var xAdj = 0;
		var yAdj = 0;
		if (pix.x < 0)
			xAdj = pix.x - margin;
		else if (pix.x > (centrePix.x * 2))
			xAdj = pix.x - (centrePix.x * 2) + margin;
		
		if (pix.y < 0)
			yAdj = pix.y - margin;
		else if (pix.y > (centrePix.y * 2))
			yAdj = pix.y - (centrePix.y * 2) + margin;
		
		var panToPix = new VEPixel(centrePix.x + xAdj, centrePix.y + yAdj);
		
		return this._map.PixelToLatLong(panToPix);
	},
	isLatLongOnMap: function(latLong)
	{
		var pix = this._map.LatLongToPixel(latLong);
		var centrePix = this._map.LatLongToPixel(this._map.GetCenter());
		return !(pix.x < 0 || pix.y < 0 || pix.x > (centrePix.x * 2) || pix.y > (centrePix.y * 2));		
	},
	getPinByDisplayId: function(displayId)
	{		
		for(var nodeIndex in this._nodes)	
		{
			var pin = this._nodes[nodeIndex];
			if (pin.DisplayId == displayId)	
				return pin;
		}		
		return null;
	},
	setNextTourItem: function()
	{
		this.setNextPrevTourItem(true);
	},
	setPrevTourItem: function()
	{
		this.setNextPrevTourItem(false);
	},
	setNextPrevTourItem: function(isNext)
	{
		//if (!this._tourAreDefaultsApplied && this._tourInProgress && this._map.GetMapMode() == VEMapMode.Mode3D)	//	only do once (and only for 3D too)
		//{
		//	this.setTourMapStyle()
		//}
			
		this._nextTourItemShape = null;
		var tourIndexOriginal = null;			
		var pin = null;
		if (isNext)
		{
			if (this._tourIndex == null)
				this._tourIndex = -1;
			tourIndexOriginal = this._tourIndex ;			
			pin = this._nodes[++this._tourIndex];
			while (pin == null || pin == undefined || pin.PinType != 1|| !pin.Visible) {
				if (pin == null || pin == undefined)
					this._tourIndex = -1;
				
				if (tourIndexOriginal == this._tourIndex)	//	stop endless loop hang
					break;
				pin = this._nodes[++this._tourIndex]
			}
		}
		else	//	get previous
		{
			if (this._tourIndex == null)
				this._tourIndex = this._nodes.length;
			tourIndexOriginal = this._tourIndex ;			
			pin = this._nodes[--this._tourIndex];
			while (pin == null || pin == undefined || pin.PinType != 1|| !pin.Visible) {
				if (pin == null || pin == undefined)
					this._tourIndex = this._nodes.length;
				
				if (tourIndexOriginal == this._tourIndex)	//	stop endless loop hang
					break;
				pin = this._nodes[--this._tourIndex]
			}
		}
		
		if (pin)
		{
			// var shape = this._map.GetShapeByID(pin.ShapeId);
			this._nextTourItemShapeId = pin.ShapeId;
			this._nextTourItemShape = this._map.GetShapeByID(pin.ShapeId);
			
			//this._map.SetCenter(new VELatLong(pin.Latitude, pin.Longitude));
			//this._map.SetCenterAndZoom(new VELatLong(pin.Latitude, pin.Longitude) , 5);
			this._map.PanToLatLong(new VELatLong(pin.Latitude, pin.Longitude));		
			
		}
	},
	onChangeView: function()
	{
		// alert('onChangeView');
		if (this._nextTourItemShape != null)
		{
			/*var anchor = this._map.GetCenter();
			var offset = new VEPixel(0,0);
			this._map.ShowInfoBox(shape, anchor, offset);*/
			if (this._tourShowPopups)
				this._map.ShowInfoBox(this._nextTourItemShape, null, new VEPixel(10,0));
			if (this._tourInProgress)
			{
				setTimeout(ByromMappingNextTourItem, this._nextTourItemDelayMilliseconds);		
			}
		}
		this._nextTourItemShape = null;
		
	},
	tourStart: function()
	{
		if (true || !this._tourInProgress)
		{
			this._map.HideInfoBox();
			this._tourInProgress = true;
			if ((!this._tourAreDefaultsApplied || this._tourAreDefaultsAppliedAlways) && this._map.GetMapMode() == VEMapMode.Mode3D)	//	only do once (and only for 3D too)
			{
				this.setTourMapStyle()
			}
			this.setNextTourItem();
		}
	},
	setTourMapStyle: function()
	{
		if (!this._tourAreDefaultsApplied || this._tourAreDefaultsAppliedAlways)
		{
			this._tourAreDefaultsApplied = true;
			this.setSelectedRadioButton(this._tourMapStyle, this._mapStyleIds);
			//this._map.SetMapStyle(this._tourMapStyle);
			this.setMapStyle(this._tourMapStyle);
			this._map.SetAltitude(this._tourAltitude);
			this._map.SetPitch(this._tourPitch);
			this._map.SetZoomLevel(this._tourZoomLevel);
		}
	},
	setSelectedRadioButton: function(buttonValue, controlIds)
	{
		var ctl = null;
		var id = null;
		var controlIdIndex = null;
		if (controlIds instanceof Array)
		{
			for (controlIdIndex = 0; controlIdIndex < controlIds.length; controlIdIndex++)
			{
				ctl = null;
				id = controlIds[controlIdIndex];
				if (id)
				{
					ctl = document.getElementById(id);
				}
				if (ctl != null && ctl.value == buttonValue)
				{
					ctl.checked = true;	
					break;
				}
			}
		} 
		else
		{
			for (controlIdIndex in controlIds)
			{
				ctl = null;
				id = controlIds[controlIdIndex];
				if (id)
				{
					ctl = document.getElementById(id);
				}
				if (ctl != null && ctl.value == buttonValue)
				{
					ctl.checked = true;	
					break;
				}
			}
		}
		/*
		this._map.SetMapStyle(this._tourMapStyle);
		this._map.SetAltitude(this._tourAltitude);
		this._map.SetPitch(this._tourPitch);
		this._map.SetZoomLevel(this._tourZoomLevel);
		*/
	},
	tourStop: function()
	{
		this._tourInProgress = false;
		this._map.HideInfoBox();
	},
	setMapMode2D: function()
	{
		this._map.HideInfoBox();
		this._map.SetMapMode(VEMapMode.Mode2D);
		this._map.HideDashboard();	//	default layer panel
		try{
			Byrom.SetMsCookieValue('Byrom.PreCheckIn', 'MapDimensions', this.getControlValueFromMapMode(VEMapMode.Mode2D))
		} catch (e) {}
	},
	getControlValueFromMapMode: function(mode)
	{
		if (mode == VEMapMode.Mode3D)
			return "3d";
		else
			return "2d";
	},
	getMapModeFromControlValue: function(value)
	{
		if (value == "3d")
			return VEMapMode.Mode3D;
		else
			return VEMapMode.Mode2D;
	},
	setMapMode3D: function()
	{
		this._map.HideInfoBox();
		this._map.SetMapMode(VEMapMode.Mode3D);
		this._map.HideDashboard();	//	default layer panel
		try{
			Byrom.SetMsCookieValue('Byrom.PreCheckIn', 'MapDimensions', this.getControlValueFromMapMode(VEMapMode.Mode3D))
		} catch (e) {}
	},
	setTreeClicks: function()
	{
		// ctl00_ctl00_c_c_TabContainer1_TabPanel2_pointsTreeViewn115CheckBox
		var index = -1;
		var elem = this.getCheckBoxFromNodeId(++index);
		while (elem) {
			//elem.onclick = function() { ByromMap.setVisiblityByNodeId(114, this.checked); };
			eval("elem.onclick = function() { ByromMap.setVisiblityByNodeId(" + index.toString() + ", this.checked); };");
			elem = this.getCheckBoxFromNodeId(++index);
		}
	},
	onRouteTabFromClick: function(pushpinTypeName)
	{
		this._routePushpinTypeNameFrom = pushpinTypeName;
		//TODO: this._routeSelectedIndexFrom = selectedIndex;
	},	
	onRouteTabToClick: function(pushpinTypeName)
	{
		this._routePushpinTypeNameTo = pushpinTypeName;
		//TODO: this._routeSelectedIndexFrom = selectedIndex;
	},	
	onRouteFromClick: function(pushpinTypeName, selectedIndex)
	{
		this.setRouteNodeIdFrom(selectedIndex);
		// this._routeSelectedNodeIdFrom = selectedIndex;
		
		this._routePushpinTypeNameFrom = pushpinTypeName;
		this._routeSelectedIndexFrom[this._routePushpinTypeNameFrom] = selectedIndex;
	},	
	onRouteToClick: function(pushpinTypeName, selectedIndex)
	{
		this.setRouteNodeIdTo(selectedIndex);
		// this._routeSelectedNodeIdTo = selectedIndex;

		this._routePushpinTypeNameTo = pushpinTypeName;
		this._routeSelectedIndexTo[this._routePushpinTypeNameTo] = selectedIndex;
	},
	setRouteTabFromChanged: function(pushpinTypeName)
	{
		selectedIndex = this._routeSelectedIndexFrom[pushpinTypeName];
		if (selectedIndex) {
			this.onRouteFromClick(pushpinTypeName, selectedIndex);
		}
	},
	setRouteTabToChanged: function(pushpinTypeName)
	{
		selectedIndex = this._routeSelectedIndexTo[pushpinTypeName];
		if (selectedIndex) {
			this.onRouteToClick(pushpinTypeName, selectedIndex);
		}
	},
	setRouteNodeIdsRefresh: function()
	{
		this.setRouteNodeIdFrom(this._routeSelectedNodeIdFrom);
		this.setRouteNodeIdTo(this._routeSelectedNodeIdTo);
	},
	setRouteNodeIdFrom: function(nodeId)
	{
		if (!this._isInitialising)
		{
			var iconAppend = 'RouteFrom';
			//	if another selected, then de-select it, then set selected icon
			this.setRouteNodeId(nodeId, this._routeSelectedNodeIdFrom, iconAppend, 'images/RouteFrom.gif');
			
			var fromToJustMadeUnEqual = (this._routeSelectedNodeIdFrom != null && this._routeSelectedNodeIdFrom == this._routeSelectedNodeIdTo &&  this._routeSelectedNodeIdFrom != nodeId);
			
			//	save this value
			this._routeSelectedNodeIdFrom = nodeId;
			
			if (fromToJustMadeUnEqual)
			{
				this.setRouteNodeIdTo(this._routeSelectedNodeIdTo);
			}
		}
		
	},
	setRouteNodeIdTo: function(nodeId)
	{
		if (!this._isInitialising)
			{
			//TODO:	set iconAppend to 'RouteTo' (instead of 'RouteFrom')
			var iconAppend = 'RouteTo';
			//	if another selected, then de-select it, then set selected icon
			this.setRouteNodeId(nodeId, this._routeSelectedNodeIdTo, iconAppend, 'images/RouteTo.gif');
			
			var fromToJustMadeUnEqual = (this._routeSelectedNodeIdFrom != null && this._routeSelectedNodeIdFrom == this._routeSelectedNodeIdTo &&  this._routeSelectedNodeIdTo != nodeId);
			
			//	save this value
			this._routeSelectedNodeIdTo = nodeId;
			
			if (fromToJustMadeUnEqual)
			{
				this.setRouteNodeIdFrom(this._routeSelectedNodeIdFrom);
			}
		}
	},
	setRouteNodeId: function(nodeId, prevNodeId, iconAppend, iconUrl)
	{
		//	1st if another selected, then de-select it
		var pin = null;
		if (prevNodeId != null && nodeId != prevNodeId ) {
			pin = this._nodes[prevNodeId];
			if (pin != null && pin.IconUrl != pin.IconUrlOriginal) {		//	something previously selected
				pin.IconUrl = pin.IconUrlOriginal;
				this.setPushpinVisiblityRefresh(pin, pin.Visible, true);	//	may be a re-display - or leave deleted (visible = false)
			}
		}
		
		//	now set selected icon
		pin = this._nodes[nodeId];
		if (iconUrl)
			pin.IconUrl = iconUrl;
		else
			pin.IconUrl = this.getAppendedIconName(pin.IconUrlOriginal, iconAppend);
			
		this.setPushpinVisiblityRefresh(pin, true, true);	//	force a (re)display 
		
	},	
	getAppendedIconName: function(iconName, appendWith)	//	append before suffix
	{
		var returnFilename = iconName;
		var indexOfDot = iconName.lastIndexOf('.');
		if (indexOfDot > 0) {
			var filename = iconName.substring(0, indexOfDot);
			var extension = iconName.substring(indexOfDot);
			returnFilename = filename + appendWith + extension;
		}
		return returnFilename;
	},	
		
	onGotRoute : function(route)
	{
		//TODO:	internationalise this (route Text's are implemented in v6 qtr1 so just add to .Options when available)
		//			all other text need to come from server
		
		var elem = document.getElementById(this._routeDirectionsElementId);	//	usually a div
		if (elem) {
			
			var distanceUnit = this._routeOptions.DistanceUnit;
			if (distanceUnit == VERouteDistanceUnit.Mile)
				distanceUnit = "m";
			else
				distanceUnit = "km";
			
			var turns = "<h3>Turn-by-Turn Directions</h3>(rounding errors are possible)";
			turns += "<p><b>Distance:</b> " + route.Distance.toFixed(1) + " miles";
			turns += "<br/><b>Time:</b> " + this.GetTimeAsString(route.Time) + "</p>";

			var steps="";
			steps += "<TABLE class=\"routeFinderDirectionsText\">\n";
			// steps += "<CAPTION>Steps</CAPTION>\n";
			//	column captions
			
			//steps += "<TR class=\"routeFinderDirectionsTextHdr\">" + "<TH>" + "<B>Step</B>"
			//		+ "<TD>" + "<B>Total</B>"
			//		+ "<TD>" + "<B>Distance</B>"
			//		+ "<TD>" + "<B>Direction</B>" + "\n";
					
			steps += "<TR class=\"routeFinderDirectionsTextHdr\">" + "<TH>" + "<B>" + this._textStep + "</B>"
					+ "<TD>" + "<B>" + this._textTotal + "</B>"
					+ "<TD>" + "<B>" + this._textDistance + "</B>"
					+ "<TD>" + "<B>" + this._textDirection + "</B>" + "\n";
			
			var totalDistance = 0;
			var totalTime = 0;
			
			var legs		  = route.RouteLegs;
			var leg		   = null;
			var turnNum	   = 0;  // The turn #

		   // Get intermediate legs
		   var legLen = legs.length;
		   for(var legIndex = 0; legIndex < legs.length; legIndex++)
		   {
				// Get this leg so we don't have to derefernce multiple times
				leg = legs[legIndex];  // leg is a VERouteLeg object
				
				totalTime += leg.Time;
				var legNum = legIndex + 1;
				turns += "<br/><b>Distance for leg " + legNum + ":</b> " + leg.Distance.toFixed(1) + " miles" +
					"<br/><b>Time for leg "	 + legNum + ":</b> " + this.GetTimeAsString(leg.Time) + "<br/><br/>";

				// Unroll each intermediate leg
				var turn		= null;  // The itinerary leg
				var legDistance = null;  // The distance for this leg

				
				var len = leg.Itinerary.Items.length;
				for(var itineraryIndex = 0; itineraryIndex < len ;itineraryIndex++)
				{
					turnNum++;
					turn = leg.Itinerary.Items[itineraryIndex];  // turn is a VERouteItineraryItem object
					turns += "<b>" + turnNum + "</b>\t" + turn.Text;
					legDistance	= turn.Distance;

					var distance = leg.Itinerary.Items[itineraryIndex].Distance;
					if (distance == null)
						distance = 0;
					var cl = " class=\"routeFinderDirectionsTextRow\"";
					if ((itineraryIndex % 2) != 0)
						cl = " class=\"routeFinderDirectionsTextRowAlt\"";
					var instruction = leg.Itinerary.Items[itineraryIndex].Text;
					if (legIndex == 0 && itineraryIndex == 0)
						instruction = this._textStartAt + this._routePushpinFrom.Title;
					else if (legIndex == (legLen - 1) && itineraryIndex == (len - 1))
						instruction = this._textArriveAt + this._routePushpinTo.Title;
					
					steps += "<TR" + cl + ">" + "<TH>" + (itineraryIndex + 1) 
							+ "<TD>" + "" + Math.round(totalDistance*10)/10 + " " + distanceUnit + " "
							+ "<TD>" + "" + Math.round(distance*10)/10 + " " + distanceUnit + " "
							+ "<TD>" + instruction + "\n";
					
					totalDistance += distance;
				}
			}
			steps += "</TABLE>\n";
			
			var fromTo = "";
			if (this._routePushpinFrom != null && this._routePushpinTo != null)
			{
				//fromTo = "From <B>" + this._routePushpinFrom.Title + "</B> to <B>" + this._routePushpinTo.Title + "</B><br />";
				fromTo = this._textFromTo.replace("{0}", this._routePushpinFrom.Title).replace("{1}", this._routePushpinTo.Title) ;
				fromTo += "<br />";
			}
			
			//var routeinfo=fromTo
			//	+ "Total distance: "
			//	+ Math.round(totalDistance*10)/10 +" "	//	route.Itinerary.Distance seems to be slightly out
			//	+ distanceUnit+"<br />"
			//	+ "Total Time: " + this.GetTimeAsString(totalTime) +"<br />";
			//if (this._routeOptions.RouteOptimize == VERouteOptimize.MinimizeTime) // "q")
			//	routeinfo += "Via quickest route";
			//else
			//	routeinfo += "Via shortest route";
			
			
			var routeinfo=fromTo
				+ this._textTotalDistance
				+ Math.round(totalDistance*10)/10 +" "	//	route.Itinerary.Distance seems to be slightly out
				+ distanceUnit+"<br />"
				+ this._textTotalTime + this.GetTimeAsString(totalTime) +"<br />";
			if (this._routeOptions.RouteOptimize == VERouteOptimize.MinimizeTime) // "q")
				routeinfo += this._textViaQuickestRoute;
			else
				routeinfo += this._textViaShortestRoute;
				
			routeinfo+="<br />"+steps;
			elem.innerHTML = routeinfo;	
		}
	},
	// time is an integer representing seconds
	// returns a formatted string
	GetTimeAsString:	function (time)
	{
		if(time == null)
		{
		   return("");
		}

		if(time > 60)
		{								 // if time == 100
		   var seconds = time % 60;	   // seconds == 40
		   var minutes = time - seconds;  // minutes == 60
		   minutes	 = minutes / 60;	// minutes == 1


		   if(minutes > 60)
		   {									 // if minutes == 100
			  var minLeft = minutes % 60;		// minLeft	== 40
			  var hours   = minutes - minLeft;   // hours	  == 60
			  hours	   = hours / 60;		  // hours	  == 1

			  // return(hours + " hour(s), " + minLeft + " minute(s), " + seconds + " second(s)");
			  return(this._textHoursMinutesSeconds.replace("{0}", hours).replace("{1}", minLeft).replace("{2}", seconds));	
		   }
		   else
		   {
			  //return(minutes + " minutes, " + seconds + " seconds");
			  return(this._textMinutesSeconds.replace("{0}", minLeft).replace("{1}", seconds));	
		   }
		}
		else
		{
		   //return(time + " seconds");
		   return(this._textSeconds.replace("{0}", seconds));	
		}
	},
	setMapStyle : function(mapStyle)
	{
		this._map.SetMapStyle(mapStyle);
		try
		{
			Byrom.SetMsCookieValue('Byrom.PreCheckIn', 'MapContour', mapStyle)
		}
		catch(e) {}
	},
	routeTypeToggle : function()
	{
		if (this._routeType == VERouteType.Shortest)
			this._routeType = VERouteType.Quickest;
		else
			this._routeType = VERouteType.Shortest;
			
	},
	setRouteTypeToQuickest: function()
	{
		this._routeType = VERouteType.Quickest;			
	},
	setRouteTypeToShortest: function()
	{
		this._routeType = VERouteType.Shortest;
			
	},
	setRouteDistanceUnitToMiles : function()
	{
		this._routeDistanceUnit = VEDistanceUnit.Miles;
	},
	setRouteDistanceUnitToKilometers : function()
	{
		this._routeDistanceUnit = VEDistanceUnit.Kilometers;
	},
	routeDistanceUnitToggle : function()
	{
		if (this._routeDistanceUnit == VEDistanceUnit.Kilometers)
			this._routeDistanceUnit = VEDistanceUnit.Miles;
		else
			this._routeDistanceUnit = VEDistanceUnit.Kilometers;

	},
	addLayers : function()
	{
		var veLayerSpec = new VELayerSpecification();
		veLayerSpec.Type = VELayerType.VECollection;
		veLayerSpec.ID = 'layer1';
		veLayerSpec.LayerSource = "9ED1673AEDDF5B29!109";
		veLayerSpec.FnCallback = this.onFeedLoad;
		this._map.AddLayer(veLayerSpec);
	},
	showLayers : function()
	{
		this._map.ShowLayer('layer1');
	},
	hideLayers : function()
	{
		this._map.HideLayer('layer1');
	},


	onFeedLoad : function(feed)
	{
		alert('RSS or Collection loaded. There are ' +
			  feed.length + ' items in this list.');
	},

	no3DInstalled : function()
	{
		try	
		{
			if (this._no3DInstalledInProgress)
				return;
			this._no3DInstalledInProgress = true;
			this.setSelectedRadioButton(this.getControlValueFromMapMode(VEMapMode.Mode2D), this._mapModeIds);	//	reset selected back to 2d
		}
		catch(err)
		{
			err2=err;
		}
		this._no3DInstalledInProgress = false;
		Byrom.setStyleDisplayShow('no3dDiv');
		/*alert('Before viewing the Byrom Plc maps in 3D mode, '+
		  'you must install Virtual Earth 3D software on your computer.' +
		  '\nTo install the software, visit ' +
		  'http://go.microsoft.com/fwlink/?LinkId=72623.');*/
	},
	closePreview : function() 
	{
		var elem = document.body;
		for(index=0; index< elem.childNodes.length; index++)
		{
			var child = elem.childNodes[index];
			if (child.style && child.className == 'ero') {
				child.style.visibility='hidden';
				break;
			}
		}
		
	},
	getRouteSelectHtml : function()
	{
		var dropdownOptions = '';

		dropdownOptions += '<option value=0>My pushpin 1</option>';
		dropdownOptions += '<option value=1>My pushpin 2</option>';
		dropdownOptions += '<option value=2>My pushpin 3</option>';
		dropdownOptions += '</select>';
	
		var html = '<br/>From : ' + '<select name="ByromMappingRouteFrom" id="ByromMappingRouteFrom">' + dropdownOptions
			+ '<br/>To : ' + '<select name="ByromMappingRouteTo" id="ByromMappingRouteTo">' + dropdownOptions
			+ "<br/><a href=\"javascript: ByromMap.getRoute(document.getElementById('ByromMappingRouteFrom').selectedIndex, document.getElementById('ByromMappingRouteTo').selectedIndex  );\" >get route</a>";
		return html;
		
	},
	getRoute : function()
	{
		try
		{
			//var fromIndex = this._routeSelectedIndexFrom[this._routePushpinTypeNameFrom];
			//var toIndex = this._routeSelectedIndexTo[this._routePushpinTypeNameTo];
			
			this._routePushpinFrom = this._nodes[this._routeSelectedNodeIdFrom];
			this._routePushpinTo = this._nodes[this._routeSelectedNodeIdTo];
	
			if (this._routePushpinFrom != null & this._routePushpinTo != null & this._routeSelectedNodeIdFrom != this._routeSelectedNodeIdTo) {
				 
				//	make sure targets are visible
				this.setRouteNodeIdsRefresh();
				
				//	show the route
				
				var units = this._routeDistanceUnit;	//	VEDistanceUnit.Miles(default) or VEDistanceUnit.Kilometers
				var routeType = this._routeType;		//	VERouteType.Shortest(default) or VERouteType.Quickest
				
				/*
				this._map.GetRoute(new VELatLong(this._routePushpinFrom.Latitude, this._routePushpinFrom.Longitude), new VELatLong(this._routePushpinTo.Latitude, this._routePushpinTo.Longitude), units, routeType, ByromMappingOnGotRoute) ; //TODO: this.onGotRoute);
				
				this.showDirectionsContent();	//	if not already displayed
				*/
				
				
				
				//	convert to map v6
				if (units == 'm')
					units = VERouteDistanceUnit.Mile;
				else
					units = VERouteDistanceUnit.Kilometer;
					
				if (routeType == 's')
					routeType = VERouteOptimize.MinimizeDistance ;
				else
					routeType = VERouteOptimize.MinimizeTime ;
					
				
				var locations;

				locations = new Array(new VELatLong(this._routePushpinFrom.Latitude, this._routePushpinFrom.Longitude), new VELatLong(this._routePushpinTo.Latitude, this._routePushpinTo.Longitude));

				var options = new VERouteOptions;

				// Otherwise what's the point?
				options.DrawRoute	  = true;

				// Does the map change ?:
				options.SetBestMapView = !this._tourInProgress;

				// Call this function when map route is determined:
				options.RouteCallback  = ByromMappingOnGotRoute;

				// Show as miles
				options.DistanceUnit   = units;

				// Show the disambiguation dialog
				options.ShowDisambiguation = true;

				// how to optimize the route order
				options.RouteOptimize = routeType;
				this._routeOptions = options;
				
				this._map.GetDirections(locations, options);

				this.showDirectionsContent();	//	if not already displayed

				
			}
		}
		catch (ex)
		{
		}
	},
	getRouteFromNodeId : function(nodeId)
	{
		this.setRouteNodeIdFrom(nodeId);
		this.getRoute();
	},
	getRouteToNodeId : function(nodeId)
	{
		this.setRouteNodeIdTo(nodeId);
		this.getRoute();
	},
	showRouteFinderContent : function()
	{
		if (!this._routeFinderContentAlreadyDisplayed) {
			//var elem = document.getElementById(this._routeChooseDisplayId);	//	usually a div
			//if (elem) {
			//	elem.click();	
			//}	
			this.showHideRouteFinderContent('show');
			this._routeFinderContentAlreadyDisplayed = true;
			
		}
	},
	hideRouteFinderContent : function()
	{
		this.showHideRouteFinderContent('hide');
	},
	showHideRouteFinderContent : function(showHide)
	{
		this.showHideCollapsibleContent(showHide, this._routeRouteFinderContentId, this._routeRouteFinderToggleId);
	},
	showDirectionsContent : function()
	{
		this.showHideDirectionsContent('show');
	},
	hideDirectionsContent : function()
	{
		this.showHideDirectionsContent('hide');
	},
	showHideDirectionsContent : function(showHide)
	{
		this.showHideCollapsibleContent(showHide, this._routeDirectionsContentId, this._routeDirectionsToggleId);
	},
	showHideCollapsibleContent : function(showHide, contentId, toggleId)
	{
		//	display contentId div if not already displayed
		//	just need to (decide to) call toggle control's click event to execute ajax extender expand/collapse or not
		var content = document.getElementById(contentId);	//	usually a div
		if (content != null && content.style != null) {
			if ((showHide == 'show' && (content.style.height == null || content.style.height == '' || content.style.height == '0px'))		//	show if hidden
					||
					(showHide != 'show' && (content.style.height != null &&  content.style.height != '' && content.style.height != '0px')) ) {	//	hide if shown
				//	need to toggle
				var elem = document.getElementById(toggleId);	//	usually a buttton
				if (elem) {
					elem.click();	
				}	
			}
		}
	},
	getRouteByPushpinIndex : function(fromPushpinindex, toPushpinindex)
	{
		if (fromPushpinindex != toPushpinindex)
			this._map.GetRoute(this._map.pushpins[fromPushpinindex].LatLong, this._map.pushpins[toPushpinindex].LatLong);
	},
	getRouteTest : function()
	{
		this._map.GetRoute(new VELatLong(40.6, -122.33), new VELatLong(49.6, -110.33));
	},
	deleteRoute : function()
	{
		this._map.DeleteRoute();


		this.hideDirectionsContent();	//	dont delete direction text, just collapse container
		
		//	hide route icons
		var pin = this._nodes[this._routeSelectedNodeIdFrom];
		if (pin != null && pin.IconUrl != pin.IconUrlOriginal) {		//	something previously selected
			pin.IconUrl = pin.IconUrlOriginal;
			this.setPushpinVisiblityRefresh(pin, pin.Visible, true)	//	may be a re-display - or leave deleted (visible = false)
		}
		pin = this._nodes[this._routeSelectedNodeIdTo];
		if (pin != null && pin.IconUrl != pin.IconUrlOriginal) {		//	something previously selected
			pin.IconUrl = pin.IconUrlOriginal;
			this.setPushpinVisiblityRefresh(pin, pin.Visible, true)	//	may be a re-display - or leave deleted (visible = false)
		}
		
	},
	
	loadXML : function(xmlFile)
	{
	  xmlDoc.async="false";
	  xmlDoc.onreadystatechange=verifyXmlLoadedOk;
	  xmlDoc.load(xmlFile);
	  xmlObj=xmlDoc.documentElement;
	},
	verifyXmlLoadedOk : function()
	{
	  // 0 Object is not initialized
	  // 1 Loading object is loading data
	  // 2 Loaded object has loaded data
	  // 3 Data from object can be worked with
	  // 4 Object completely initialized
	  if (xmlDoc.readyState != 4)
	  {
		  return false;
	  }
	},
	loadXmlString : function(xml)
	{
		if (window.ActiveXObject) {
			this._xmlDoc.async="false";
			this._xmlDoc.loadXML(xml);
		}
		else {
			var parser=new DOMParser();
			this._xmlDoc = parser.parseFromString(xml,"text/xml");
		}
	},
	
	getXmlNodeZeroText : function(parentNode, childNodeName)
	{
		var nodes = parentNode.getElementsByTagName(childNodeName);
		if (nodes != null && nodes.length > 0)
		{
			return nodes[0].text;
		}
		else
		{
			return "";
		}
	},
	getXmlAttributeValue : function(parentNode, attributeName, defaultValue)
	{
		var node = parentNode.attributes.getNamedItem(attributeName);
		if (node != null)
		{
			return node.value;
		}
		else
		{
			return defaultValue;
		}
	},
	setLayerAllVisiblity : function(visible)
	{	
		for(index in this._layers) {
			this.setLayerVisiblity(this._layers[index].name, visible);
		}	
		if (!visible)
			this.deleteRoute();
	},
	setLayerVisiblity : function(layerName, visible)
	{	   
		this.setLayerVisiblityByLayer(this._layers[layerName], visible)
	},
	setLayerVisiblityByLayer : function(layer, visible)
	{	   
		layer.visible = visible;
		if (layer.CheckBox && layer.CheckBox.checked != visible) 
			layer.CheckBox.checked = visible;
		if (layer.pushpins) {
			var pushpins = layer.pushpins;
			
			for(indexOfPin in pushpins) {
				try
				{
					var pin = pushpins[indexOfPin];
					this.setPushpinVisiblity(pin, visible);
				}
				catch (ex) {
					x = ex;
				}
			}	
		}
		if (layer.childLayers)	//	recurse thru
		{
			for(indexOfChildLayer in layer.childLayers) {
				this.setLayerVisiblityByLayer(layer.childLayers[indexOfChildLayer], visible);
			}	
		}
	},
	setVisiblityByNodeId : function(nodeId, visible)
	{	  
		var node = this._nodes[nodeId];
		if (node) {
			if (node.pushpins) {
				//	parent layer node
				var layer = node;
				layer.visible = visible;
				if (layer.pushpins) {
					if (layer.CheckBox && layer.CheckBox.checked != visible) 
						layer.CheckBox.checked = visible;
								
					var pushpins = layer.pushpins;
					
					for(indexOfPin in pushpins) {
						try
						{
							var pin = pushpins[indexOfPin];
							this.setPushpinVisiblity(pin, visible);
						}
						catch (ex) {
							x = ex;
						}
					}	
				}
				if (layer.childLayers)	//	recurse thru
				{
					for(indexOfChildLayer in layer.childLayers) {
						this.setLayerVisiblityByLayer(layer.childLayers[indexOfChildLayer], visible);
					}	
				}
			}
			else
			{
				//	its a leaf node
				pin = node;
				this.setPushpinVisiblity(pin, visible);
			}
		}
	},
	//	note 'pin' is ByromPin not VE pin or GE point
	setPushpinVisiblity : function(pin, visible)
	{	
		this.setPushpinVisiblityRefresh(pin, visible, false);
	},
	//	note 'pin' is ByromPin not VE pin or GE point
	//	refresh : redisplay if already displayed
	setPushpinVisiblityRefresh : function(pin, visible, refresh)
	{	
		/*if (pin.Visible != visible) {					
			if (visible) {
				var newPin = new VEPushpin(pin.ID, new VELatLong(pin.Latitude, pin.Longitude), pin.IconUrl, pin.Title, pin.Details, pin.IconStyle, pin.TitleStyle, pin.DetailsStyle);						
				this._map.AddPushpin(newPin);
			}
			else
			{
				this._map.DeletePushpin(pin.ID);
			}
		}
		else if (pin.Visible && visible && refresh) {	//	refresh this point (icon changed ?)
			//	delete it so can re-add with (UN)modified icon
			this._map.DeletePushpin(pin.ID);
			//	now force a re-display
			newPin = new VEPushpin(pin.ID, new VELatLong(pin.Latitude, pin.Longitude), pin.IconUrl, pin.Title, pin.Details, pin.IconStyle, pin.TitleStyle, pin.DetailsStyle);						
			this._map.AddPushpin(newPin);
		}*/
		var shape = this._map.GetShapeByID(pin.ShapeId);
		if (refresh) {	//	refresh this point (icon changed ?)
			shape.SetCustomIcon(pin.IconUrl);
			if (pin.Visible && visible)
				shape.Show();	//	reshow
		}
		if (pin.Visible != visible) {
			if (visible) 
				shape.Show();
			else
				shape.Hide();
		}
		
		if (pin.CheckBox && pin.CheckBox.checked != visible) 
			pin.CheckBox.checked = visible;
		pin.Visible = visible;			
	},
	addPushpinsWithXml : function()
	{
		//	this._xmlDoc MUST be loaded with xml data by now.
		this._latitudeMin = 9999999999;
		this._longitudeMin = 9999999999;
		this._latitudeMax = -9999999999;
		this._longitudeMax = -9999999999;
		
		this._layers = [];
		this._nodes = [];
		
		if (this._xmlDoc != null && this._xmlDoc.documentElement && this._xmlDoc.documentElement.childNodes != null ) {
			for (indexOfpushpinType=0;indexOfpushpinType<this._xmlDoc.documentElement.childNodes.length;indexOfpushpinType++)
			{
				var pushpinType = this._xmlDoc.documentElement.childNodes[indexOfpushpinType];
				if (pushpinType.nodeType != 1) continue;
				
				var elementName = pushpinType.tagName;
				
				if (elementName == 'system')
				{
					this.processSystemNode(pushpinType);
				}
				else if (elementName == 'pushpinType')
				{
					//	route finder defaults (set to null so can set to 1st leaf point)
					this._indexOfpushpinType = indexOfpushpinType;
					
					var pushpinTypeName = pushpinType.getAttribute("pushpinTypeName");
					if (pushpinTypeName != null) {
						this._layers[pushpinTypeName] = new Object();
						this.addPushpinsTypeWithXml(pushpinType, this._layers[pushpinTypeName]);
					}
				}
			}
		}
		//	set route from to defaults
		//this.setRouteTabFromChanged(1);	//	airport
		//this.setRouteTabToChanged(3);	//	property
		
		this.setRouteTabFromChanged(this._routePushpinTypeNameFrom );	//	airportbj
		this.setRouteTabToChanged(this._routePushpinTypeNameTo);	//	property
				
		//	get centre
		//TODO:	set Zoom (in/out by 1 doubles/halves scale)
		if (this._latitudeMin != 9999999999 && this._longitudeMin != 9999999999 && this._latitudeMax != -9999999999 && this._longitudeMax != -9999999999) {
			var latitudeCentre = (this._latitudeMax + this._latitudeMin) / 2;
			var longitudeCentre = (this._longitudeMax + this._longitudeMin) / 2;
			this._map.SetCenterAndZoom(new VELatLong(latitudeCentre, longitudeCentre) , 5);
		}
	},
	processSystemNode : function(systemElement)
	{
		var mapContour = this.getXmlAttributeValue(systemElement, "mapContour", "");
		if (mapContour != "")
			this.setMapStyle(mapContour);
		
		var mapDimensions = this.getXmlAttributeValue(systemElement, "mapDimensions", "");
		if (mapDimensions == "3d")
			this.setMapMode3D();
		else
			this.setMapMode2D();
			
		//	internationalised text
		this._textStep = this.getXmlAttributeValue(systemElement, "textStep", this._textStep);
		this._textTotal = this.getXmlAttributeValue(systemElement, "textTotal", this._textTotal);
		this._textDistance = this.getXmlAttributeValue(systemElement, "textDistance", this._textDistance);
		this._textDirection = this.getXmlAttributeValue(systemElement, "textDirection", this._textDirection);
		this._textStartAt = this.getXmlAttributeValue(systemElement, "textStartAt", this._textStartAt);
		this._textArriveAt = this.getXmlAttributeValue(systemElement, "textArriveAt", this._textArriveAt);
		this._textFromTo = this.getXmlAttributeValue(systemElement, "textFromTo", this._textFromTo);
		this._textTotalDistance = this.getXmlAttributeValue(systemElement, "textTotalDistance", this._textTotalDistance);
		this._textTotalTime = this.getXmlAttributeValue(systemElement, "textTotalTime", this._textTotalTime);
		this._textViaQuickestRoute = this.getXmlAttributeValue(systemElement, "textViaQuickestRoute", this._textViaQuickestRoute);
		this._textViaShortestRoute = this.getXmlAttributeValue(systemElement, "textViaShortestRoute", this._textViaShortestRoute);
		this._textHoursMinutesSeconds = this.getXmlAttributeValue(systemElement, "textHoursMinutesSeconds", this._textHoursMinutesSeconds);
		this._textMinutesSeconds = this.getXmlAttributeValue(systemElement, "textMinutesSeconds", this._textMinutesSeconds);
		this._textSeconds = this.getXmlAttributeValue(systemElement, "textSeconds", this._textSeconds);
		
		this._textSetFrom = this.getXmlAttributeValue(systemElement, "textSetFrom", this._textSetFrom);
		this._textSetTo = this.getXmlAttributeValue(systemElement, "textSetTo", this._textSetTo);
		this._textGetRoute = this.getXmlAttributeValue(systemElement, "textGetRoute", this._textGetRoute);
		this._textRouteFromHere = this.getXmlAttributeValue(systemElement, "textRouteFromHere", this._textRouteFromHere);
		this._textRouteToHere = this.getXmlAttributeValue(systemElement, "textRouteToHere", this._textRouteToHere);
		
	},
	addPushpinsTypeWithXml : function(pushpinType, layer)
	{
		var pushpinTypeName;
		var pushpins = [];
		
		if (pushpinType != null) {
			pushpinTypeName = pushpinType.getAttribute("pushpinTypeName");
		}
		
		if (pushpinType != null && pushpinTypeName != null) {
			// default properties
			var nodeId =  this.getXmlAttributeValue(pushpinType, "nodeId", 0);
			var imageWidth = this.getXmlAttributeValue(pushpinType, "imageWidth", "150");
			var imageHeight = this.getXmlAttributeValue(pushpinType, "imageHeight", "150");
			var pushpinIconUrl = this.getXmlAttributeValue(pushpinType, "pushpinIconUrl", "");
			var detailsUrl = this.getXmlAttributeValue(pushpinType, "detailsUrl", "");
			var detailsText = this.getXmlAttributeValue(pushpinType, "detailsText", "More »");
			if (detailsText.length > 0 && '>.»'.indexOf(detailsText.substring(detailsText.length, detailsText), 0) < 0)
				detailsText = detailsText + ' »';
			
			
			var index = 0;
			for (index=0;index<pushpinType.childNodes.length;index++)
			{
				var point = pushpinType.childNodes[index];
				if (point.nodeType != 1) continue;
				if (point.tagName == 'pushpinType') {
					//	its a parent node	-	recurse thru
					if (!layer.childLayers)
					{
						layer.childLayers = [];
					}	
					var pointPushpinTypeName = point.getAttribute("pushpinTypeName");
					layer.childLayers[pointPushpinTypeName] = new Object();
					this.addPushpinsTypeWithXml(point, layer.childLayers[pointPushpinTypeName]);
				} else if (point.tagName == 'point') {
					//	its a leaf point
					var pointNodeId =  point.attributes.getNamedItem("nodeId").value; 
					var pin = this.addPoint(point, imageWidth, imageHeight , pushpinIconUrl , detailsUrl , detailsText, index);
					pushpins.push(pin);
					this._nodes[pointNodeId] = pushpins[pushpins.length - 1];	//	save for setVisibiltyByNodeId
					//	now add 1st default route finder if not already set
					if (this._indexOfpushpinType != null) {
						this.onRouteFromClick(this._indexOfpushpinType, pointNodeId);
						this.onRouteToClick(this._indexOfpushpinType, pointNodeId);
						this._indexOfpushpinType = null;
					}
				}
			}
			layer.pushpins = pushpins;		//	save for later re-use
			layer.visible = true;
			layer.name = pushpinTypeName;
			layer.CheckBox = this.getCheckBoxFromNodeId(nodeId);
			layer.PinType = 0;				//	it's a parent node
			this._nodes[nodeId] = layer;	//	save for setVisibiltyByNodeId
		}
		
		return pushpins;
	},
	addPoint : function(point, imageWidth, imageHeight , pushpinIconUrl , detailsUrl , detailsText, index)
	{
		//	its a leaf point
		var nodeId = point.attributes.getNamedItem("nodeId").value; 
		var hotelId = point.attributes.getNamedItem("id").value;
		var name = point.attributes.getNamedItem("hdg").value;
		var latitude = point.attributes.getNamedItem("la").value;
		var longitude = point.attributes.getNamedItem("lo").value;
		var imageUrl = point.attributes.getNamedItem("img").value;
		
		var description = this.getXmlNodeZeroText(point, "dsc");
		var detailsLink = this.getXmlNodeZeroText(point, "lnk");
		var displayId = point.attributes.getNamedItem("displayId").value;
		
		var routeFromText = this._textSetFrom ;
		var routeToText = this._textSetTo;
		var routeGetText = this._textGetRoute;
		var routeGetFromText = this._textRouteFromHere;
		var routeGetToText = this._textRouteToHere;
		
		if (imageUrl != null && imageUrl != "")
			description = " <br/><img src='" + imageUrl + "' alt=" + name + "'  width=" + imageWidth + " height=" + imageHeight + " />" 
				+ "<br/><br/>" + description;
		if (detailsUrl != null && detailsUrl != "")
			description += "<br/><br/><a href='" + detailsUrl + "hotelId=" + hotelId + "&index=" + index.toString() + "' target='_blank' >" + detailsText + "</a>";


		description += "<br/><div >"
					+ "<a class = 'imageLinkBlock' style='width:150px;' href='javascript: ByromMap.setRouteNodeIdFrom(" + nodeId.toString() + ");' title='" + routeFromText + "' >" + routeFromText + "</a>"
					+ "<a class = 'imageLinkBlock' style='width:150px;' href='javascript: ByromMap.setRouteNodeIdTo(" + nodeId.toString() + ");' title='" + routeToText + "' >" + routeToText + "</a>"								
//					+ "<a class = 'imageLinkBlock' style='width:150px;' href='javascript: ByromMap.getRouteFromNodeId(" + nodeId.toString() + ");' title='" + routeGetFromText + "' >" + routeGetFromText + "</a>"
//					+ "<a class = 'imageLinkBlock' style='width:150px;' href='javascript: ByromMap.getRouteToNodeId(" + nodeId.toString() + ");' title='" + routeGetToText + "' >" + routeGetToText + "</a>"
					+ "</div>";
		
		var pin = this.addPushpin(latitude, longitude, pushpinIconUrl, name, description, nodeId, displayId);
		//	save for centreing (invalid lat/lon crashes map)
		if (Math.abs(latitude) <= 180 && Math.abs(longitude) <= 180 && (latitude != 0 || longitude != 0)) {
			this._latitudeMin = Math.min(this._latitudeMin, latitude);
			this._latitudeMax = Math.max(this._latitudeMax, latitude);
			this._longitudeMin = Math.min(this._longitudeMin, longitude);
			this._longitudeMax = Math.max(this._longitudeMax, longitude);
		}
		
		return pin;
	},
	
	addPushpins : function()
	{
		/*this.addPushpin(40.6, -122.33, 'http://78.136.2.216/PreCheckIn/images/Accommodation/1001/150/GOLD REEF.JPG', 'My pushpin', 'This is pushpin number ' + (this._map.pushpins.length + 1).toString());
		this.addPushpin(45.6, -120.33, 'http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG', 'My pushpin', 'This is pushpin number ' + (this._map.pushpins.length + 1).toString());
		this.addPushpin(49.6, -110.33, '', 'My pushpin', 'This is pushpin number ' + (this._map.pushpins.length + 1).toString() + " <a href='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' target='_blank' >my image</a>"
				+ " <img src='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' alt='my image'/>" );
		*/		
		this.addPushpin(40.6, -122.33, 'http://cadpc001/PreCheckIn/images/Accommodation/20023/50/BLOEM POOL.jpg', 'My pushpin' + (this._map.pushpins.length + 1).toString(), 'This is pushpin number ' + (this._map.pushpins.length + 1).toString() + " <a href='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' target='_blank' >my image</a>"
				+ " <img src='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' alt='my image'/>" 
				+ "<br/><a href='javascript: ByromMap.deleteRoute();' >clear route</a>" 
				+ this.getRouteSelectHtml() 
				//+ "<br/><a href=\"javascript:ByromMap.closePreview();\" style='position:absolute;right:20px; bottom:20px;'>close</a>" 
				);
		this.addPushpin(45.6, -120.33, 'http://cadpc001/PreCheckIn/images/Accommodation/20023/50/DIAMOND LODGE BED.jpg', 'My pushpin' + (this._map.pushpins.length + 1).toString(), 'This is pushpin number ' + (this._map.pushpins.length + 1).toString() + " <a href='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' target='_blank' >my image</a>"
				+ " <img src='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' alt='my image'/>" 
				+ "<br/><a href='javascript: ByromMap.deleteRoute();' >clear route</a>" 
				+ "<br/><a href=\"javascript:ByromMap.closePreview();\" style='position:absolute;right:20px; bottom:20px;'>close</a>" );
		this.addPushpin(49.6, -110.33, '', 'My pushpin' + (this._map.pushpins.length + 1).toString(), 'This is pushpin number ' + (this._map.pushpins.length + 1).toString() + " <a href='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' target='_blank' >my image</a>"
				+ " <img src='http://78.136.2.216/PreCheckIn/images/Accommodation/1010/150/WANDERERS BED.JPG' alt='my image'/>" 
				+ "<br/><a href='javascript: ByromMap.getRoute();' >get route</a>" 
				+ "<br/><a href='javascript: ByromMap.deleteRoute();' >clear routes</a>" 
				+ "<br/><a href=\"javascript:ByromMap.closePreview();\" style='position:absolute;right:20px; bottom:20px;'>close</a>" );
		
		//VEMap.DeleteRoute();
	},
	addPushpin : function(latitude, longitude, imageUrl, name, description, nodeId, displayId)
	{
		return this.addPushpinWithStyle (latitude, longitude, imageUrl, name, description, this._iconStyle, this._titleStyle, this._previewStyle, nodeId, displayId);
	},
	addPushpinWithStyle : function(latitude, longitude, imageUrl, name, description, iconStyle, titleStyle, previewStyle, nodeId, displayId)
	{	
		imageUrl = Byrom.formatString(imageUrl, displayId);
		
		var pinID = this._map.pushpins.length + 1;
		
		//	bj	for image & text
		//<div style="font-size:smaller; font-weight:bold;  background-image:url(mapicon.jpg); width: 27px; height:30px; text-align:center; padding:6px 5px 0px 0px;">1</div>
		
		
		//var pin = new VEPushpin(pinID, new VELatLong(latitude, longitude), imageUrl, name, description, iconStyle, titleStyle, previewStyle);
		//this._map.AddPushpin(pin);
		
		var pin = new VEShape(VEShapeType.Pushpin, new VELatLong(latitude, longitude));
		pin.SetCustomIcon(imageUrl);
		pin.SetTitle(name);
		pin.SetDescription(description);
		// pin.SetMoreInfoURL("http://msdn.microsoft.com");	//	not needed
		
		this._map.AddShape(pin);	
		var shapeId = pin.GetID();	//	shapeId : internal id used in map.getShapeById
		
		//	save separate object as 'on pin deleted from map', 'var pin' above is garbage collected and loses some (but not all) of it's properties (ID, LatLong etc)
		var checkBox = this.getCheckBoxFromNodeId(nodeId);
		var byromPin = new ByromMaps.Mapping.MapPin(pinID, latitude, longitude, imageUrl, name, description, iconStyle, titleStyle, previewStyle, nodeId, shapeId, checkBox, displayId);
		byromPin.PinType = 1;	//	leaf node
		return byromPin;
	},
	getCheckBoxFromNodeId : function(nodeId)
	{
		var elem = document.getElementById(this._treeViewId + "n" + nodeId.toString() + "CheckBox");
		return elem;
	},
	addClickHandler : function(id)
	{
		var elem = document.getElementById(id);
		if (elem) {
			elem.onclick = ByromMenu.toggleSubMenuEvent;
		}
	},
	toggleSubMenuEvent : function()
	{
		//	note : 'this' is the object raising the event
		ByromMenu.toggleSubMenu(this.id + _byromSubMenuIdSuffix);		
	},
	
	toggleSubMenu : function(id)
	{
		// ByromMenu.disableSubMenus();
		//ByromMenu.setStyleDisplay(id, 'block');
		ByromMenu.setStyleDisplayToggle(id);
	},
	
	enableSubMenuEvent : function()
	{
		//	note : 'this' is the object raising the event
		ByromMenu.enableSubMenu(this.id + _byromSubMenuIdSuffix);		
	},
   
	enableSubMenu : function(id)
	{
		ByromMenu.disableSubMenus();
		ByromMenu.setStyleDisplay(id, 'block');
	},
	disableSubMenus : function()
	{
		var elem = document.getElementById(_byromSubMenuContainerId);
		if (elem) {
		  for(index=0; index< elem.childNodes.length; index++)
		  {
			if (elem.childNodes[index].style)
			  elem.childNodes[index].style.display = 'none';
		  }
		}
	},

	setStyleDisplay : function(id, value)
	{
		var elem = document.getElementById(id);
		if (elem)
			elem.style.display=value;
	},
	setStyleDisplayToggle : function(id)
	{
		var elem = document.getElementById(id);
		if (elem && elem.style) {
			if (elem.style.display == 'block')
				elem.style.display='';
			else
				elem.style.display='block';
		}
	}
	
	/************************************************************************************************************
	************************************************************************************************************
		OLD (UNUSED) CODE (START OF)
	************************************************************************************************************
	************************************************************************************************************/
	
	/*
	onGotRoute : function(route)
	{
		//TODO:	internationalise this (route Text's are implemented in v6 qtr1 so just add to .Options when available)
		//			all other text need to come from server
		
		var elem = document.getElementById(this._routeDirectionsElementId);	//	usually a div
		if (elem) {
			
			var distanceUnit = this._routeOptions.DistanceUnit;
			if (distanceUnit == VERouteDistanceUnit.Mile)
				distanceUnit = "m";
			else
				distanceUnit = "km";
			
			var turns = "<h3>Turn-by-Turn Directions</h3>(rounding errors are possible)";
			turns += "<p><b>Distance:</b> " + route.Distance.toFixed(1) + " miles";
			turns += "<br/><b>Time:</b> " + this.GetTimeAsString(route.Time) + "</p>";

			var steps="";
			steps += "<TABLE class=\"routeFinderDirectionsText\">\n";
			// steps += "<CAPTION>Steps</CAPTION>\n";
			//	column captions
			steps += "<TR class=\"routeFinderDirectionsTextHdr\">" + "<TH>" + "<B>Step</B>"
					+ "<TD>" + "<B>Total</B>"
					+ "<TD>" + "<B>Distance</B>"
					+ "<TD>" + "<B>Direction</B>" + "\n";
			
			var totalDistance = 0;
			var totalTime = 0;
			
			var legs		  = route.RouteLegs;
			var leg		   = null;
			var turnNum	   = 0;  // The turn #

		   // Get intermediate legs
		   var legLen = legs.length;
		   for(var legIndex = 0; legIndex < legs.length; legIndex++)
		   {
				// Get this leg so we don't have to derefernce multiple times
				leg = legs[legIndex];  // leg is a VERouteLeg object
				
				totalTime += leg.Time;
				var legNum = legIndex + 1;
				turns += "<br/><b>Distance for leg " + legNum + ":</b> " + leg.Distance.toFixed(1) + " miles" +
					"<br/><b>Time for leg "	 + legNum + ":</b> " + this.GetTimeAsString(leg.Time) + "<br/><br/>";

				// Unroll each intermediate leg
				var turn		= null;  // The itinerary leg
				var legDistance = null;  // The distance for this leg

				
				var len = leg.Itinerary.Items.length;
				for(var itineraryIndex = 0; itineraryIndex < len ;itineraryIndex++)
				{
					turnNum++;
					turn = leg.Itinerary.Items[itineraryIndex];  // turn is a VERouteItineraryItem object
					turns += "<b>" + turnNum + "</b>\t" + turn.Text;
					legDistance	= turn.Distance;

					var distance = leg.Itinerary.Items[itineraryIndex].Distance;
					if (distance == null)
						distance = 0;
					var cl = " class=\"routeFinderDirectionsTextRow\"";
					if ((itineraryIndex % 2) != 0)
						cl = " class=\"routeFinderDirectionsTextRowAlt\"";
					var instruction = leg.Itinerary.Items[itineraryIndex].Text;
					if (legIndex == 0 && itineraryIndex == 0)
						instruction = "Start at " + this._routePushpinFrom.Title;
					else if (legIndex == (legLen - 1) && itineraryIndex == (len - 1))
						instruction = "Arrive at " + this._routePushpinTo.Title;
					
					steps += "<TR" + cl + ">" + "<TH>" + (itineraryIndex + 1) 
							+ "<TD>" + "" + Math.round(totalDistance*10)/10 + " " + distanceUnit + " "
							+ "<TD>" + "" + Math.round(distance*10)/10 + " " + distanceUnit + " "
							+ "<TD>" + instruction + "\n";
					
					totalDistance += distance;
				}
			}
			steps += "</TABLE>\n";
			
			var fromTo = "";
			if (this._routePushpinFrom != null && this._routePushpinTo != null)
			{
				fromTo = "From <B>" + this._routePushpinFrom.Title + "</B> to <B>" + this._routePushpinTo.Title + "</B><br />";
			}
			
			var routeinfo=fromTo
				+ "Total distance: "
				+ Math.round(totalDistance*10)/10 +" "	//	route.Itinerary.Distance seems to be slightly out
				+ distanceUnit+"<br />"
				+ "Total Time: " + this.GetTimeAsString(totalTime) +"<br />";
			if (this._routeOptions.RouteOptimize == VERouteOptimize.MinimizeTime) // "q")
				routeinfo += "Via quickest route";
			else
				routeinfo += "Via shortest route";
			
			routeinfo+="<br />"+steps;
			elem.innerHTML = routeinfo;	
		}
	},
	onGotRoute: function(route)
	{
		var elem = document.getElementById(this._routeDirectionsElementId);	//	usually a div
		if (elem) {
			
			var steps="";
			steps += "<TABLE class=\"routeFinderDirectionsText\">\n";
			// steps += "<CAPTION>Steps</CAPTION>\n";
			//	column captions
			steps += "<TR class=\"routeFinderDirectionsTextHdr\">" + "<TH>" + "<B>Step</B>"
					+ "<TD>" + "<B>Total</B>"
					+ "<TD>" + "<B>Distance</B>"
					+ "<TD>" + "<B>Direction</B>" + "\n";
			
			var totalDistance = 0;
			var len = route.Itinerary.Segments.length;
			for(var i = 0; i < len ;i++)
			{
				var distance = route.Itinerary.Segments[i].Distance;
				if (distance == null)
					distance = 0;
				var cl = " class=\"routeFinderDirectionsTextRow\"";
				if ((i % 2) != 0)
					cl = " class=\"routeFinderDirectionsTextRowAlt\"";
				var instruction = route.Itinerary.Segments[i].Instruction;
				if (i == 0)
					instruction = "Start at " + this._routePushpinFrom.Title;
				else if (i == (len - 1))
					instruction = "Arrive at " + this._routePushpinTo.Title;
				
				steps += "<TR" + cl + ">" + "<TH>" + (i + 1) 
						+ "<TD>" + "" + Math.round(totalDistance*10)/10 + " " + route.Itinerary.DistanceUnit + " "
						+ "<TD>" + "" + distance + " " + route.Itinerary.DistanceUnit + " "
						+ "<TD>" + instruction + "\n";
				
				totalDistance += distance;
			}
			steps += "</TABLE>\n";
			
			var fromTo = "";
			if (this._routePushpinFrom != null && this._routePushpinTo != null)
			{
				fromTo = "From <B>" + this._routePushpinFrom.Title + "</B> to <B>" + this._routePushpinTo.Title + "</B><br />";
			}
			
			var routeinfo=fromTo
				+ "Total distance: "
				+ Math.round(totalDistance*10)/10 +" "	//	route.Itinerary.Distance seems to be slightly out
				+ route.Itinerary.DistanceUnit+"<br />"
				+ "Total Time: " + route.Itinerary.Time+"<br />";
			if (route.Itinerary.RouteType == VERouteType.Quickest) // "q")
				routeinfo += "Via quickest route";
			else
				routeinfo += "Via shortest route";
			
			routeinfo+="<br />"+steps;
			elem.innerHTML = routeinfo;	
		}
	}
	
	*/
	
	/************************************************************************************************************
	************************************************************************************************************
		OLD (UNUSED) CODE (END OF)
	************************************************************************************************************
	************************************************************************************************************/
};


ByromMaps.Mapping.MapPin = function(iD, latitude, longitude, iconUrl, title, details, iconStyle , titleStyle , detailsStyle, nodeId, shapeId, checkBox, displayId) 
{
		/// <summary>
		/// creates a simple mapping pin object to hold pin values
		/// </summary>
		/// <param name="iD" type="int" DomElement="false" mayBeNull="false" />
		/// <returns />
		
		// var newPin = new VEPushpin(pin.ID, pin.LatLong, pin.IconUrl, pin.Title, pin.Details, pin.IconStyle, pin.TitleStyle, pin.DetailsStyle);
		// Properties
		this.ID = iD;
		this.Latitude = latitude;
		this.Longitude = longitude;		//Icon style class name
		this.IconUrl = iconUrl;			//	Icon Url
		this.Title = title;				//Preview style class name
		this.Details = details;			//id of element containing xml pushpin point data 
		this.IconStyle = iconStyle;		//xml pushpin point data  (should we use json ?)
		this.TitleStyle = titleStyle;
		this.DetailsStyle = detailsStyle;
		this.NodeId = nodeId;
		this.ShapeId = shapeId;			//	the id of the actual map shape object
		this.CheckBox = checkBox;		//	checkbox html control
		this.DisplayId = displayId;		//	display number (to match displayed hotel list)
		this.PinType = 1;				//	pin type :	0 = parent node (has child pushpins and possibly a parent too)
										//				1 = leaf node (has NO child pushpins)
		
		// Variables
		this.Visible = true;	//	default to all displayed
		this.IconUrlOriginal = iconUrl;	//	original icon url	(this.IconUrl overwritten by from/to route)

		// Delegates
		// this._imageLoadedHandler = null;
		
		// Setup
		// this.initialize(mapId);	
};


//	create after page loaded
window.onload = ByromMappingOnLoad;