var map;
var bounds;
var altitudeMarker;
var heartMarker;
var compMarkerOne;
var compMarkerTwo;
var videoMarker;
var polyline;
var polylineClickHandler;
var comparison;

// Return XML
function grabMapXML(url) {
	$('#map-loading').show();
	$.ajax({
        type: "GET",
        url: url,
        dataType: "xml",
        success: function(data) {

			if (GBrowserIsCompatible()) {
				// Set up the map
				map = new GMap2(document.getElementById("map"));
	
				map.setCenter(new GLatLng(0,0), 0);
				bounds = new GLatLngBounds();
			
				// Create the icon for the start point
				var startIcon = new GIcon();
				startIcon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
				startIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
				startIcon.iconSize = new GSize(12, 20);
				startIcon.shadowSize = new GSize(22, 20);
				startIcon.iconAnchor = new GPoint(6, 20);
				startIcon.infoWindowAnchor = new GPoint(5, 1);
			
				// Create the icon for the end point
				var endIcon = new GIcon();
				endIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
				endIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
				endIcon.iconSize = new GSize(12, 20);
				endIcon.shadowSize = new GSize(22, 20);
				endIcon.iconAnchor = new GPoint(6, 20);
				endIcon.infoWindowAnchor = new GPoint(5, 1);
				
				var startMarker;
				var endMarker;
	
		 		var polylineEncoder = new PolylineEncoder(18, 2);
				var $points = $(data).find("point");
				var txtPoints = [];
				$points.each(function(i) {
					var $point = $(this);
				
					var lng = parseFloat($point.find('longitude').eq(0).text());
					var lat = parseFloat($point.find('latitude').eq(0).text());
					txtPoints[i] = new GLatLng(lat, lng);
					bounds.extend(new GLatLng(lat, lng));
					// If this is the first point, create the start marker, otherwise create the end marker
					if(i == 0) {
						startMarker = new GMarker(new GLatLng(lat, lng), startIcon);
						GEvent.addListener(startMarker, "click", function() {
							var infoShellStart = document.createElement('div');
							infoShellStart.id = "overlayStart";
							infoShellStart.className = "overlay";
							infoShellStart.innerHTML = '<div class="inner"><a href="#close" onclick="closeInfo(\'Start\'); return false;" id="close" class="close">Close</a><p><strong>Starting Point</strong></p></div>';
							map.getPane(G_MAP_MARKER_PANE).appendChild(infoShellStart);
							var markerPosition = map.fromLatLngToDivPixel(startMarker.getPoint());
							var overlayBottom = parseInt(markerPosition.y)-(infoShellStart.offsetHeight+20);
							var overlayLeft = parseInt(markerPosition.x)-110;
							infoShellStart.style.top = overlayBottom+"px";
							infoShellStart.style.left = overlayLeft+"px";
							infoShellStart.style.visibility = "visible";
							map.panTo(startMarker.getPoint());
						});
					} else if (i == $points.size()-1) {
						endMarker = new GMarker(new GLatLng(lat, lng), endIcon);
						GEvent.addListener(endMarker, "click", function() {
							var infoShellEnd = document.createElement('div');
							infoShellEnd.id = "overlayEnd";
							infoShellEnd.className = "overlay";
							infoShellEnd.innerHTML = '<div class="inner"><a href="#close" onclick="closeInfo(\'End\'); return false;" id="close" class="close">Close</a><p><strong>Ending Point</strong></p></div>';
							map.getPane(G_MAP_MARKER_PANE).appendChild(infoShellEnd);
							var markerPosition = map.fromLatLngToDivPixel(endMarker.getPoint());
							var overlayBottom = parseInt(markerPosition.y)-(infoShellEnd.offsetHeight+20);
							var overlayLeft = parseInt(markerPosition.x)-110;
							infoShellEnd.style.top = overlayBottom+"px";
							infoShellEnd.style.left = overlayLeft+"px";
							infoShellEnd.style.visibility = "visible";
							map.panTo(endMarker.getPoint());
						});
					}
				});
				// Encode the points and create polyline
				polyline = polylineEncoder.dpEncodeToGPolyline(txtPoints, '#FF0000', 5, 0.5);
				
				// Add the polyline and markers to the map and zoom to the proper level
				map.addOverlay(polyline);
				
				map.addOverlay(startMarker);
				map.addOverlay(endMarker);
				map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	
				if($('#map').width() > 250) {
					//Create accessible map controls
					$('#mapcontrols button').click(function() { return false; });
					
					$('#centerButton').click(function() { map.panTo(bounds.getCenter()); });
					$('#upButton').click(function() { map.panDirection(0,0.5); });
					$('#rightButton').click(function() { map.panDirection(-0.5,0); });
					$('#downButton').click(function() { map.panDirection(0,-0.5); });
					$('#leftButton').click(function() { map.panDirection(0.5,0); });
					$('#zoomInButton').click(function() { map.zoomIn(); });
					$('#zoomOutButton').click(function() { map.zoomOut(); });
				
					// Map Views
					$('#normalView').click(function() { map.setMapType(G_NORMAL_MAP); });
					$('#satelliteView').click(function() { map.setMapType(G_SATELLITE_MAP); });
					$('#hybridView').click(function() { map.setMapType(G_HYBRID_MAP); });
					
					// Comparison
					$('#clearPoints').click(function() { clearComparisonPoints(); });
					$('#comparePoints').click(function() { grabComparisonXML(); });
				}
	
				$('#map-loading').animate( {opacity: 'hide' },1500);
				
				if(document.getElementById('video'))
					GEvent.addListener(polyline, "click", function(point) { seekVideo(point); });
				
				if(document.getElementById('graph')) { grabGraphXML(data); }
			}
		}
	});
}

function seekVideo(point) {
	var coords = new GLatLng(point.y, point.x)
	var route_id = $('#route_id').val();
	var video_player_id = $('#video').find('object').eq(0).attr('id');
	
	$.ajax({
        type: "GET",
        url: '/routes/'+route_id+'/elapsed_time/?lat='+coords.lat()+'&lng='+coords.lng(),
        dataType: "xml",
        success: function(data) {
			var time = $(data).find('time').eq(0).text();
			var seconds = $(data).find('elapsedtime').eq(0).text();
			var altitude = $(data).find('altitude').eq(0).text();
			var distance = ($(data).find('distance').eq(0).text())/1000;
			var heartrate = $(data).find('heartrate').eq(0).text();
			var cadence = $(data).find('cadence').eq(0).text();

			viddlerSeek(video_player_id, seconds);
			
			createVideoPoint(point);

			var infoShell = document.createElement('div');
			infoShell.id = "overlayVideo";
			infoShell.className = "overlay";
			infoShell.innerHTML = '<div class="inner"><a href="#close" onclick="closeInfo(\'Video\'); return false;" id="close" class="close">Close</a><p><strong>Heart Rate:</strong> '+heartrate+'bpm</p><p><strong>Altitude:</strong> '+altitude+'m</p><p><strong>Distance:</strong> '+distance.toFixed(2)+'km</p><p><strong>Time:</strong> '+time+'</p></div>';
			map.getPane(G_MAP_MARKER_PANE).appendChild(infoShell);
			var markerPosition = map.fromLatLngToDivPixel(videoMarker.getPoint());
			var overlayBottom = parseInt(markerPosition.y)-(infoShell.offsetHeight+20);
			var overlayLeft = parseInt(markerPosition.x)-110;
			infoShell.style.top = overlayBottom+"px";
			infoShell.style.left = overlayLeft+"px";
			infoShell.style.visibility = "visible";
			map.panTo(videoMarker.getPoint());
		}
	});
}


function createVideoPoint(point, info) {
	// Create the icon
	var icon = new GIcon();
	icon.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
	icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
	icon.iconSize = new GSize(12, 20);
	icon.shadowSize = new GSize(22, 20);
	icon.iconAnchor = new GPoint(6, 20);
	icon.infoWindowAnchor = new GPoint(5, 1);

	if(videoMarker != null) {
		clearVideoPoint();
	}
	
	videoMarker = new GMarker(new GLatLng(point.y, point.x), icon, true);
	map.addOverlay(videoMarker);
	
	GEvent.addListener(videoMarker, "click", function() {
		$('#overlayVideo').show();
		map.panTo(videoMarker.getPoint());
	});
}

function clearVideoPoint() {
	if(videoMarker) {
		map.removeOverlay(videoMarker);
		$('#overlayVideo').remove();
	}
	videoMarker = null;
}

function createComparisonPoint(point) {
	// Create the icon
	var icon = new GIcon();
	icon.image = "http://labs.google.com/ridefinder/images/mm_20_purple.png";
	icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
	icon.iconSize = new GSize(12, 20);
	icon.shadowSize = new GSize(22, 20);
	icon.iconAnchor = new GPoint(6, 20);
	icon.infoWindowAnchor = new GPoint(5, 1);

	if(compMarkerOne != null && compMarkerTwo != null) {
		clearComparisonPoints();
	}
	
	if(compMarkerOne != null) {
		compMarkerTwo = new GMarker(new GLatLng(point.y, point.x), icon, true);
		map.addOverlay(compMarkerTwo);
	} else {
		compMarkerOne = new GMarker(new GLatLng(point.y, point.x), icon, true);
		map.addOverlay(compMarkerOne);
	}
}

function clearComparisonPoints() {
	if(compMarkerOne)
		map.removeOverlay(compMarkerOne);
	if(compMarkerTwo)
		map.removeOverlay(compMarkerTwo);
	compMarkerOne = compMarkerTwo = null;
	$('#results .details').slideUp('normal', function() { $('#results span').text(''); });
}

// Get comparison XML
function grabComparisonXML() {
	if(!compMarkerOne || !compMarkerTwo) {
		// Add better error handling in here!!
		alert('Please select two points on the route');
		return false;
	}
	
	$('.loading_data').animate({ opacity: 'show' }, 50);
	
	var pointOne = compMarkerOne.getLatLng();
	var pointTwo = compMarkerTwo.getLatLng();

	var route_id = $('#route_id').val();
	
	var url = '/routes/'+route_id+'/comparison/?lat1='+pointOne.lat()+'&lng1='+pointOne.lng()+'&lat2='+pointTwo.lat()+'&lng2='+pointTwo.lng();
	
	$.ajax({
        type: "GET",
        url: url,
        dataType: "xml",
        success: function(data) {
		
			var distance = data.getElementsByTagName("distance")[0];
			var total_time = data.getElementsByTagName("total_time")[0];
			var max_altitude = data.getElementsByTagName("max_altitude")[0];
			var slope = data.getElementsByTagName("slope")[0];
			var average_heartrate = data.getElementsByTagName("average_heartrate")[0];
			var average_speed = data.getElementsByTagName("average_speed")[0];
			var average_cadence = data.getElementsByTagName("average_cadence")[0];
			
			$('#results .details .distance').text($(distance).text());
			$('#results .details .total_time').text($(total_time).text());
			$('#results .details .max_altitude').text($(max_altitude).text());
			$('#results .details .slope').text($(slope).text());
			$('#results .details .average_heartrate').text($(average_heartrate).text());
			$('#results .details .average_speed').text($(average_speed).text());
			$('#results .details .average_cadence').text($(average_cadence).text());
			
			$('.loading_data').animate({ opacity: 'hide' }, 500);
			$('#results .details').slideDown('normal');
		}
	});
}

function toggleComparison() {
	$('#results').slideToggle('normal', function() {
		if($('.show-comparison').text() == 'Open Comparison Tools') {
			GEvent.clearListeners(polyline, "click");
			GEvent.addListener(polyline, "click", function(point) { createComparisonPoint(point); });
			$('.show-comparison').text('Close Comparison Tools');
			comparison = true;
		} else {
			GEvent.clearListeners(polyline, "click");
			clearComparisonPoints();
			GEvent.addListener(polyline, "click", function(point) { seekVideo(point); });
			$('.show-comparison').text('Open Comparison Tools');
			comparison = null;
		}
	});
}

function closeInfo(type) {
	if(type == 'Start' || type == 'End')
		$('#overlay'+type).remove();
	else
		$('#overlay'+type).hide();
	map.panTo(bounds.getCenter());
}