

// RoutePlanner code here

var RoutePlanner = {};

RoutePlanner = {
  init: function(){
	    OpenLayers.Renderer.SVG.prototype.supported = function() {
        var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
        return (document.implementation &&
           (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
            document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
            document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
        };

      osMap = new OpenSpace.Map('map');
	  //osMap = new OpenLayers.Map('map');
	//var options = {
    //	maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
    //	maxResolution: 156543,
    //	units: 'm',
    //	projection: "EPSG:41001"
	//};
	//osMap = new OpenLayers.Map("map",options);
	//osMap.setMaxEntent(new OpenLayers.Bounds(-200000, -200000, 200000, 200000));

      var point = OS.NGR2NE_wtp('SH720583');
      //osMap.setCenter(new OpenSpace.MapPoint(439300, 114760), 8);
      osMap.setCenter(point,7);

      markers = new OpenLayers.Layer.Markers("Markers");
      osMap.addLayer(markers);

        vectorLayer = new OpenLayers.Layer.Vector("Vector Layer");
        osMap.addLayer(vectorLayer);

		// TODO redo this in pure OpenLayers
		screenOverlay = new OpenSpace.Layer.ScreenOverlay("coords");
		screenOverlay.setPosition(new OpenLayers.Pixel(0, 470));
		osMap.addLayer(screenOverlay);


      // Default icon
      //var pos = new OpenSpace.MapPoint(438760, 114760);
      //var marker = new OpenLayers.Marker(pos);

      //markers.addMarker(marker);

      // Different icon
      //var size = new OpenLayers.Size(100, 100);
      //var offset = new OpenLayers.Pixel(-size.w / 2, -size.h / 2);
      //icon = new OpenLayers.Icon('house.gif', size, offset);
      //pos = new OpenSpace.MapPoint(439870, 115048);
      //marker = new OpenLayers.Marker(pos, icon);

      //markers.addMarker(marker);

      //var gridProjection = new OpenSpace.GridProjection();

	  osMap.events.register("click",osMap, function(e) {
        var pt = osMap.getMapPointFromViewPortPx(e.xy);
        if(pt) {
		  //var pg = new OpenLayers.LonLat(pt.lon,pt.lat);
		  //var po = gridProjection.getMapPointFromLonLat(pg);
        var clicked = document.getElementById('clicked');
        clicked.innerHTML = OS.NE2NGR_wtp(pt.lon,pt.lat) + " : " + pt.lon + "," + pt.lat;
		  RoutePlanner.plotClick(pt);
		}
	  });

      osMap.events.register("mousemove", osMap, function(e) {
        var pt = osMap.getMapPointFromViewPortPx(e.xy);
        //var lonlat = gridProjection.getLonLatFromMapPoint(pt);
        //var coords = document.getElementById('coords');
        //coords.innerHTML = NE2NGR_wtp(pt.lon,pt.lat);
		screenOverlay.setHTML("<div style='width:120px;background-color:#fff;'>" + OS.NE2NGR_wtp(pt.lon,pt.lat) + "</div>");
      });

	  osMap.events.register("mouseover", osMap, function(e) {
		document.body.style.cursor = "crosshair";
	  });

	  // TODO debug this - doesn't change to crosshair after dragging the map. The following code does not work.
	  osMap.events.register("mouseup", osMap, function(e) {
		document.body.style.cursor = "crosshair";
	  });

	  osMap.events.register("mouseout", osMap, function(e) {
		document.body.style.cursor = "default";
	  });

      //var elCoords = document.getElementById("coords");
      //var elMap = document.getElementById("map");
	  //alert (elMap.style.top + "," + elMap.style.height + "," + elMap.style.left);
      //elCoords.style.top = '600px';
      //elCoords.style.left = ((window.innerWidth-940)/2) + 'px';

  },

  initEditor: function() {
	RoutePlanner.initViewerEditor(true);
  },

  initViewer: function() {
	RoutePlanner.initViewerEditor(false);
  },

  initViewerEditor: function(editing) {
	    OpenLayers.Renderer.SVG.prototype.supported = function() {
        var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
        return (document.implementation &&
           (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
            document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
            document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
        };

		//OSCODE
      osMap = new OpenSpace.Map('map');

		// OpenLayers code - http://dev.openlayers.org/releases/OpenLayers-2.7/doc/apidocs/files/OpenLayers/Map-js.html#OpenLayers.Map.OpenLayers.Map


		// create a map with non-default options in an element with id "map2"
		//var options = {
    	//	maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000)
    		//maxResolution: 156543,
    		//units: 'm',
    		//projection: "EPSG:41001"
		//};
		//osMap = new OpenLayers.Map("map",options);
		//var map = new OpenLayers.Map("map2", options);

      var point = OS.NGR2NE_wtp('SH720583')
      //osMap.setCenter(new OpenSpace.MapPoint(439300, 114760), 8);
      osMap.setCenter(point,7)

      markers = new OpenLayers.Layer.Markers("Markers");
      osMap.addLayer(markers);

        vectorLayer = new OpenLayers.Layer.Vector("Vector Layer");
        osMap.addLayer(vectorLayer);

		//TODO replace this with pure OpenLayers
		screenOverlay = new OpenSpace.Layer.ScreenOverlay("coords");
		screenOverlay.setPosition(new OpenLayers.Pixel(0, 470));
		osMap.addLayer(screenOverlay);


      // Default icon
      //var pos = new OpenSpace.MapPoint(438760, 114760);
      //var marker = new OpenLayers.Marker(pos);

      //markers.addMarker(marker);

      // Different icon
      //var size = new OpenLayers.Size(100, 100);
      //var offset = new OpenLayers.Pixel(-size.w / 2, -size.h / 2);
      //icon = new OpenLayers.Icon('house.gif', size, offset);
      //pos = new OpenSpace.MapPoint(439870, 115048);
      //marker = new OpenLayers.Marker(pos, icon);

      //markers.addMarker(marker);

      //var gridProjection = new OpenSpace.GridProjection();

	  osMap.events.register("click",osMap, function(e) {
        var pt = osMap.getMapPointFromViewPortPx(e.xy);
        if(pt) {
		  //var pg = new OpenLayers.LonLat(pt.lon,pt.lat);
		  //var po = gridProjection.getMapPointFromLonLat(pg);
          //var clicked = document.getElementById('clicked');
          //clicked.innerHTML = OS.NE2NGR_wtp(pt.lon,pt.lat) + " : " + pt.lon + "," + pt.lat;
		  //plotClick(pt);
		
		  // zoom in 
		  var zoom = osMap.getZoom();
		  if (zoom < 10) {
		    osMap.setCenter(pt,++zoom);
		  }
		}
        });

      osMap.events.register("mousemove", osMap, function(e) {
        var pt = osMap.getMapPointFromViewPortPx(e.xy);
        //var lonlat = gridProjection.getLonLatFromMapPoint(pt);
        //var coords = document.getElementById('coords');
        //coords.innerHTML = NE2NGR_wtp(pt.lon,pt.lat);
		screenOverlay.setHTML("<div style='width:120px;background-color:#fff;'>" + OS.NE2NGR_wtp(pt.lon,pt.lat) + "</div>");
      });

	  osMap.events.register("mouseover", osMap, function(e) {
		document.body.style.cursor = "crosshair";
	  });

	  // TODO debug this - doesn't change to crosshair after dragging the map. The following code does not work.
	  osMap.events.register("mouseup", osMap, function(e) {
		document.body.style.cursor = "crosshair";
	  });

	  osMap.events.register("mouseout", osMap, function(e) {
		document.body.style.cursor = "default";
	  });
	
	  // AJAX load the route and waypoint information into the page - XSLT for route card, XML for marker daa
	  
		var params = new Hash();
		params.set("authenticity_token", AUTH_TOKEN);
		
		// create route with LEGS
		var req = new Ajax.Request('/routes/' + ROUTE_ID + ".xml", {method: "get",contentType:"application/xml", asynchronous:true, evalScripts:true, onSuccess: function(response){RoutePlanner.routeLoadCallback(response,editing);},parameters:$H(params)});
  },

  routeLoadCallback: function(response,editing) {
	//alert("editor load callback");
	//alert(response.responseText);
		// TODO show markers on OS map for these results
		//alert("callback2: " + response);
		var responseXML = response.responseText;
		// now parse the XML and do something useful
		// transform via xslt
		var xslloc = "/xslt/routeplanner-viewroute.xsl";
		if (editing) {
		  xslloc = "/xslt/routeplanner-editroute.xsl";
		}
		var xmlDoc = XML.parse(responseXML);
		var genDoc = XML.transform(xmlDoc,xslloc);
		
		var el = document.getElementById("routecard-body");
		XML.removeAllChildren(el);
		el.appendChild(genDoc);
		
		el = document.getElementById("loading");
		el.setAttribute("class","hidden");
		
		// show markers for each of these points! (do this within XSLT)
		
		var route = xmlDoc.documentElement;
		var coll = [];
		var lonmin = 0;
		var lonmax = 0;
		var latmin = 0;
		var latmax = 0;
		//alert("fetching waypoints");
		coll = xmlDoc.getElementsByTagName("waypoints");
		//alert("got waypoints collection");
		if (coll.length > 0) {
			//alert("waypoints collection exist");
			// draw points
			var lastMarker;
			var lastLeg;
			var wps = [];
			var legCount = 0;
			//alert("getting points");
			wps = coll[0].getElementsByTagName("Waypoint");
			//alert("waypoints");
			//alert("waypoints len " + wps.length);
			var legHg = 0;
			var legMins = 0;
			var legDist = 0;
			for (var i = 0;i < wps.length;i++) {
				var wp = wps[i];
				// create marker
				var refs = wp.getElementsByTagName("gridReference");
				//alert("refs " + refs.length);
				//alert("refs 0 " + refs[0]);
				//alert(XML.toString(refs[0]));
				var gr = refs[0].firstChild.nodeValue;
				//alert("got gr node " + gr);
				//var lonlat = OS.NGR2NE_wtp(gr);
				var lonlat = [];
				lonlat[0] = wp.getElementsByTagName("lonlaty")[0].firstChild.nodeValue;
				lonlat[1] = wp.getElementsByTagName("lonlatx")[0].firstChild.nodeValue;
				//alert("casting");
				var dist = 1.0*(wp.getElementsByTagName("distance")[0].firstChild.nodeValue);
				//alert("cast dist");
				var bear = wp.getElementsByTagName("bearing")[0].firstChild.nodeValue;
				var hg = 1*(wp.getElementsByTagName("ascent")[0].firstChild.nodeValue);
				var descent = 1*(wp.getElementsByTagName("descent")[0].firstChild.nodeValue);
				var mins = 1.0*(wp.getElementsByTagName("timemins")[0].firstChild.nodeValue);
				tDist += dist;
				tMins += mins;
				tHg += hg;
				legDist += dist;
				legMins += mins;
				legHg += hg;
				//alert("lon " + lonlat[0] + ", lat " + lonlat[1]);
				//alert("got lonlat");
				var isLeg = ("true"==wp.getElementsByTagName("isLeg")[0].firstChild.nodeValue);
				//alert("got isleg");
				var id = wp.getElementsByTagName("id")[0].firstChild.nodeValue;
				//alert("got id");
				// show marker
				//var p = new OpenSpace.MapPoint(lonlat[0],lonlat[1]);
				var p = new OpenLayers.LonLat(lonlat[0],lonlat[1]);
				if (lonmin == 0 || lonlat[0] < lonmin) {
					lonmin = lonlat[0];
				}
				if (lonlat[0] > lonmax) {
					lonmax = lonlat[0];
				}
				if (latmin==0 || lonlat[1] < latmin) {
					latmin = lonlat[1];
				}
				if (lonlat[1] > latmax) {
					latmax = lonlat[1];
				}
				//alert("got map point");
				var oMkr;
				if (i == 0) {
					oMkr = new OpenLayers.Marker(p,oTrackStartIcon.clone());
				} else {
					oMkr = new OpenLayers.Marker(p,oTrackIcon.clone());
				}
				//oMkr.lonlat.lon = lonlat[0];
				//oMkr.lonlat.lat = lonlat[1];
				oMkr.naismithMins = mins;
				oMkr.ascent = hg;
				oMkr.descent = descent;
				if (i != 0) {
					lastMarker.bToNext = bear;
					lastMarker.dToNext = dist;
				}
				//oMkr. = ;
				//alert("got marker");
				// TODO add marker information
				//alert("added marker");
				if (isLeg) {
					//alert("got a leg");
					osTrackLegs.push(oMkr);
					if (legCount == 0) {
						var title = "";
						var titleEl = wp.getElementsByTagName("title");
						//alert("title " + titleEl);
						var titleEl2 = titleEl[0];
						//alert("title2 " + titleEl2);
						var titleEl2fc = titleEl2.firstChild;
						//alert("fc " + titleEl2fc);
						if (null != titleEl2fc) {
							title = titleEl2fc.nodeValue;
						}
						var el = document.getElementById("route-start");
						if (editing) {
							el.innerHTML = gr + "<br/><input type='text' size='15' name='waypoint[" + id + "][title]' id='waypoint_" + id + "_title' value='" + title + "'/>";
						} else {
							el.innerHTML = gr + "<br/>" + title;
						}
					} else {
						var el = document.getElementById("leg-" + id + "-legnum");
						el.innerHTML = "Leg " + legCount;
					}
					//alert("leg dist " + legDist + ", leg mins " + legMins + ", leg hg" + legHg);
					
					// set leg summaries
					if (i != 0) {
						var elDist = document.getElementById("p-" + id + "-dist");
						elDist.innerHTML = (legDist/1000).toFixed(1);
						var elHg = document.getElementById("p-" + id + "-hg");
						elHg.innerHTML = legHg.toFixed(0);
						var elTfl = document.getElementById("p-" + id + "-tfl");
						elTfl.innerHTML = mins2string(legMins.toFixed(0));
		
						var elBear = document.getElementById("p-" + id + "-bear");
						var p1 = new OpenLayers.Geometry.Point(lastLeg.lonlat.lon,lastLeg.lonlat.lat);
						var p2 = new OpenLayers.Geometry.Point(lonlat[0],lonlat[1]);
						elBear.innerHTML = OL.bearingBetween(p1,p2);
					}
					
					// clear leg summaries
					legCount++;
					legHg = 0;
					legDist = 0;
					legMins = 0;
					
					lastLeg = oMkr;
				} else {
					oMkr = new OpenLayers.Marker(p,oTrackBlankIcon.clone());
				}
				if (i != 0) {
					lastMarker.succ = oMkr;
					oMkr.pred = lastMarker;
				}
				osTrackMkrs.push(oMkr);
				markers.addMarker(oMkr);
				//alert("adding marker to map");
				//alert("next markers...");
   				OSRoute.linkOsPoints(oMkr);

				lastMarker = oMkr;
				
				// if not first, show link line (coloured based on ascent/descent)
			}
			//alert("post loop");
			// set map center
			//alert("lonmin" + lonmin + ",lonmax" + lonmax + ",latmin" + latmin + ", latmax" + latmax);
			//var centerPoint = new OpenSpace.MapPoint((lonmin+lonmax)/2,(latmin+latmax)/2);
			var centerPoint = new OpenLayers.LonLat((lonmin+lonmax)/2,(latmin+latmax)/2);
			osMap.setCenter(centerPoint);
			
			// set totals
						var elDist = document.getElementById("total-dist");
						elDist.innerHTML = (tDist/1000).toFixed(1);
						var elHg = document.getElementById("total-hg");
						elHg.innerHTML = tHg.toFixed(0);
						var elTfl = document.getElementById("total-tfl");
						elTfl.innerHTML = mins2string(tMins.toFixed(0));
		
						//var elBear = document.getElementById("p-" + id + "-bear");
						//var p1 = new OpenLayers.Geometry.Point(lastLeg.lonlat.lon,lastLeg.lonlat.lat);
						//var p2 = new OpenLayers.Geometry.Point(lonlat[0],lonlat[1]);
						//elBear.innerHTML = OL.bearingBetween(p1,p2);
			
		}
		
  },

  // DEPENDS ON: OSRoute.linkOsMarkers
  // DEPENDS ON: RoutePlanner.calculateSummary
  plotClick: function(pt){

    //if(bTracing){
	    //insert at trace point
	//    if(gTraceMarker.isHidden()){
	  //      pt = oTraceMarker.lonlat;
	//        var mp = gridProjection.getLonLatFromMapPoint(new OpenSpace.MapPoint(pt.lon,pt.lat)); 
    //        gp = new GLatLng(mp.lat,mp.lon);
	//    }
	//    else{
	//        gp = gTraceMarker.getPoint(); 
	//        var pg = new OpenLayers.LonLat(gp.lng(),gp.lat());
	//		pt = gridProjection.getMapPointFromLonLat(pg);
	//    } 
    //}
	//else if(!bTracking)
	//	return;

	var oMkr;
	//var gMkr;

    //add new marker
    if(osTrackMkrs.length != 0){
	//    gMkr = new GMarker(gp,{draggable:true, icon:gTrackIcon, bouncy:false});
	    oMkr = new OpenLayers.Marker(pt,oTrackIcon.clone()); 
    } else {
	    oMkr = new OpenLayers.Marker(pt,oTrackStartIcon.clone()); 
        oMkr.startTime = new Date();
        oMkr.startTime.setHours(10);
        oMkr.startTime.setMinutes(0);
	//    gMkr = new GMarker(gp,{draggable:true, icon:gTrackStartIcon, bouncy:false});
    }
		
    oMkr.iwSize = new OpenLayers.Size(270,265);
    oMkr.userNotes = "";
    oMkr.uid = osTrackMkrUid++;
    oMkr.bTerrain = false;
	oMkr.naismithMins = 0;
	oMkr.naismithFromStart = 0;	
	oMkr.naismithToEnd = 0;
    markers.addMarker(oMkr); 	

    oMkr.events.register("click",oMkr,function(evt){
	    //if((!osDragging) && (!bTracing)){
		    osMap.closeInfoWindow();
		    osMap.openInfoWindow(this.icon, this.lonlat, makeMkrInfoWindoHtml(oMkr), this.iwSize);
	    //}
	    //else if(!osDragging)   
        //    deleteMkr(oMkr.gMkr);
	    OpenLayers.Event.stop(evt);}
    );

    oMkr.events.register("mouseover",oMkr,function(evt){
        bOverMarker = true;
    });
	
    oMkr.events.register("mouseout",oMkr,function(evt){
        bOverMarker = false;
    });
    
    //if(!bTracing)
    //{
    
        //gMkr.disableDragging();
    
        osTrackMkrs.push(oMkr);
        //gTrackMkrs.push(gMkr);

	    if (osTrackMkrs.length == 1){
		    //gMkr.pred = null;
		    //gMkr.succ = null;
		    oMkr.pred = null;
		    oMkr.succ = null;
	    }
	    else if (osTrackMkrs.length  > 1){
		    //gMkr.pred = gTrackMkrs[gTrackMkrs.length-2];
		    //gMkr.pred.succ = gMkr; 
		    oMkr.pred = osTrackMkrs[osTrackMkrs.length-2];
		    oMkr.pred.succ = oMkr; 
	    }

	    //linkMarkers(gMkr,oMkr);
	

	//}
	//else{

	//    var g1 = gTrackMkrs[traceLinkIndex-1];
	//    var g2 = gTrackMkrs[traceLinkIndex];
	//    var o1 = osTrackMkrs[traceLinkIndex-1];
	//    var o2 = osTrackMkrs[traceLinkIndex];

	//    osTrackMkrs.splice(traceLinkIndex,0,oMkr);
	//    gTrackMkrs.splice(traceLinkIndex,0,gMkr);
	
    //    g1.succ = gMkr;
    //    g2.pred = gMkr;
    //    gMkr.pred = g1;
    //    gMkr.succ = g2; 

    //    o1.succ = oMkr;
    //    o2.pred = oMkr;
    //    oMkr.pred = o1;
    //    oMkr.succ = o2; 
        
    //    linkMarkers(g1,o1);
    //    linkMarkers(g2,o2);
    //    linkMarkers(gMkr,oMkr);
        
    //    setGTrackXys();	
	//	setOTrackXys();	
        
	//}

    //gMap.addOverlay(gMkr);//last so it does not flicker

   OSRoute.linkOsMarkers(oMkr);


    if (1 == oMkr.uid) {
	  //toggleLeg(oMkr.uid);
	  OSRoute.markAsLeg(oMkr.uid);
	  var startPoint = document.getElementById("route-start");
	  startPoint.innerHTML = OS.NE2NGR_wtp(pt.lon,pt.lat);
    } else {

		//var pts = document.getElementById("points");
		//var pts = document.getElementById("routecard");
	
		//var str = "<p id='p-" + oMkr.uid + "'>" + oMkr.uid + " : " + NE2NGR_wtp(pt.lon,pt.lat);
		var str = "<tr id='p-" + oMkr.uid + "'>";
		//var str = "";
	
		// TODO button column (delete, insert before, promote to Leg, demote to Waypoint)
		str += "<td>";
		str += "<a href='#' id='p-" + oMkr.uid + "-bml' onmouseover='javascript: this.style.underline=1' onclick='javascript:RoutePlanner.toggleLeg(" + oMkr.uid + ")'><img src='/images/promote.png' alt='Make Leg'/></a>";
		str += "<a href='#' class='hidden' id='p-" + oMkr.uid + "-bsl' onmouseover='javascript: this.style.underline=1' onclick='javascript:RoutePlanner.toggleLegRows(" + oMkr.uid + ")'><img src='/images/show.png' alt=' | Show Legs'/></a>";
		//str += " | ";
		str += "<a href='#' id='p-" + oMkr.uid;
		str += "-ins' onclick='javascript:RoutePlanner.insertLeg(";
		str += oMkr.uid
		str += ")'><img src='/images/insert.png' alt=' | Insert Leg'/></a>";
		str += "<a href='#' id='p-" + oMkr.uid + "-del' onclick='javascript:RoutePlanner.deleteLeg(" + oMkr.uid + ")'><img src='/images/delete.png' alt=' | Delete Leg'/></a>";
		str += "</td>";
	
		str += "<td>" + (oMkr.uid - 1) + " : " + OS.NE2NGR_wtp(pt.lon,pt.lat) + "</td>";
		if (oMkr.uid != 1) {
			//str += ", Distance: " + (oMkr.pred.dToNext/1000).toFixed(1);
			// bearing, distance, height gain, time for leg
			var d = oMkr.pred.dToNext;
			tDist += d;
			var elTDist = document.getElementById("total-dist");
			elTDist.innerHTML = (tDist/1000).toFixed(1);
			var mFirst = osTrackMkrs[0];
			var p1 = new OpenLayers.Geometry.Point(mFirst.lonlat.lon,mFirst.lonlat.lat);
			var p2 = new OpenLayers.Geometry.Point(oMkr.lonlat.lon,oMkr.lonlat.lat);
			var elTBear = document.getElementById("total-bear");
			elTBear.innerHTML = OL.bearingBetween(p1,p2);
			str += "<td class='c' id='p-" + oMkr.uid + "-bear'>" + oMkr.pred.bToNext + "</td>";
			str += "<td class='c' id='p-" + oMkr.uid + "-dist'>" + (d/1000).toFixed(1) + "</td>";
			str += "<td class='c' id='p-" + oMkr.uid + "-hg'>Calculating...</td>";
			str += "<td class='c' id='p-" + oMkr.uid + "-tfl'>Calculating...</td>";
		} else {
			str += "<td>N/A</td><td>N/A</td><td>N/A</td><td>N/A</td>";
		}
	
		//str += "</p>";
		str += "</tr>";

		var pts = document.getElementById("routecard-body");
    	pts.innerHTML += str;

		//var newRow = document.createElement("tr");
		//newRow.setAttribute("id","p-" + oMkr.uid);
		//newRow.innerHTML = str;
		//var footer = document.getElementById("route-footer");
		//pts.insertBefore(newRow,footer);
		//pts.appendChild(newRow);
		
		RoutePlanner.calculateSummary();
	}
  },


	disableForm: function() {
		//alert("disable");
		Form.disable('new-route-form');
	},
	
	enableForm: function() {
		//alert("enable");
		Form.enable('new-route-form');
	},

    // NOT USED - submit as one XML request instead
	addLegsToRoute: function() {
		window.location = "/routes/" + id + "/waypoints"; // this for testing. normally just /routes/:id
		return; // hot wire this so we don't have to execute the following code
		
		
		
		//alert("add legs to route");
		var elRouteId = document.getElementById("route_id");
		var id = elRouteId.innerHTML;
		//alert("got route id: " + id);
	
		// loop through routes and do an AJAX call for each
		for (var i = 0;i < osTrackMkrs.length;i++) {
			var oMkr = osTrackMkrs[i];
			var params = new Array();
			params["waypoint"] = new Array();
			//alert("got init");
			params["waypoint"]["route_id"] = id;
			//alert("set route id");
			params["waypoint"]["isLeg"] = isLeg(oMkr);
			//alert("set is leg: " + params["isLeg"]);
			//alert(oMkr);
			//alert(oMkr.lonlat);
			params["waypoint"]["lonlatx"] = oMkr.lonlat.lat;
			params["waypoint"]["lonlaty"] = oMkr.lonlat.lon;
			//alert("set lonlat");
			params["waypoint"]["gridReference"] = NE2NGR_wtp(oMkr.lonlat.lon,oMkr.lonlat.lat);
			//alert("set gridref");
			params["waypoint"]["ascent"] = oMkr.ascent;
			//alert("set ascent");
			params["waypoint"]["descent"] = oMkr.descent;
			//alert("doing auth token");
			var elAuth = document.getElementById("authenticity_token");
			params["authenticity_token"] = elAuth.innerHTML;
			//alert(params["authenticitytoken"]);
			//alert("set descent");
			//alert("got main params");
			if (i == 0) {
				params["waypoint"]["distance"] = 0;
				params["waypoint"]["bearing"] = 0;
			} else {
				params["waypoint"]["distance"] = oMkr.pred.dToNext;
				params["waypoint"]["bearing"] = oMkr.pred.bToNext;
			}
			//alert(params.toString());
			//alert("sending ajax create waypoint request");
			//var req = new Ajax.Request('/routes/' + id + '/waypoints', {method: 'post', asynchronous:false, evalScripts:true, parameters:params});
			//req.request();
			//alert(req.status);
		}
	
		// forward on to show URL
		//alert("forwarding");
		window.location = "/routes/" + id + "/waypoints"; // this for testing. normally remove legs
	},
	
	createRouteXML: function() {
		//alert("create route xml");
		var x = XML.newDocument("Route");
		var el = x.createElement("totalDist");
		var t = x.createTextNode(tDist);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		el = x.createElement("totalHg");
		t = x.createTextNode(tHg);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		el = x.createElement("totalMins");
		t = x.createTextNode(tMins);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		el = x.createElement("lonlatx");
		t = x.createTextNode(cenLonlatx);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		el = x.createElement("lonlaty");
		t = x.createTextNode(cenLonlaty);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		el = x.createElement("grcenter");
		t = x.createTextNode(cenGridref);
		el.appendChild(t);
		x.documentElement.appendChild(el);
		
		// add waypoints
		el = x.createElement("waypoints");
		x.documentElement.appendChild(el);
		
		for (var i = 0;i < osTrackMkrs.length;i++) {
			var elWP = x.createElement("Waypoint");
			
			var oMkr = osTrackMkrs[i];
			
			var elC = x.createElement("isLeg");
			var il = OSRoute.isLeg(oMkr.uid);
			if (i == osTrackMkrs.length-1) {
				il = 'true';
			}
			t = x.createTextNode(il);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
		    elC = x.createElement("sequenceId");
			t = x.createTextNode(i+1);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("timemins");
			t = x.createTextNode(oMkr.naismithMins);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("lonlatx");
			t = x.createTextNode(oMkr.lonlat.lat);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("lonlaty");
			t = x.createTextNode(oMkr.lonlat.lon);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("gridReference");
			t = x.createTextNode(OS.NE2NGR_wtp(oMkr.lonlat.lon,oMkr.lonlat.lat));
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("ascent");
			t = x.createTextNode(oMkr.ascent);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			elC = x.createElement("descent");
			t = x.createTextNode(oMkr.descent);
			elC.appendChild(t);
			elWP.appendChild(elC);
			
			if (i == 0) {
				elC = x.createElement("distance");
				t = x.createTextNode(0);
				elC.appendChild(t);
				elWP.appendChild(elC);
				
				elC = x.createElement("bearing");
				t = x.createTextNode(0);
				elC.appendChild(t);
				elWP.appendChild(elC);
			} else {
				elC = x.createElement("distance");
				t = x.createTextNode(oMkr.pred.dToNext);
				elC.appendChild(t);
				elWP.appendChild(elC);
				
				elC = x.createElement("bearing");
				t = x.createTextNode(oMkr.pred.bToNext);
				elC.appendChild(t);
				elWP.appendChild(elC);
			}
			
			el.appendChild(elWP);
		} // end for
		
		//alert(XML.toString(x));
		// HTTP request params
		var params = new Hash();
		//var elAuth = document.getElementById("authenticity_token");
		//params.set("authenticity_token", elAuth.innerHTML);
		params.set("authenticity_token", AUTH_TOKEN);
		params.set("requestXML", XML.toString(x));
		
		// create route with waypoints
		var req = new Ajax.Request('/routes', {method: 'post', asynchronous:true, evalScripts:true, parameters:$H(params)});
		
		// RJS response will redirect us to the /routes/:id/edit page
	}, // end function

  // DEPENDS ON: OS.NE2NGR_wtp
  calculateSummary: function() {
	// fill in summary information
	var totalLonlatx = 0;
	var totalLonlaty = 0;
	var length = osTrackMkrs.length;
	for (var i = 0;i < length;i++) {
		var oMkr = osTrackMkrs[i];
		// TODO take into account the fact that start and finish may be the same! Don't skew the center point if they are (ignore one of them).
		totalLonlatx += oMkr.lonlat.lat;
		totalLonlaty += oMkr.lonlat.lon;
		//alert(i + ":" + oMkr.lonlat.lat + "," + oMkr.lonlat.lon);
	}
	cenLonlatx = totalLonlatx / length;
	cenLonlaty = totalLonlaty / length;
	//alert("total: " + length + ":" + cenLonlatx + "," + cenLonlaty);
	// figure out grid ref of this point
	cenGridref = OS.NE2NGR_wtp(cenLonlaty,cenLonlatx)
	
	// fill in form fields
	var el = document.getElementById("route_lonlatx");
	el.setAttribute("value",cenLonlatx);
    el = document.getElementById("route_lonlaty");
	el.setAttribute("value",cenLonlaty);
	el = document.getElementById("route_grcenter");
	el.setAttribute("value",cenGridref);
	el = document.getElementById("route_totalDist");
	el.setAttribute("value",tDist);
	el = document.getElementById("route_totalMins");
	el.setAttribute("value",tMins);
	el = document.getElementById("route_totalHg");
	el.setAttribute("value",tHg);
	
	// show center marker
	//var point = new OpenLayers.Geometry.Point(totalLonlatx,totalLonlaty);
	//var point = new OpenSpace.MapPoint(cenLonlaty, cenLonlatx);
	var point = new OpenLayers.LonLat(cenLonlaty, cenLonlatx);
	if (null != centerMarker) {
		markers.removeMarker(centerMarker);
	}
    centerMarker = new OpenLayers.Marker(point);
	markers.addMarker(centerMarker);
  },

  toggleLeg: function(id) {
	// TODO toggle between Waypoint and Leg
	var il = OSRoute.isLeg(id);
	if (il) {
		var bmlEl = document.getElementById("p-" + id + "-bml");
		bmlEl.innerHTML = "<img src='/images/promote.png' alt='Make Leg'/>";
		// get preceding leg
		RoutePlanner.showLegRows(id);
		OSRoute.removeLeg(id);
		// bold leg
		var row = document.getElementById("p-" + id);
		//row.style.fontWeight = "bold";
		row.setAttribute("class","normal");
		
		var bslEl = document.getElementById("p-" + id + "-bsl");
		bslEl.setAttribute("class","hidden");
		
		// now set this waypoints data row to show only this leg's data
		var elDist = document.getElementById("p-" + id + "-dist");
		var mThis = osTrackMkrs[id-1];
		elDist.innerHTML = (mThis.pred.dToNext/1000).toFixed(1);
		var elHg = document.getElementById("p-" + id + "-hg");
		elHg.innerHTML = mThis.pred.ascent.toFixed(0);
		var elTfl = document.getElementById("p-" + id + "-tfl");
		elTfl.innerHTML = mins2string(mThis.pred.naismithMins.toFixed(0));
		
		var elBear = document.getElementById("p-" + id + "-bear");
		var mPrev = osTrackMkrs[id-2];
		//var mThis = osTrackMkrs[id-1];
		var p1 = new OpenLayers.Geometry.Point(mPrev.lonlat.lon,mPrev.lonlat.lat);
		var p2 = new OpenLayers.Geometry.Point(mThis.lonlat.lon,mThis.lonlat.lat);
		elBear.innerHTML = OL.bearingBetween(p1,p2);
	} else {
		var bmlEl = document.getElementById("p-" + id + "-bml");
		bmlEl.innerHTML = "<img src='/images/demote.png' alt='Make WayPoint'/>";
		OSRoute.markAsLeg(id);
		RoutePlanner.hideLegRows(id);
		// bold leg
		var row = document.getElementById("p-" + id);
		//row.style.fontWeight = "bold";
		row.setAttribute("class","leg");
		
		// now set this waypoints data row to summerise all data for the leg
	    var previd = OSRoute.getPreviousLeg(id);
	    if (previd != -1) {
			var totalDist = 0;
			var totalHg = 0;
			var totalTime = 0;
			for (var i = previd - 1;i < id;i++) {
				if (0 != i) {
					totalDist += osTrackMkrs[i].pred.dToNext;
				}
				if (i != id - 1) {
					totalHg += osTrackMkrs[i].ascent;
					totalTime += osTrackMkrs[i].naismithMins;
				}
			}
			var elDist = document.getElementById("p-" + id + "-dist");
			elDist.innerHTML = (totalDist/1000).toFixed(1);
			var elHg = document.getElementById("p-" + id + "-hg");
			elHg.innerHTML = totalHg.toFixed(0);
			var elTfl = document.getElementById("p-" + id + "-tfl");
			elTfl.innerHTML = mins2string(totalTime.toFixed(0));
			
			var elBear = document.getElementById("p-" + id + "-bear");
			var mPrev = osTrackMkrs[previd-1];
			var mThis = osTrackMkrs[id-1];
			var p1 = new OpenLayers.Geometry.Point(mPrev.lonlat.lon,mPrev.lonlat.lat);
			var p2 = new OpenLayers.Geometry.Point(mThis.lonlat.lon,mThis.lonlat.lat);
			elBear.innerHTML = OL.bearingBetween(p1,p2);
		}
	}
	// Append / remove ID from legs array
	// hide intermediate legs
	// show 'show icon'
  },

  showLegRows: function(id) {
	RoutePlanner.showHideLegRows(id,true);
  },

  hideLegRows: function(id) {
	RoutePlanner.showHideLegRows(id,false);
  },

  toggleLegRows: function(id) {
	var previd = OSRoute.getPreviousLeg(id);
	//if (!isLeg(previd) & previd != -1 & (id - previd) > 1) {
		// show or hide?
		var prevRow = document.getElementById("p-" + (id - 1));
		if (prevRow.getAttribute("class") == "hidden") {
			RoutePlanner.showLegRows(id);
		} else {
			RoutePlanner.hideLegRows(id);
		}
	//}
	
  },

  showHideLegRows: function(id,show) {
	var previd = OSRoute.getPreviousLeg(id);
	if (-1 != previd) {
		// hide waypoints between previous leg and this leg
		for (var i = previd + 1;i < id;i++) {
	       var row = document.getElementById("p-" + i);
	       //row.style.display = "none";
			// remove marker objects from map
	       	if (show) {
		       	row.setAttribute("class","");
				markers.addMarker(osTrackMkrs[i - 1]);
			} else {
		        row.setAttribute("class","hidden");
				markers.removeMarker(osTrackMkrs[i - 1]);
			}
			
		}
	}
	var bslEl = document.getElementById("p-" + id + "-bsl");
	if (show) {
		bslEl.innerHTML = "<img src='/images/hide.png' alt=' | Hide Legs'/>";
		// do we need to show show/hide leg toggle?
		if (OSRoute.isLeg(id) & previd != -1 & (id - previd) > 1) {
			bslEl.setAttribute("class","");
		}
	} else {
		bslEl.innerHTML = "<img src='/images/show.png' alt=' | Show Legs'/>";
		// force hide
		if (OSRoute.isLeg(id) & previd != -1 & (id - previd) > 1) {
			bslEl.setAttribute("class","");
		} else {
			bslEl.setAttribute("class","hidden");
		}
	}
  }

} // end RoutePlanner object

