		// JavaScript Document
		// RouteViwer.js $Rev: 107 $
		// Declare the global variables

		var route="unselected";
		var stage="unselected";
		var routes = [];
		var bounds;
		var routeIndex;
		var stageIndex;
		
		var mapIcons = [];

		mapIcon = new MapIcon('icons/stage.png');			// 0 = Polylines
		mapIcons.push(mapIcon);
		mapIcon = new MapIcon('icons/information.png');	// 1 = Points of Interest
		mapIcon.icon=createIcon(mapIcon);
		mapIcon.visibility=true;
		mapIcons.push(mapIcon);
		mapIcon = new MapIcon('icons/signage.png');		// 2 = Signage
		mapIcon.iconW = 34;
		mapIcon.icon=createIcon(mapIcon);
		mapIcons.push(mapIcon);
		mapIcon = new MapIcon('icons/triangle.png');		// 3 = Milestone
		mapIcons.push(mapIcon);
		mapIcon.icon=createIcon(mapIcon);		
		mapIcon = new MapIcon('icons/train.png');			// 4 = Train station
		mapIcon.visibility=true;
		mapIcon.iconH=20;
		mapIcon.iconW=40;
		mapIcon.shadH=20;
		mapIcon.shadW=50;
		mapIcon.iconX=20;
		mapIcon.iconY=20;
		mapIcon.infoX=20;
		mapIcon.infoY=0;
		mapIcon.icon=createIcon(mapIcon);
		mapIcons.push(mapIcon);
		
		// Declare the main JavaScript objects

		function Route(routeID) {
			this.routeID=routeID;
			this.name="";
			this.stageList="";
			this.stages=[];
			this.img="";
			this.height="";
			this.width="";
			this.owner="";
			this.seq="";
		}

		function Stage(stageID) {
			this.stageID=stageID;
			this.name="";
			this.colour="";
			this.polylines=[];
			this.markers=[];
			this.center=0;
			this.zoomLevel=0;
			this.on=false;
			this.loaded=false;
			this.owner="";
			this.seq="";
		}

		function Polyline(polylineID) {
			this.polylineID=polylineID;
			this.featureCode=0;
			this.gObject='removed';
			this.points="";
			this.levels="";
			this.colour="";
			this.width="";
			this.owner="";
			this.vertices=[];
			this.status="loaded";
			this.gpxFile="";
		}
		
		function MapIcon(imageURL) {
			this.imageURL=imageURL;
			this.iconW = 20;
			this.iconH = 34;
			this.shadW = 36;
			this.shadH = 34;
			this.iconX = 5;
			this.iconY = 34;
			this.infoX = 5;
			this.infoY = 2;
			this.visibility = true;
			this.icon="";
		}
		
		function Marker(pointID) {
			this.pointID=pointID;
			this.featureCode="";
			this.points=[];
			this.name="";
			this.text="";
			this.img="";
			this.height="";
			this.width="";
			this.size="";
			this.popupW="";
			this.popupH="";
			this.href="";
			this.gObject='removed';
			this.owner="";
		}
		
		// now define the working functions


		function testLine(){
//		points="_gkxEr}|vNcBwBoAoA{Jg@cBcBoA{@S?uBoA}@wBS_DbBwhATg@c[sDiT}\\g@i@{@S{@{@ScBRSnAg@SoAS{Eg@kCkClH?nAoF`LQRU{E~CgJ?g@jCqNrNcGz@?zJyBf@y@~CmC{@zJ?f@mAnA?f@x@z@bBR~HsIRe@jClKRz@`Dh@`Bd@vBRnF_DRSg@S?wBpFcGd@SScBwBvB{@T_D~Cg@?oA`B{@R{E~CqD{EUgJwB{@nAoA?kChJrIdJaBz@i@f@_DdBf@dEgEnFcGoP_N{@SeTvBqKoA{J_SsDoF?_Df@{@vB_XoAoPbLoZrDcBy@{EmC_D{ToAy@g@?_DlAgEgEcLg@g@qDnAqAkR_DyJy@i@mC?g@{@}CqNi@i@_ISoK_g@g@{@{EiCiCd@g@z@yGfOwBnAoARyJ_DuDRoAg@_D_IoKyEcGk\\gOx@cGy@{@}@sI_DcGgEwLbBuBRmCe@{JgOS}Jy@{@kHcBy[_]gEmPnA}Ef@g@vGwBgEa[rDqP|h@w[hMoFzJ{J~HwL{@_DoAkCcGwBuBgJyBoA_SfJiCz@{Jz@yBg@oU{OkCkCf@cLbBsIy@iCyGeB}H{@mCnFoAvB}ReEyGaIpFsSx@iHoAmCkHkCQ{JmM{TS_DvBuG?qFR{@vBoA~Hg@bBoAlCuL}@cG_IcGyEi@?sNUy@{@}@wLvBuB?aIcGgTgOSwLS_DoFoFwQTsDUg^kW}Hwe@U_DrI_l@|@_Dx@g@fTbBjC?j\\sD|OgEdJcGnAwBaB{EuDoAaLcB}J{JqDjCee@wGsD{JoAwB_X?cB{@g@g@kCqSkf@ye@gJkWoi@_]{JgESkHcBkHco@u[{Od@{@e@sIa]{@gJk\\kMkHoF_NgJcG?oAaBoAyGcBoAgESgYvG{@?wB_NcBgO~HoFrI_I~a@_]rNcVzJoAnU_q@nA{@rIsDrDsIwG_Ng@}CjMa]bBcGz@g@nF|@z@i@sDa[vGiYvBoAfJ_Dz@_DgEoKoA_NdBuL`VkWvLmH_Ie@kH?wB|Ce^|TyBx@cL?f@{T{@yEcQyBoFfEoKtDeJPmCoFg@{@gO}Huj@oA}OgOaBeBwQf@}@?mFsIyB_DyE_DaXrDcGrDbBkCvBgE{JsSoKsIqDSuDkHR{@xB?lAbBcBR";
//		levels="P?CFDEADGDHBGIBDCEADCFDECFADFBFGCFCEEBDBCDGBEBFHDEABDFBCCDEBFCEFEDCFFECFGEFFCGEHEDCJFGDEDFGHDFBEGECFCIBEGCEDFFGHEFCGEKFECGEHDEFGCEIFDEFGHGHIFDEFGDFGEFJDFEDGEFDGHFEGEFIDEFBDGDFEFGHBDFDGLEFEGDHGDIDCFGHFGDEDFGDHEFGDBFJFHEFEIFCGKGEHEDFDEGCIEFGHFGICFEGDHJCECFGDHDFEGIFEFDGDHFDGEFGICFHFDGCJDEGEDEMFDGBDEP";


			var requestLine = GXmlHttp.create();
			var elements = [];
			requestLine.open('GET', 'getEncodedLines.php' , false);	// request XML from PHP with AJAX call
			requestLine.send(null);
			
			var xmlDoc = requestLine.responseXML;
			elements = xmlDoc.documentElement.getElementsByTagName("line");
			if (elements.length){
				for (var i = 0; i < elements.length; i++) { // cycle thru elements
					points=(elements[i].getAttribute("points"));
					levels=(elements[i].getAttribute("levels"));
					minLat=(elements[i].getAttribute("minLat"));
					minLng=(elements[i].getAttribute("minLng"));
					maxLat=(elements[i].getAttribute("maxLat"));
					maxLng=(elements[i].getAttribute("maxLng"));
					
		newLine= GPolyline.fromEncoded({
  color: "#00ffff",
  weight: 4,
  opacity: 1.0,
  points: points,
  levels: levels,
  zoomFactor: 2,
  numLevels: 18
});
					map.addOverlay(newLine);
					sw= new GLatLng(minLat,minLng);
					ne= new GLatLng(maxLat,maxLng);
					bounds=new GLatLngBounds(sw,ne);
					center=bounds.getCenter();
					zoomLevel=map.getBoundsZoomLevel(bounds);
					map.setCenter(center, zoomLevel);
				}
			}

		}

			
		function displayRouteList(editMode){
//			alert("v2.78?");
			routeList_html='Routes<br/>';
			routes=new Array();
			route="unselected";
			stage="unselected";
			var requestRoutes = GXmlHttp.create();
			var elements = [];
			requestRoutes.open('GET', 'getRoutes.php' , false);	// request XML from PHP with AJAX call
			requestRoutes.send(null);

					var xmlDoc = requestRoutes.responseXML;
					elements = xmlDoc.documentElement.getElementsByTagName("route");
					if (elements.length){
						for (var i = 0; i < elements.length; i++) { // cycle thru elements
							route = new Route(elements[i].getAttribute("routeID"));
							route.name=elements[i].getAttribute("name");
							route.owner=elements[i].getAttribute("owner");
							route.img=elements[i].getAttribute("img");
							route.height=elements[i].getAttribute("height");
							route.width=elements[i].getAttribute("width");
							route.owner=elements[i].getAttribute("owner");
							route.seq=elements[i].getAttribute("seq");
							routes.push(route);
							routeList_html += '<div class="listRow"><input style="float:left;" type="radio" name="rbRoute" '; 
							routeList_html += 'onclick="displayStageList(' + editMode+','+i +')"/>'+ routeHTML(route) +'</div><br/>';
						}
					document.getElementById("routeList").innerHTML = routeList_html;
					document.getElementById("stageList").innerHTML = 'STAGE LIST ...will appear here when you click a route button.';
					route="unselected";
					}

		}
		
		
		function displayStageList(editMode,i){
			routeIndex=i;
			route = routes[routeIndex];
			if (!route.stageList == ""){
			document.getElementById("stageList").innerHTML = route.stageList;
			return;
			}
			if ( route.routeID > 0 ) {
				stageList_html='<div>Route '+route.routeID+' Stages<p/>';
			}
			else {
				stageList_html='<div>Selected Route Stages<p/>';
			}
			document.getElementById("stageList").innerHTML = stageList_html;
			requestStages = GXmlHttp.create();
			var elements = [];
			requestStages.open('GET', 'getStages.php?routeID='+route.routeID , false);	// request XML from PHP with AJAX call
			requestStages.send(null);

			var xmlDoc = requestStages.responseXML;
			elements = xmlDoc.documentElement.getElementsByTagName("stage");
			if (elements.length){
				for (var i = 0; i < elements.length; i++) { // cycle thru elements
					stage = new Stage(elements[i].getAttribute("stageID"));
					stage.name=elements[i].getAttribute("name");
					stage.colour=elements[i].getAttribute("colour");
					stage.owner=elements[i].getAttribute("owner");
					stage.seq=elements[i].getAttribute("seq");
					route.stages.push(stage);
					if(editMode){
						stageList_html += '<div class="listRow"><input  style="float:left;" type="radio" name="rbStage" onclick="stagePushed(' + routeIndex + ',' + i + ')"> '+'<div  style="color: ' + stage.colour +'"><em>'+stage.name+ '</em></div></div><br/>';
					}
					else{
						stageList_html += '<div class="listRow"><input type="checkbox" onclick="stageTicked(' + routeIndex + ',' + i + ')"> '+'<a  style="color: ' + stage.colour +'" href="javascript:stageLinked(' + routeIndex + ',' + i + ')"><em>'+stage.name+ '</em></a></div><br/>';
					}
				}
			route.stageList+='</div>';	
			route.stageList=stageList_html;
			document.getElementById("stageList").innerHTML = stageList_html;
			stage="unselected";
			}
		}

		function stageTicked(routeIndex, stageIndex) {
			stage=routes[routeIndex].stages[stageIndex];
			if (stage.on) {
				untickCache(routeIndex, stageIndex);
				removeStage(stage);
			}
			else {
				tickCache(routeIndex, stageIndex);
				addStage(stage);
			}
		}
		
		function tickCache(routeIndex, stageIndex) {
			stage=routes[routeIndex].stages[stageIndex];
			findStr = 'stageTicked(' + routeIndex + ',' + stageIndex + ')"';
			replaceStr = findStr + ' checked' ;
			result=routes[routeIndex].stageList.replace(findStr,replaceStr);
			routes[routeIndex].stageList=result;
		}

		function untickCache(routeIndex, stageIndex) {
			stage=routes[routeIndex].stages[stageIndex];
			findStr= 'stageTicked(' + routeIndex + ',' + stageIndex + ')"'  + ' checked';
			replaceStr = 'stageTicked(' + routeIndex + ',' + stageIndex + ')"';
			result=routes[routeIndex].stageList.replace(findStr,replaceStr);
			routes[routeIndex].stageList=result;
		}

		function stageLinked(routeIndex, stageIndex) {
			stage=routes[routeIndex].stages[stageIndex];
			if (!stage.on) {
				tickCache(routeIndex, stageIndex);
				displayStageList(false,routeIndex);
			}
			addStage(stage);
		}

		function loadStage(stage){
			var elements = [];
			bounds = new GLatLngBounds();
			requestPolylines = GXmlHttp.create();
			requestPolylines.open('GET', 'getPolylines.php?stageID='+ stage.stageID , false);	// request XML from PHP with AJAX call
			requestPolylines.send(null);

			var xmlDoc = requestPolylines.responseXML;
			elements = xmlDoc.documentElement.getElementsByTagName("polyline");
			if (elements.length){
				finalPolyline = false;
				for (var i = 0; i < elements.length; i++) { // cycle thru elements
					if ( i == elements.length - 1){
						finalPolyline = true;
					}
					var polyline = new Polyline (elements[i].getAttribute("polylineID"));
					polyline.colour=elements[i].getAttribute("colour");
					polyline.width=elements[i].getAttribute("width");
					polyline.owner=elements[i].getAttribute("owner");
					polyline.gpxFile=elements[i].getAttribute("gpxFile");
					polyline.status="loaded";
					loadVertices(polyline, stage, finalPolyline);					
//					loadLines(polyline, stage, finalPolyline);
				}
			}
		}
		
		function loadVertices(polyline, stage, finalPolyline){
		//	alert("loading vertices");
			var points=[];
			var requestVertices = GXmlHttp.create();
			requestVertices.open('GET', "getVertices.php?polylineID="+polyline.polylineID , false);	// request XML from PHP with AJAX call
			requestVertices.send(null);

					var xmlDoc = requestVertices.responseXML;
					var vertices = [];
					vertices = xmlDoc.documentElement.getElementsByTagName("vertex");
					if (vertices.length){
						for (var i = 0; i < vertices.length; i++) { // cycle thru vertices
							var point = new GLatLng(vertices[i].getAttribute("lat"),vertices[i].getAttribute("lng"));
							points.push(point);
							bounds.extend(point);
						}
/*
				testLine=new GPolyline(points, "blue", 1, 1.0);
				map.addOverlay(testLine);
*/
						polyline.vertices=points;
						stage.polylines.push(polyline);

						if(finalPolyline){
								loadMarkers(stage);
						}

					}
		}


		function loadLines(polyline, stage, finalPolyline){
			var requestLine = GXmlHttp.create();
//			alert("getEncodedLines.php?lineID="+polyline.polylineID);
			requestLine.open('GET', 'getEncodedLines.php?lineID='+polyline.polylineID , false);	// request XML from PHP with AJAX call
			requestLine.send(null);
			
			var xmlDoc = requestLine.responseXML;
			elements = xmlDoc.documentElement.getElementsByTagName("line");
			if (elements.length){
				for (var i = 0; i < elements.length; i++) { // cycle thru elements
					// normally elements.length should be == 1
					polyline.points=(elements[i].getAttribute("points"));
					polyline.levels=(elements[i].getAttribute("levels"));
					minLat=(elements[i].getAttribute("minLat"));
					minLng=(elements[i].getAttribute("minLng"));
					maxLat=(elements[i].getAttribute("maxLat"));
					maxLng=(elements[i].getAttribute("maxLng"));
					sw= new GLatLng(minLat,minLng);
					ne= new GLatLng(maxLat,maxLng);
					bounds.extend(sw);
					bounds.extend(ne);
					stage.polylines.push(polyline);
				}
			}

			if(finalPolyline){
				loadMarkers(stage);
			}
		}

		function loadMarkers(stage){
			var points=[];
			var requestPoints = GXmlHttp.create();
			requestPoints.open('GET', "getPoints.php?stageID="+stage.stageID , false);	// request XML from PHP with AJAX call
			requestPoints.send(null);
			var xmlDoc = requestPoints.responseXML;

			points = xmlDoc.documentElement.getElementsByTagName("point");
			if (points.length){
				for (var i = 0; i < points.length; i++) { // cycle thru points
					var point = new GLatLng(points[i].getAttribute("lat"),points[i].getAttribute("lng"));
					var marker = new Marker(points[i].getAttribute("pointID"));
					marker.featureCode=points[i].getAttribute("type");
					marker.points[0]=point;
					marker.name=points[i].getAttribute("name");
					marker.text=points[i].getAttribute("text");
					marker.img=points[i].getAttribute("img");
					marker.height=points[i].getAttribute("height");	
					marker.width=points[i].getAttribute("width");
					marker.size=points[i].getAttribute("size");
					marker.href=points[i].getAttribute("href");
					marker.owner=points[i].getAttribute("owner");
					marker.popupH=points[i].getAttribute("popupH")=="0"?2*marker.height:points[i].getAttribute("popupH");
					marker.popupW=points[i].getAttribute("popupW")=="0"?marker.width:points[i].getAttribute("popupW");
					if (marker.text=="" && points[i].getAttribute("popupH")=="0"){
						marker.popupH=marker.height/2+300;
					}
					stage.markers.push(marker);
					bounds.extend(point);
				}
			}
			center=bounds.getCenter();
			zoomLevel=map.getBoundsZoomLevel(bounds);
			stage.center=center;
			stage.zoomLevel=zoomLevel;
			stage.loaded=true;
		}
		
		function markerHTML(m){
			var html="";
			if (m.name!="") html += '<em>'+m.name+'</em><br/>';
			if (m.text!="") {
				var text=new String(m.text);
				text = text.replace(/\[/g,"<");
				text = text.replace(/\]/g,">");		
				html += text+'<br/>';
			}
			if (m.img!="") {
//				alert(m.size);
				if(m.size!=""){
					if (m.size.indexOf("!")==-1){
						html += '<img src="../files/images/'+m.img.replace('.','.'+m.size+'.')+'" width='+m.width+' height='+m.height+'></img><br/>';
					}
					else{
						html += '<img src="../files/images/'+m.img.replace('.','.'+m.size+'.')+'" width='+m.width+' height='+m.height+'></img><br/>';
						html = html.replace('!','');
						html += 'Click <a target="_blank" href="../files/images/'+m.img+'">here</a>&nbsp;for a bigger picture.<br/>';
					}
//					alert(html);
				}
				else{
					if (m.img.indexOf("_tn.")==-1){
						html += '<img src="../gmaps/images/'+m.img.replace('.','_tn.')+'" width='+m.width+' height='+m.height+'></img><br/>';
						html += 'Click <a target="_blank" href="../gmaps/images/'+m.img+'">here</a>&nbsp;for a bigger picture.<br/>';
					}
					else{
						html += '<img src="../gmaps/images/'+m.img+'" width='+m.width+' height='+m.height+'></img><br/>';
					}
				}
			}
			if (m.href!=""){
				href = m.href.replace(/~/g,"&"); 
				html += 'more info: click <a target="_blank" href="'+href+'">here</a>.<br/>';
			}
			return html;
		}
		
		function routeHTML(r){
			var html="";
			if (r.img!="") html += '<img class="listIcon" src="icons/'+r.img+'" width='+r.width+' height='+r.height+'/>';
			if (r.name!="") html += '<div class="listItem">' + r.name + '</div>';
			html += '<br/>';
			return html;
		}

		function addMarkersByStage(stage){
			for (var i = 0; i < stage.markers.length; i++) { // display each overlay
				if (mapIcons[stage.markers[i].featureCode].visibility) {
					if (stage.markers[i].gObject == 'removed') {
						stage.markers[i].gObject = createMarker(stage.markers[i].points[0],mapIcons[stage.markers[i].featureCode],markerHTML(stage.markers[i]));
						map.addOverlay(stage.markers[i].gObject);
					}
				}
			}
		}

		function removeMarkersByFeatureCode(featureCode){
			for (var i = 0; i < routes.length; i++) {
				for (var j = 0; j < routes[i].stages.length; j++) {
					for (var k = 0; k < routes[i].stages[j].markers.length; k++) {
						var overlay = routes[i].stages[j].markers[k];
						if (overlay.featureCode == featureCode) {
							map.removeOverlay(overlay.gObject);
							overlay.gObject='removed';
						}
					}
				}
			}
		}

		function addMarkersByFeatureCode(featureCode){
			for (var i = 0; i < routes.length; i++) {
				for (var j = 0; j < routes[i].stages.length; j++) {
					if (!routes[i].stages[j].on) {
						continue;
					}
					for (var k = 0; k < routes[i].stages[j].markers.length; k++) {
						if (routes[i].stages[j].markers[k].featureCode == featureCode) {
							if (routes[i].stages[j].on) {
								if ( routes[i].stages[j].markers[k].gObject == 'removed' ) {
									routes[i].stages[j].markers[k].gObject = createMarker(routes[i].stages[j].markers[k].points[0],mapIcons[routes[i].stages[j].markers[k].featureCode],markerHTML(routes[i].stages[j].markers[k]));
									map.addOverlay(routes[i].stages[j].markers[k].gObject);
								}
							}
						}
					}
				}
			}
		}

		function removeStage(stage){
			for (var i = 0; i < stage.polylines.length; i++) { // display each overlay
				map.removeOverlay(stage.polylines[i].gObject);
				stage.polylines[i].gObject='removed';
			}
			for (var i = 0; i < stage.markers.length; i++) { // display each overlay
				map.removeOverlay(stage.markers[i].gObject);
				stage.markers[i].gObject='removed';
			}
			stage.on=false;
		}

		function addStage(stage){
			if (!stage.loaded){
				loadStage(stage);
			}
			if (stage.center!=0){
				map.setCenter(stage.center, stage.zoomLevel);
			}
			if (stage.on){
				return;
			}
			for (var i = 0; i < stage.polylines.length; i++) { // display each overlay
				var polyline = stage.polylines[i];
				if (polyline.status=='deleted') continue;
				/*
				polyline.gObject=GPolyline.fromEncoded({
				  	color: polyline.colour,
  					weight: polyline.width,
  					opacity: 1.0,
  					points: polyline.points,
  					levels: polyline.levels,
  					zoomFactor: 2,
  					numLevels: 18
				}); 
				map.addOverlay(polyline.gObject);
				*/
				polyline.gObject=new GPolyline(polyline.vertices, polyline.colour, polyline.width, 1.0);
				map.addOverlay(polyline.gObject);
			}
			stage.on=true;
			addMarkersByStage(stage);
		}
		
		function createIcon(mapIcon){
			icon=new GIcon();
			icon.image=mapIcon.imageURL;
//			alert(mapIcon.imageURL);
			icon.iconSize = new GSize(mapIcon.iconW, mapIcon.iconH);
			icon.shadow=mapIcon.imageURL.replace('.png','_shadow.png');
			icon.shadowSize = new GSize(mapIcon.shadW, mapIcon.shadH);
			icon.iconAnchor = new GPoint(mapIcon.iconX, mapIcon.iconY);
			icon.infoWindowAnchor = new GPoint(mapIcon.infoX, mapIcon.infoY);
			return icon;
		}
		

		function createMarker(point,icon,html) {
			var marker = new GMarker(point,icon);
			GEvent.addListener(marker, "click", function() {
			  marker.openInfoWindowHtml(html);
			});
			return marker;
		}

		function featureTicked(featureCode){
//			var status = mapIcons[featureCode].visibilty;
			if (mapIcons[featureCode].visibility){
				mapIcons[featureCode].visibility=false;
				removeMarkersByFeatureCode(featureCode);
			}
			else {
				mapIcons[featureCode].visibility=true;
				addMarkersByFeatureCode(featureCode);
			}
		}

