var map = null;
var geocoder = null;
var markerManager = null;

var polyline = null; 
var recording = false;
var dataPoints = new Array();
var undostack = new Array();
var oldPoints = new Array();
var undoFlag = false; // used to stop undo actions being added to the undo stack
var editmode = false;

var milestones = new Array();
var distanceMarkers = new Array();
var icons = new Array();
var startFlag = null;var endFlag = null;
var startMarker = null;var endMarker = null;

var	opacity = 0.5;
var graphHeight = 0;

var findPolylines = new Array();
var findPage = 0;
var routeCount = 0;

var unsavedData = false;

window.onresize=resizeMap;
if(navigator.appVersion.indexOf('Safari') != -1){
	window.onbeforeunload = function() {
	if(unsavedData){
	  	return 'You have unsaved changes. You will lose them if you continue.';
	  }
	};	
	window.onunload = function(){
		saveMapLocation();
		GUnload();	
	};
}else{
	window.onunload=myUnload;
}

var mapLocation = new MyCookie('maplocation');


function myUnload()
{
	if(unsavedData){
		saveTempRoute(route_id);
	}
	saveMapLocation();
	GUnload();	
}




function loadMap(lat, lng, bounds, view)
{
	if (GBrowserIsCompatible()) // Do Map if Compatible Browser only
	{
		map = new GMap2(document.getElementById("map"),{draggableCursor: 'crosshair'}) ;
		map.addMapType(G_PHYSICAL_MAP);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new GScaleControl()) ;
		setView(view);
		var latlng = new GLatLng(lat,lng) ;
		if(typeof(bounds) == 'number' || typeof(bounds) == 'int' ){
			var zoom = bounds;
		}else{
			var zoom = map.getBoundsZoomLevel(bounds);
		}
		map.setCenter(latlng,zoom);
		geocoder = new GClientGeocoder();
        markerManager = new MarkerManager(map, {borderPadding:200});
		loadIcons();
		
//      on-map ads code - leave off for now
//		var adsManagerOptions = {maxAdsOnMap:6, style:G_ADSMANAGER_STYLE_ADUNIT,position: new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 30))};	
//		adsManager = new GAdsManager(map, publisher_id, adsManagerOptions);
//		adsManager.enable();
		

//		var adsManager2Options = {maxAdsOnMap:10, style:G_ADSMANAGER_STYLE_ICON, minZoomLevel:6};	
//		adsManager2 = new GAdsManager(map, publisher_id, adsManager2Options);
//		adsManager2.enable();
		 
		GEvent.addListener(map, 'click',
			function(overlay, point)
			{
				var followRoadsElement = document.getElementById("followRoads");
				if(overlay && overlay.advert_id){
					fetchInfoWindow(overlay);
				}else if(overlay == map.getInfoWindow() ){
					// do nothing
				}else if(followRoadsElement){
					if(!followRoadsElement.checked || polyline.getVertexCount() == 0){
						addPoint(point);
					}else{				
						addRoute(point);
					}
				}
			});
		loadRoute('');

	}else{
		document.getElementById("map").innerHTML = "<h1>Browser not compatible with Google Maps. Sorry...</h1>" ;
	}
	
}

function loadSetupMap(lat, lng, zoom, view)
{
	if (GBrowserIsCompatible()) 				// Do Map if Compatible Browser only
	{
		map = new GMap2(document.getElementById("map"));
		map.addMapType(G_PHYSICAL_MAP);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new GScaleControl()) ;
		setView(view);
		var latlng = new GLatLng(lat,lng) ;
		map.setCenter(latlng,zoom);
		geocoder = new GClientGeocoder();
		loadIcons();
		GEvent.addListener(map, 'moveend',
			function(){
				mapChanged= true;
			});
	
	}else	{
		document.getElementById("map").innerHTML = "<h1>Browser not compatible with Google Maps. Sorry...</h1>" ;
	}
}

function loadMapAds(show_id)
{
	if(advertData.length >0)
	{
		var markers = new Array();
		var markerToShow = null;
		for(var i=0; i<advertData.length; i++)
		{
			var marker = new GMarker(new GLatLng(advertData[i][1],advertData[i][2]),{title:advertData[i][3], icon:icons[advertData[i][3]]});
			marker.advert_id = advertData[i][0];
			if(marker.advert_id == show_id){
				markerToShow = marker;
			}
			marker.type = advertData[i][3];
			markers.push(marker);
		}
		markerManager.addMarkers(markers, 13);
		markerManager.refresh();
		if(markerToShow !== null){
			GEvent.trigger(markerToShow, 'click');
		}
	}
}

function loadRoute(route_data, center, zoom, view)
{
	setView(view);
	map.setCenter(center, zoom);

	var points = new Array();
	if(route_data != ''){
		var pointStrings = route_data.split(',');
		for(var i=0 ; i<pointStrings.length; i++)
		{
			var latlng = pointStrings[i].split(':');
			var point = new GLatLng(parseFloat(latlng[0]), parseFloat(latlng[1]))
			if(i==0){
				points.push(point);
			}else if(point.lat().toFixed(6) != points[points.length-1].lat().toFixed(6) || point.lng().toFixed(6) != points[points.length-1].lng().toFixed(6)){
				points.push(point);				
			}
		}
	}
	polyline = new GPolyline(points, '#ff0000',3, opacity, {clickable: false});
	map.addOverlay(polyline);
	update();		 
	// save old state
	oldPoints.length = 0;
	for(var i=0; i< polyline.getVertexCount(); i++)
	{
		oldPoints[i] = polyline.getVertex(i);			
	}
	addPolylineListener();
}

function update()
{
	// remove start and finish markers
	if(endMarker !== null && endMarker !== undefined){
		map.removeOverlay(endMarker);
		endMarker = undefined;
	}	
	if(startMarker !== null && startMarker !== undefined){
		map.removeOverlay(startMarker);
		startMarker = undefined;
	}	
	
	if(polyline.getVertexCount() > 0)
	{   		
		if(polyline.getVertexCount() > 1)
		{
			var point = polyline.getVertex(polyline.getVertexCount() -1);
			endMarker = new GMarker(point, {icon: endFlag, clickable:false, title:'Finish'});
			map.addOverlay(endMarker);
		}
		startMarker = new GMarker(polyline.getVertex(0), {icon: startFlag, clickable:false, title:'Start'});
		map.addOverlay(startMarker);
	}		
	// refresh any distance markers
	displayDistance();
	displayEnergy();
	updateMarkers();
}

function updateMarkers()
{
	if(distanceMarkers.length > 0)
	{
		for(var i=0; i<distanceMarkers.length; i++)
		{
			map.removeOverlay(distanceMarkers[i]);
		}	
		distanceMarkers.length=0;
	}
	
	var showMarkersElement = document.getElementById("showMarkers");
	if(showMarkersElement && showMarkersElement.checked)
	{
		var milesElement = document.getElementById("miles");
		if(milesElement.checked == true){
			unitDistance = 1000 / 0.621367;
		}else{
			unitDistance = 1000;
		}
		
		var distances = new Array();
		distances[0] = 0;
		for(i=1; i<polyline.getVertexCount(); i++)
		{
			distances[i] = distances[i-1] + polyline.getVertex(i-1).distanceFrom(polyline.getVertex(i))  / unitDistance;
		}	
		distance = distances[distances.length-1];

		step = 1;
		if(distance >30 ){ step = 5; }
		if(distance >104 ){ step = 10; }
		if(distance >209 ){ step = 20; }
		if(distance >519 ){ step = 50; }

		var unitCount = 0;
		var markerCount = 0;
		for(i=1; i< distances.length; i++)
		{
			var count = Math.floor(distances[i]);
			while(count >= unitCount+step)
			{
				// do calcs on page co-ords and then convert to lat / lang ???
				unitCount+=step;
				var posOnLine = (unitCount - distances[i-1])/((distances[i] - distances[i-1]));
				var lat = polyline.getVertex(i-1).lat()+ (polyline.getVertex(i).lat() - polyline.getVertex(i-1).lat()) * posOnLine; // need to allow for date-line!
				var lng = polyline.getVertex(i-1).lng()+ (polyline.getVertex(i).lng() - polyline.getVertex(i-1).lng()) * posOnLine; // need to allow for date-line!
				var markerPoint = new GLatLng(lat, lng);
				if(milestones[unitCount]){
					var marker = new GMarker(markerPoint, {icon: milestones[unitCount], clickable:false});
				}else{
					var marker = new GMarker(markerPoint, {icon: milestones[0], clickable:false});
				}
				map.addOverlay(marker);
				distanceMarkers[markerCount++] = marker;
			}
		}
	}
}



function searchRoutes(page)
{
	var zoom = map.getZoom();
	if(zoom < 11){
		alert("Route search only works at zoom level 11 or greater\n\nClick 'OK' to search at zoom level 11");
		map.setZoom(11);
	}
	
	var bounds = map.getBounds();
	var sw = bounds.getSouthWest();
	var ne = bounds.getNorthEast();
	
	var params = 'allsports='+document.getElementById('all_sports').checked;
	if(!document.getElementById('all_sports').checked){
		params += '&sports=';
		var sportList = '';
		if(document.getElementById('running_select').checked){ 
			sportList += 'running|';
		}
		if(document.getElementById('walking_select').checked){ 
			sportList += 'walking|';
		}
		if(document.getElementById('cycling_select').checked){ 
			sportList += 'cycling|';
		}
		if(document.getElementById('mountain_biking_select').checked){ 
			sportList += 'mountain biking|';
		}
		if(document.getElementById('horse_riding_select').checked){ 
			sportList += 'horse riding|';
		}
		if(document.getElementById('canoeing_select').checked){ 
			sportList += 'canoeing|';
		}
		if(document.getElementById('downhill_skiing_select').checked){ 
			sportList += 'downhill skiing|';
		}
		if(document.getElementById('cross-country_skiing_select').checked){ 
			sportList += 'cross-country skiing|';
		}
		if(document.getElementById('swimming_select').checked){ 
			sportList += 'swimming|';
		}
		params += encodeURIComponent(sportList);
	}
	
	params += '&min_dist='+document.getElementById('minlength').value;
	params += '&max_dist='+document.getElementById('maxlength').value;

	var bounds = map.getBounds();
	var sw = bounds.getSouthWest();
	var ne = bounds.getNorthEast();
	params += "&n="+ne.lat()+"&e="+ne.lng()+"&s="+sw.lat()+"&w="+sw.lng();

//alert(params);	
	var oldpage = -1;
	if(page == 0){
		findPage = 0;
		var requestC = GXmlHttp.create();
		requestC.open('POST', '/en/main/ajax/searchRouteCount', true);
		requestC.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		requestC.setRequestHeader("Content-length", params.length);
		requestC.setRequestHeader("Connection", "close");

		//tell the request what to do when the state changes.
		requestC.onreadystatechange = function() 
		{
			if (requestC.readyState == 4 && requestC.status == 200) 
			{
				routeCount = parseInt(requestC.responseText);
				if(isNaN(routeCount)){
					alert("RouteCount: "+requestC.responseText);
					routeCount = 0;
				}
				if(document.getElementById('routesShowing')){ // if this result arrives back after the routes are shown
					var perPage = parseInt(document.getElementById('per_page').value);
					var from = findPage*perPage+1;
					var to = (1+findPage)*perPage;
					if(from > routeCount) { from = routeCount; }
					if(to > routeCount) { to = routeCount; }		
					document.getElementById('routesShowing').innerHTML = from+" - "+to+' '+ofLang+' '+routeCount+" "+matchesLang;
				}
			}
		} //function	
		requestC.send(params);	
	}else{
		oldpage = findPage;
		findPage += page;
		maxPage = Math.floor(routeCount / parseInt(document.getElementById('per_page').value));
		if(findPage > maxPage){
			findPage = maxPage;
		}
		if(findPage <0){
			findPage = 0;
		}
	}
	
	if(oldpage != findPage)
	{
		params += '&page='+findPage;
		params += '&per_page='+document.getElementById('per_page').value;
		params += '&sort_by='+document.getElementById('sort_by').value;
//alert(params);


		var request = GXmlHttp.create();
		request.open('POST', '/en/main/ajax/searchRoutes', true);
		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		request.setRequestHeader("Content-length", params.length);
		request.setRequestHeader("Connection", "close");

		//tell the request what to do when the state changes.
		request.onreadystatechange = function() 
		{
//alert(request.readyState+' : '+request.status);
			if (request.readyState == 4 && request.status == 200) 
			{
//alert(request.responseText);

				var routesHTML = '';
				var countContent = '';
				if(request.responseText.length>0){
					var findRoutes = eval('('+request.responseText+')');
				}else{
					var findRoutes = new Array();
				}
				var perPage = parseInt(document.getElementById('per_page').value);
				var from = findPage*perPage+1;
				var to = (1+findPage)*perPage;
				if(from > routeCount) { from = routeCount; }
				if(to > routeCount) { to = routeCount; }		

				routesHTML = '<p id="routesShowing" style="margin-bottom:5px;">'+from+" - "+to+' '+ofLang+' '+routeCount+" "+matchesLang+"</p>";
				routesHTML += '<p class="search_page"><a href="javascript:searchRoutes(-1);"><img src="/images/arrow_left.gif" width="17" height="25" alt="" style="border:0px solid;" />&nbsp;'+prevLang+'</a>&nbsp;<a href="javascript:searchRoutes(+1);" >'+nextLang+'&nbsp;<img src="/images/arrow_right.gif" width="17" height="25" alt="" style="border:0px solid;" /></a></p>';					

				if(findRoutes.length>0){
					for(var i=0; i<findRoutes.length; i++)
					{
						var route=findRoutes[i];
						var points= new Array();
						for(var j=0; j<route.points.length; j++)
						{
							points.push(new GLatLng(route.points[j].lat, route.points[j].lng));
						}
						if(findPolylines[i]){
							map.removeOverlay(findPolylines[i]);
						}
						findPolylines[i] = new GPolyline(points, route.color, 5, 1.0);
						map.addOverlay(findPolylines[i]);

						var km = (route.distance/1000);
						var miles = (route.distance*0.621367/1000);
						routesHTML += '<div class="found_route">';
						routesHTML += '<div class="route_colour" style="background-color:'+route.color+';"></div>';
						routesHTML += '<div>'+route.name+'<br /></div>';
						routesHTML += '<div style="float:right;padding-bottom:5px;"><a href="view/route_'+route.route_id+'.html" onclick="var w=window.open(this.href, \'view_route\'); w.focus(); return false;"><img src="/images/view_route.gif" width="65" height="13" alt="view route" /></a></div>';
						routesHTML += '<div><span class="distance">'+km.toFixed(1)+'Km&nbsp;/&nbsp;'+miles.toFixed(1)+'Ml</span></div>';
						routesHTML += '</div>';
					}
				}else{
					routesHTML = sorrynomatchesLang;
				}				
				var routeContainerElement = document.getElementById('routeContainer');
				routeContainerElement.innerHTML = routesHTML;
			}	
		} //function	
		request.send(params);	

		var routeContainerElement = document.getElementById('routeContainer');
		routeContainerElement.innerHTML = holdingHTML;
		
		for(var i=0; i<findPolylines.length;i++){
			map.removeOverlay(findPolylines[i]);
		}
		findPolylines.length = 0;
	}
}
function clearSearchResults()
{
	var routeContainerElement = document.getElementById('routeContainer');
	routeContainerElement.innerHTML = '';	
}

function minimiseSearch()
{
	document.getElementById('searchControls').style.display='none';
	document.getElementById('searchRestore').style.display='block';	
}
function maximiseSearch()
{
	document.getElementById('searchRestore').style.display='none';
	document.getElementById('searchControls').style.display='block';	
}
function saveMapLocation()
{
	if(map){
		mapLocation = new MyCookie('maplocation');
		var mapCenter = map.getCenter();
		mapLocation.lat = mapCenter.lat();
		mapLocation.lng = mapCenter.lng();
		mapLocation.zoom = map.getZoom();
		mapLocation.store('/', ".mapometer.com");
	}
}



function fetchInfoWindow(marker)
{
	var request = GXmlHttp.create();
	request.open('POST', '/en/main/ajax/getInfoWindow', true);
	var params = "advert_id="+encodeURIComponent(marker.advert_id);

	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", params.length);
	request.setRequestHeader("Connection", "close");

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() 
	{
		if (request.readyState == 4 && request.status == 200) 
		{
			var typestrings = marker.type.split('_');
			var htmlText = request.responseText.split('|');
			var tabs = new Array();
			tabs[0] = new GInfoWindowTab(typestrings[0], htmlText[0]);
			tabs[1] = new GInfoWindowTab('description', htmlText[1]);
			marker.openInfoWindowTabsHtml(tabs, {maxWidth:250});
		}	
	} //function	
	request.send(params);
}

function setView(view)
{
	switch(view){
		case 'Satellite':
			mapType = G_SATELLITE_MAP;
			break;
		case 'Hybrid':
			mapType = G_HYBRID_MAP;
			break;
		case 'Terrain':
			mapType = G_PHYSICAL_MAP;
			break;
		default:
			mapType = G_NORMAL_MAP;
	}
	map.setMapType(mapType);
}

function setMapDefaults()
{
	mapChanged = false;
	latElement = document.getElementById('lat');
	lngElement = document.getElementById('lng');
	zoomElement = document.getElementById('zoom');
	viewElement = document.getElementById('view');
	var center = map.getCenter();
	latElement.value = center.lat();
	lngElement.value = center.lng();
	zoomElement.value = map.getZoom();
	mapType = map.getCurrentMapType();
	if(mapType == G_SATELLITE_MAP){
		viewType = 'Satellite';
	}else if(mapType == G_HYBRID_MAP){
		viewType = 'Hybrid';
	}else if(mapType == G_PHYSICAL_MAP){
		viewType = 'Terrain';
	}else{
		viewType = 'Map';
	}
	viewElement.value = viewType;
	return true;
}

function resizeMap()
{
	var mapElement = document.getElementById("map");
	if( window.innerHeight )
	{
		var width = window.innerWidth - 420 ;
		var height = window.innerHeight - 57 - graphHeight;
	} 
	else
	{
		var width = document.documentElement.offsetWidth - 420 ;
		var height = document.documentElement.offsetHeight - 57 - graphHeight;
	}
	mapElement.style.width = width  + 'px';
	mapElement.style.height = height + 'px';
	
	var graphElement = document.getElementById('google_graph');
	if(graphElement){
		graphElement.style.width =  (width-140) + 'px';
		redrawGraph();
	}
}

function getLangCode()
{
	var theUrl = window.location.toString();
	var domainPos = theUrl.indexOf('.mapometer.com/');
	var requestURI = theUrl.substring(domainPos+15);
	var uriParts = requestURI.split('/');
	return uriParts[0];
}

function changeLocation()
{
	if (geocoder) 
	{
		var countryElement = document.getElementById("country");
		var country = countryElement.value;
		var locationElement = document.getElementById("locationBox");
		var location = locationElement.value;
		var zoomElement = document.getElementById("zoom_level");
		zoom = zoomElement.value;
		if(location && location != '')
		{
			var place = location;
		}
		if(country != 'WWW')
		{
			geocoder.setBaseCountryCode(country);
		}
		geocoder.getLatLng(place, 
			function(point) 
			{
				if (!point) {
			  		alert(address + " not found");
				} else {
			  		map.setCenter(point,parseInt(zoom));
				}
		  	});
	}
}


function startRecording(recordingText)
{
	recording=true;
	var startButton = document.getElementById("startButton");
	startButton.value = recordingText;
	startButton.disabled=true;

	document.getElementById("stopButton").disabled=false;
	document.getElementById("undoButton").disabled=false;
	document.getElementById("loopButton").disabled=false;
	document.getElementById("outButton").disabled=false;
	document.getElementById("saveButton").disabled=false;
	document.getElementById("printButton").disabled=false;
}

function stopRecording(startText)
{
	recording=false;
	var startButton = document.getElementById("startButton");
	startButton.value = startText;
	startButton.disabled=false;

	document.getElementById("stopButton").disabled=true;
	document.getElementById("undoButton").disabled=true;
	document.getElementById("loopButton").disabled=true;
	document.getElementById("outButton").disabled=true;
	document.getElementById("printButton").disabled=false;;
}


function saveRoute(route_id, lang_code)
{
	if(polyline.getVertexCount() >=2)
	{
		refreshGraph(lang_code);
	}

	var params = 'points=';
	if(polyline){
		for(var i=0; i< polyline.getVertexCount(); i++)
		{
			var pointLatLng = polyline.getVertex(i);
			if(i>0){
				params+=',';
			}		
			params+= pointLatLng.lat().toFixed(6)+':'+pointLatLng.lng().toFixed(6);
		}
		params+= '&distance='+polyline.getLength().toFixed(0);
	}else{
		params+= '&distance=0';
	}
	var showMarkersElement = document.getElementById("showMarkers");
	var markers = showMarkersElement.checked;
	var milesElement = document.getElementById("miles");
	if(milesElement.checked == true){
		var unit = 'miles';
	}else{
		var unit = 'km';		
	}
	var sportElement = document.getElementById("sport");
	params+= '&sport='+sportElement.value;

	var center = map.getCenter();
	params+= '&location='+center.lat()+':'+center.lng();
	params+= '&zoom='+map.getZoom();
	params+= '&view='+map.getCurrentMapType().getName();
	params+= '&units='+unit;
	params+= '&markers='+markers;
	if(route_id){
		params+= '&id='+route_id;		
	}

	var request = GXmlHttp.create();
	request.open('POST', '/en/main/ajax/save', true);

	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", params.length);
	request.setRequestHeader("Connection", "close");

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() 
	{
		if (request.readyState == 4 && request.status == 200) 
		{
			unsavedData = false;
			location = request.responseText;
//			alert(request.responseText);
		}	
	} //function	
	request.send(params);
}

function saveTempRoute(route_id)
{
	if(polyline && polyline.getVertexCount() > 1){
		var params = 'points=';
		for(var i=0; i< polyline.getVertexCount(); i++)
		{
			var pointLatLng = polyline.getVertex(i);
			if(i>0){
				params+=',';
			}		
			params+= pointLatLng.lat().toFixed(6)+':'+pointLatLng.lng().toFixed(6);
		}
		params+= '&distance='+polyline.getLength();
		var showMarkersElement = document.getElementById("showMarkers");
		var markers = showMarkersElement.checked;
		var milesElement = document.getElementById("miles");
		if(milesElement.checked == true){
			var unit = 'miles';
		}else{
			var unit = 'km';		
		}
		var sportElement = document.getElementById("sport");
		params+= '&sport='+sportElement.value;

		var center = map.getCenter();
		params+= '&location='+center.lat()+':'+center.lng();
		params+= '&zoom='+map.getZoom();
		params+= '&view='+map.getCurrentMapType().getName();
		params+= '&units='+unit;
		params+= '&markers='+markers;
		params+= '&temp=1';
		if(route_id){
			params +='&route_id='+route_id;
		}

		var request = GXmlHttp.create();
		request.open('POST', '/en/main/ajax/save_temp', true);

		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		request.setRequestHeader("Content-length", params.length);
		request.setRequestHeader("Connection", "close");
		request.send(params);
	}
}

function saveViewedRoute(route_id)
{
	params= 'route_id='+route_id;

	var request = GXmlHttp.create();
	request.open('POST', '/en/main/ajax/saveViewed', true);

	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", params.length);
	request.setRequestHeader("Connection", "close");

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() 
	{
		if (request.readyState == 4 && request.status == 200) 
		{
			location = request.responseText;
		}	
	} //function	
	request.send(params);	
}


function addPoint(point)
{
	if(editmode != true && recording)
	{		
		polyline.insertVertex(polyline.getVertexCount(), point);
		update();
		unsavedData = true;
	}
}

function addRoute(point)
{
	if(editmode != true && recording)
	{
		var wayPoints = new Array();
		wayPoints[0] = polyline.getVertex(polyline.getVertexCount()-1);
		wayPoints[1] = point;
		paneldiv = document.getElementById("panel");
		directions = new GDirections(null, paneldiv);
		GEvent.addListener(directions, 'load',
			function()
			{
				var polylineSection = directions.getPolyline();
				var start = polyline.getVertexCount();
				for(var i=1; i< polylineSection.getVertexCount(); i++)
				{
					var point = polylineSection.getVertex(i);
					var lastPoint = polyline.getVertex(polyline.getVertexCount()-1);
					if(point.lat().toFixed(6) != lastPoint.lat().toFixed(6) || point.lng().toFixed(6) != lastPoint.lng().toFixed(6)) // only insert if different from last point
					{
						polyline.insertVertex(polyline.getVertexCount(), point);
					}					
				}
				panelElement = document.getElementById('panel');
				panelElement.innerHTML = '';
				unsavedData = true;
			});
		GEvent.addListener(directions, 'error',
			function()
			{
				switch(directions.getStatus().code)
				{
					case 604:
						alert(	'We could not compute directions to the last point you clicked.\n'+
								'This is usually because there is no route available between the two\n'+
								'points, or because we do not have data for routing in that region.\n\n'+
								'Try turning off the "auto-follow roads" feature and follow the route\n'+
								'by hand until you reach a larger road or path');
						break;
					case 500:
						alert(	'A geocoding or directions request could not be successfully\n'+
								'processed - the exact reason for the failure is not known (status'+ directions.getStatus().code+').');
						break;
					default:
						alert(	'An error occured in finding directions (status '+directions.getStatus().code+')');
						break;
				}
			});
		directions.loadFromWaypoints(wayPoints, {getPolyline:true, travelMode:G_TRAVEL_MODE_WALKING});
	}	
}

function showUndostack()
{
	var output = "";
	for(i=0; i<undostack.length; i++)
	{
		if(undostack[i].latlng){
			output += i+" - "+undostack[i].position+"-"+undostack[i].latlng.lat()+":"+undostack[i].latlng.lng()+" \n";
		}else{
			output += i+" - "+undostack[i].start+":"+undostack[i].end+" \n";
		}		
	}
	alert(output);
}

function undoPoint()
{
	undoFlag = true;
	if(undostack.length > 0) //if we have anything to undo
	{
//		showUndostack();
		var action = undostack.pop();
		// is it an add or a move action?
		if(action.start !== undefined) // add action
		{
			panTo = action.start -1;
			for(var i=action.end;i>=action.start; i--)
			{
				var vertexCount = polyline.getVertexCount();
				if(action.start == 0){
					deletePolyline();
					unsavedData = false;
					break;
				}else if(vertexCount==2){
					firstpoint = polyline.getVertex(0);
					deletePolyline();
					polyline.insertVertex(0,firstpoint);
					undostack.push({start:0, end:0});
					unsavedData = true;
				}else if(vertexCount>2){
					polyline.deleteVertex(i);
					unsavedData = true;
				}
			}
		}
		else if(action.position !== undefined)  // move action
		{
			panTo = action.position;
			polyline.insertVertex(action.position, action.latlng);
			polyline.deleteVertex(action.position +1);
			unsavedData = true;
		}
	}else{ // Nothing on the undo stack - just delete last point.
		if(polyline.getVertexCount() > 2){
			polyline.deleteVertex(polyline.getVertexCount()-1);
			unsavedData = true;		
		}else if(polyline.getVertexCount() == 2){
			firstpoint = polyline.getVertex(0);
			deletePolyline();
			polyline.insertVertex(0,firstpoint);
			undostack.push({start:0, end:0});
			unsavedData = true;
		}
	}
	
	if(unsavedData == true){	
		// reset oldPoints
		oldPoints.length = 0;
		for(var i=0; i<polyline.getVertexCount(); i++)
		{
			oldPoints[i] = polyline.getVertex(i);
		}
		// pan if necessary
		var autoScrollElement = document.getElementById("autoScroll");
		if(autoScrollElement && autoScrollElement.checked && panTo !== undefined)
		{
			if(panTo < polyline.getVertexCount() && panTo >= 0){
				map.panTo(polyline.getVertex(panTo));
			}	
		}
		update();
	}	
	setTimeout('undoFlag=false;', 100);
}



function clearRoute(lang_code, popup_text)
{
	if(confirm(popup_text))
	{
		clearRoute2();
		deletePolyline();
		update();
		
		refreshElement = document.getElementById('refGraph');
		if(refreshElement){
			refreshGraph(lang_code);
		}
		unsavedData = false;
	}	
}

function clearRoute2()
{
	map.clearOverlays();
	loadMapAds();
}

function deletePolyline()
{
	polyline.disableEditing();
	oldpolyline = polyline;
	polyline = new GPolyline([], '#ff0000',3, opacity, {clickable: false});
	undostack.length = 0; // empty undostack 
	oldPoints.length = 0;
	map.addOverlay(polyline);
	drawMode();
	addPolylineListener();
	setTimeout('map.removeOverlay(oldpolyline);',100);
}



function closeLoop()
{
	if(polyline.getVertex(0).lat() != polyline.getVertex(polyline.getVertexCount()-1).lat() || polyline.getVertex(0).lng() != polyline.getVertex(polyline.getVertexCount()-1).lng())
	{
		var followRoadsElement = document.getElementById("followRoads");
		if(!followRoadsElement.checked && polyline.getVertexCount() > 0)
		{
			polyline.insertVertex(polyline.getVertexCount(), polyline.getVertex(0));
		}
		else if(followRoadsElement.checked && polyline.getVertexCount() > 0)
		{
			addRoute(polyline.getVertex(0));
		}
		unsavedData = true;
	}
}

function outBack()
{
	var start = polyline.getVertexCount();
	if(start > 1){
		for(i=polyline.getVertexCount()-2; i>=0; i--)
		{
			var point = new GLatLng(polyline.getVertex(i).lat()+0.000025, polyline.getVertex(i).lng()+0.000025);
			polyline.insertVertex(polyline.getVertexCount(), point);
		}
		unsavedData = true;
	}
}




function displayDistance()
{
	var distance = 0.0;
	if(polyline && polyline.getVertexCount() > 0){
		distance = polyline.getLength() /1000;
		var milesElement = document.getElementById("miles");
		if(milesElement && milesElement.checked == true){
			distance = distance * 0.621367;
			var unit = 'Ml';
		}else{
			var unit = 'Km';
		}
		distance = distance.toFixed(2);
		var distanceElement = document.getElementById("distance");
		if(distanceElement){
			distanceElement.value = distance + unit;
		}	
	//	updateGraph();
	}
	return distance;
}

function displayEnergy()
{
	var energyElement = document.getElementById("energy");
	if(energyElement){
		var energy = 0.0;
		if(polyline && polyline.getVertexCount() > 0)
		{
			var cals = {running:0.999, cycling:0.403, walking:0.699, 'mountain biking':0.544, swimming: 2.941, 'horse riding': 0.502, canoeing: 0.765, 'cross-country skiing': 1.211, 'downhill skiing': 0.118 };
			var weightElement = document.getElementById("weight");
			weight = parseInt(weightElement.value);
			var sportElement = document.getElementById("sport");
			var sport = sportElement.value;		
			var calsKmKg = cals[sport];
			var energy =  calsKmKg * weight * polyline.getLength() / 1000;
		}
		var joulesElement = document.getElementById("joules");
		if(joulesElement.checked == true)
		{
			energy = energy * 4.184;
		}
		energy = energy.toFixed(0);
		energyElement.value = energy;
	}	
}

function showMarkers(distance, unit )
{
	unitDistance = 1000;
	if(unit=='miles')
	{
		unitDistance = 1000 / 0.621367;
	}
		
	var distances = new Array();
	distances[0] = 0;
	for(i=1; i<polyline.getVertexCount(); i++)
	{
		distances[i] = distances[i-1] + polyline.getVertex(i-1).distanceFrom(polyline.getVertex(i))  / unitDistance;
	}	
	var distance = distances[distances.length-1];
	step = 1;
	if(distance >30 ){ step = 5; }
	if(distance >104 ){ step = 10; }
	if(distance >209 ){ step = 20; }
	if(distance >519 ){ step = 50; }

	var unitCount = 0;
	for(i=1; i< distances.length; i++)
	{
		var count = Math.floor(distances[i]);
		while(count >= unitCount+step)
		{
			// do calcs on page co-ords and then convert to lat / lang ???
			unitCount+=step;
			var posOnLine = (unitCount - distances[i-1])/(distances[i] - distances[i-1]);
			var lat = polyline.getVertex(i-1).lat()+ (polyline.getVertex(i).lat() - polyline.getVertex(i-1).lat()) * posOnLine; // need to allow for date-line!
			var lng = polyline.getVertex(i-1).lng()+ (polyline.getVertex(i).lng() - polyline.getVertex(i-1).lng()) * posOnLine; // need to allow for date-line!
			var markerPoint = new GLatLng(lat, lng);
			if(milestones[unitCount]){
				var marker = new GMarker(markerPoint, {icon: milestones[unitCount], clickable:false});
			}else{
				var marker = new GMarker(markerPoint, {icon: milestones[0], clickable:false});
			}
			map.addOverlay(marker);
		}
	}
}

function drawMode()
{
	document.getElementById('drawButton').disabled = true;
	document.getElementById('editButton').disabled = false;
	editmode = false;
	polyline.disableEditing();
}

function editMode()
{
	document.getElementById('drawButton').disabled = false;
	document.getElementById('editButton').disabled = true;
	editmode = true;
	polyline.enableEditing();
}

function addPolylineListener()
{
	GEvent.addListener(polyline, 'lineupdated',
	function()
	{		
		if(!undoFlag)
		{
			// what's changed?			
			// is line longer? >> point(s) added
			if(polyline.getVertexCount() > oldPoints.length)
			{
				// is it the first point?
				if(oldPoints.length==0 && polyline.getVertexCount()==1)
				{
					undostack.push({start:0, end:0});
					panTo = 0;
				}else
				{
			
					//is old last point in the same place? >> added to end
					var oldLastpoint = oldPoints[oldPoints.length-1];
					var newLastpoint = polyline.getVertex(oldPoints.length-1);
					if(oldLastpoint.lat()==newLastpoint.lat() && oldLastpoint.lng()==newLastpoint.lng())
					{
						undostack.push({start:oldPoints.length, end:polyline.getVertexCount()-1});
						panTo = polyline.getVertexCount()-1;
					}else // must have added a point to the middle
					{
						// lets find where it was added
						for(var i=0; i< oldPoints.length; i++)
						{
							var oldpoint = oldPoints[i];
							var newpoint = polyline.getVertex(i);
							if(oldpoint.lat()!=newpoint.lat() || oldpoint.lng()!=newpoint.lng())
							{
								undostack.push({start:i, end:i});
								panTo = i;
								break;
							}						
						}
					}
				}
			}
			else if(polyline.getVertexCount() == oldPoints.length) // >> point moved
			{
				for(var i=0; i< oldPoints.length; i++)
				{
					var oldpoint = oldPoints[i];
					var newpoint = polyline.getVertex(i);
					if(oldpoint.lat()!=newpoint.lat() || oldpoint.lng()!=newpoint.lng())
					{
						undostack.push({position:i, latlng:oldpoint});
						panTo = i;
						break;
					}						
				}
			}
			
			// save old state
			oldPoints.length = 0;
			for(var i=0; i< polyline.getVertexCount(); i++)
			{
				oldPoints[i] = polyline.getVertex(i);			
			}
			
			update();		 
		}
		var autoScrollElement = document.getElementById("autoScroll");
		if(autoScrollElement && autoScrollElement.checked && panTo !== undefined)
		{
			if(panTo < polyline.getVertexCount() && panTo >= 0){
				map.panTo(polyline.getVertex(panTo));
			}		
		}
	});
}


function loadIcons()
{
	milestones[0] = new GIcon();
	milestones[0].image = "/images/milestone_blank.png";
	milestones[0].shadow = "/images/milestone_shadow.png";
	milestones[0].shadowSize = new GSize(24,15);
	milestones[0].iconSize = new GSize(15,15);
	milestones[0].iconAnchor = new GPoint(15,8);
	
	for(i=1; i<=30; i++)
	{
		milestones[i] = new GIcon(milestones[0]);
		milestones[i].image = "/images/milestone_"+i+".png";
	}
	for(i=35; i<=100; i+=5)
	{
		milestones[i] = new GIcon(milestones[0]);
		milestones[i].image = "/images/milestone_"+i+".png";
	}
	for(i=110; i<=200; i+=10)
	{
		milestones[i] = new GIcon(milestones[0]);
		milestones[i].image = "/images/milestone_"+i+".png";
	}
	for(i=220; i<=500; i+=20)
	{
		milestones[i] = new GIcon(milestones[0]);
		milestones[i].image = "/images/milestone_"+i+".png";
	}
	for(i=550; i<=950; i+=50)
	{
		milestones[i] = new GIcon(milestones[0]);
		milestones[i].image = "/images/milestone_"+i+".png";
	}
	
	startFlag = new GIcon();
	startFlag.image = "/images/start_flag.png";
	startFlag.shadow = "/images/flag_shadow.png";
	startFlag.shadowSize = new GSize(34,20);
	startFlag.iconSize = new GSize(20,20);
	startFlag.iconAnchor = new GPoint(2,20);

	endFlag = new GIcon(startFlag);
	endFlag.iconAnchor = new GPoint(8,20);
	endFlag.image = "/images/end_flag.png";
	
	icons['club_cycling'] = new GIcon();
	icons['club_cycling'].image = "/images/markers/club_cycling.png";
	icons['club_cycling'].shadow = null;
	icons['club_cycling'].shadowSize = null;
	icons['club_cycling'].iconSize = new GSize(30,30);
	icons['club_cycling'].iconAnchor = new GPoint(15,15);
	icons['club_cycling'].infoWindowAnchor = new GPoint(15,15);

	icons['club_mountain_bike'] = new GIcon(icons['club_cycling']);
	icons['club_mountain_bike'].image = "/images/markers/club_mountain_bike.png";

	icons['club_running'] = new GIcon(icons['club_cycling']);
	icons['club_running'].image = "/images/markers/club_running.png";

	icons['club_walking'] = new GIcon(icons['club_cycling']);
	icons['club_walking'].image = "/images/markers/club_walking.png";

	icons['gym'] = new GIcon(icons['club_cycling']);
	icons['gym'].image = "/images/markers/gym.png";

	icons['misc'] = new GIcon(icons['club_cycling']);
	icons['misc'].image = "/images/markers/misc.png";

	icons['shop_cycling'] = new GIcon(icons['club_cycling']);
	icons['shop_cycling'].image = "/images/markers/shop_cycling.png";

	icons['shop_outdoor'] = new GIcon(icons['club_cycling']);
	icons['shop_outdoor'].image = "/images/markers/shop_outdoor.png";

	icons['shop_running'] = new GIcon(icons['club_cycling']);
	icons['shop_running'].image = "/images/markers/shop_running.png";

	icons['shop_sports'] = new GIcon(icons['club_cycling']);
	icons['shop_sports'].image = "/images/markers/shop_sports.png";
	
}

function checkForReturn(event)
{
	var e = event || window.event;
	var code = e.charcode || e.keyCode;
	if(code == 13 || code == 10)
	{
		changeLocation();
	}
}


function refreshGraph()
{
	if(polyline.getVertexCount() >1)
	{
		var milesElement = document.getElementById("miles");

		unitDistance = 1000;

		var distances = new Array();
		distances[0] = 0;
		for(i=1; i<polyline.getVertexCount(); i++)
		{
			distances[i] = distances[i-1] + polyline.getVertex(i-1).distanceFrom(polyline.getVertex(i))  / unitDistance;
		}	

		step = distances[distances.length-1] / 200;

		var unitCount = 0;
		var coords = new Array();
		var params = "points=0.0," + polyline.getVertex(0).lat() + ',' + polyline.getVertex(0).lng();
		for(i=1; i< distances.length; i++)
		{
			while(unitCount+step <= distances[i])
			{
				unitCount+=step;
				var posOnLine = (unitCount - distances[i-1])/((distances[i] - distances[i-1]));
				var lat = polyline.getVertex(i-1).lat()+ (polyline.getVertex(i).lat() - polyline.getVertex(i-1).lat()) * posOnLine; // need to allow for date-line!
				var lng = polyline.getVertex(i-1).lng()+ (polyline.getVertex(i).lng() - polyline.getVertex(i-1).lng()) * posOnLine; // need to allow for date-line!
				params += ':'+ unitCount + ',' + lat + ',' + lng;
			}
		}
		params +=  ':'+ distances[distances.length-1] + ',' + polyline.getVertex(polyline.getVertexCount()-1).lat() + ',' + polyline.getVertex(polyline.getVertexCount()-1).lng();
		
		var request = GXmlHttp.create();
		request.open('POST', '/en/main/ajax/graph', true);

		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		request.setRequestHeader("Content-length", params.length);
		request.setRequestHeader("Connection", "close");

		//tell the request what to do when the state changes.
		request.onreadystatechange = function() 
		{
			if (request.readyState == 4 && request.status == 200) 
			{
				redrawGraph();
			}	
		} //function	
		request.send(params);
	}	
}

function redrawGraph(){
	var graphElement = document.getElementById('google_graph');
	if(graphElement){
		var width = parseInt(graphElement.style.width);
		var metric = document.getElementById('kms').checked;

		var request = GXmlHttp.create();
		request.open('GET', '/en/main/ajax/getGraphData', true);
		request.setRequestHeader("Connection", "close");

		//tell the request what to do when the state changes.
		request.onreadystatechange = function() 
		{
			if (request.readyState == 4 && request.status == 200) 
			{
				var heightData = eval('('+request.responseText+')');
				var data = new google.visualization.DataTable();
				data.addColumn('number', 'distance');
				data.addColumn('number', 'height');
				data.addRows(heightData==null ? 0 : heightData.length);
				
				if(metric == true)	{
					unitDistance = 1;
					unitHeight = 1;
					titleX = "Distance (km)";
					titleY = altitudeGraphTitleMeters;
				}else{
					unitDistance = 0.621367;
					unitHeight = 3.2808399;
					titleX = "Distance (miles)";
					titleY = altitudeGraphTitleFeet; //"Altitude (ft)";
				}
				var maxHeight = -9999;
				var minHeight = +99999;
				var totalAsc = 0;
				var totalDesc = 0;
				for (var i = 0; i < (heightData==null ? 0 : heightData.length); ++i) {
					if(parseInt(heightData[i][1]) > maxHeight) { maxHeight = parseInt(heightData[i][1]); }
					if(parseInt(heightData[i][1]) < minHeight) { minHeight = parseInt(heightData[i][1]); }
					if(i > 0){
						if(heightData[i][1] > heightData[i-1][1]){
							totalAsc += heightData[i][1] - heightData[i-1][1];
						}else{
							totalDesc += heightData[i-1][1] - heightData[i][1];
						}
					}
				
					data.setCell(i, 0, parseFloat(heightData[i][0]) * unitDistance);		  	
				  	data.setCell(i, 1, Math.floor(parseFloat(heightData[i][1]) * unitHeight));
				}
				// Create and draw the visualization.
				var ac = new google.visualization.ScatterChart(document.getElementById('google_graph'));
				ac.draw(data, { 					
					width: (width),
					height: 100,
				  	hAxis: {title: titleX},
				  	vAxis: {title: titleY},
					lineSize: 3,
					pointSize: 1,		
					titleFontSize:11,
					legend: 'none'
				});
				
				// update altitude summary stats
				if(document.getElementById('kms').checked){
					var statsContent = '<div style="float:right; text-align:right;">'+maxHeight+'m<br />'+minHeight+'m<br />'+totalAsc+'m<br />'+totalDesc+'m</div><div>'+maxHeightText+':<br />'+minHeightText+':<br />'+totalAscText+':<br />'+totalDescText+':</div>';
				}else{
					meterToFeet = 3.2808399;
					var statsContent = '<div style="float:right; text-align:right;">'+Math.round(maxHeight*meterToFeet)+'ft<br />'+Math.round(minHeight*meterToFeet)+'ft<br />'+Math.round(totalAsc*meterToFeet)+'ft<br />'+Math.round(totalDesc*meterToFeet)+'ft</div><div>'+maxHeightText+':<br />'+minHeightText+':<br />'+totalAscText+':<br />'+totalDescText+':</div>';
				}
				var statsDiv = document.getElementById('alt_stats');
				statsDiv.innerHTML = statsContent;
			}	
		} //function	
		request.send(null);
	}	
}

/*
function redrawGraph(lang_code)
{
	var graphElement = document.getElementById('graphImg');
	if(graphElement){
		var width = parseInt(graphElement.style.width);
		var milesElement = document.getElementById('miles');
		graphElement.src = '/'+lang_code+'/main/graph/'+width+'/'+milesElement.checked+'/rand'+ Math.floor(Math.random()*1000000);
	}
}
*/

function displayGraph(showText, hideText, lang_code)
{
	hideElement = document.getElementById('showGraph');
	if(graphHeight == 90)
	{
		hideElement.value = showText;
		graphElement = document.getElementById('graph');
		graphElement.style.display = 'none';
		refreshElement = document.getElementById('refGraph');
		if(refreshElement){
			refreshElement.style.display = 'none';	
		}
		graphHeight = 0;
		resizeMap();
	}
	else if(polyline.getVertexCount() >=2)
	{
		hideElement.value = hideText;
		graphElement = document.getElementById('graph');
		graphElement.style.display = 'block';
		refreshElement = document.getElementById('refGraph');
		if(refreshElement){
			refreshElement.style.display = 'block';	
			refreshGraph(lang_code);
		}
		graphHeight = 90;
		resizeMap();
	}
}

function printRoute(lang_code, route_id)
{
	if(polyline)
	{	
		var graphElement = document.getElementById('graphImg');
		refreshGraph(lang_code);
		print_params = "graph=true";
		print_params += "|point_data=";
		for(var i=0; i<polyline.getVertexCount(); i++)
		{
			if(i>0){
				print_params+= ',';
			}
			print_params+= polyline.getVertex(i).lat()+':'+polyline.getVertex(i).lng();
		}

		var showMarkersElement = document.getElementById("showMarkers");
		var markers = showMarkersElement.checked;

		print_params += "|distance="+polyline.getLength();
		var center = map.getCenter();
		print_params += "|lat="+ center.lat();
		print_params += "|lng="+ center.lng();
		print_params += "|zoom="+ map.getZoom();
		print_params += "|view="+ map.getCurrentMapType().getName();

		if(route_id){
			print_params += "|route_id="+ route_id;	
		}
		var paramElement = document.getElementById('route_params');
		paramElement.value = print_params;
	
		if( window.innerHeight )
		{
			var height = window.innerHeight;
		} 
		else
		{
			var height = document.documentElement.offsetHeight;
		}
		if(route_id){
			window.open('', 'printWindow', 'height='+height+',width=700,location=no,menubar=no,resizeable=yes,scrollbars=yes,status=no,toolbar=no,top=0,left=0');
		}else{
			window.open('', 'printWindow', 'height='+height+',width=700,location=no,menubar=no,resizeable=yes,scrollbars=yes,status=no,toolbar=no,top=0,left=0');
		}		
	}
}

function printdraw(showmarkers, dist_unit)
{
	if(polyline.getVertexCount() > 0)
	{   		
		if(polyline.getVertexCount() > 1)
		{
//			polyline = new GPolyline(points, '#ff0000',3, opacity, {clickable: false});
			map.addOverlay(polyline) ;
			var point = polyline.getVertex(polyline.getVertexCount() -1);
			var marker = new GMarker(point, {icon: endFlag, clickable:false, title:'Finish'});
			map.addOverlay(marker);
		}
		var marker = new GMarker(polyline.getVertex(0), {icon: startFlag, clickable:false, title:'Start'});
		map.addOverlay(marker);
	}
	var distance = displayDistance();
	displayEnergy();
	if(polyline.getVertexCount() > 0 && showmarkers){
		showMarkers(distance, dist_unit);
	}	
}

