diff --git a/server/app.py b/server/app.py
index 712d32c93f10035f5f656a3568ad8299d2967521..53ec4e7e4481c1035103d405d2f7ecdc870382c5 100644
--- a/server/app.py
+++ b/server/app.py
@@ -205,20 +205,19 @@ def apiStopInfo(version):
 # URI: /api/v1/bus/<busId>/
 @app.route('/api/v<int:version>/bus/')
 @app.route('/api/v<int:version>/bus/<busId>/')
-def apiBusInfo(version, busId = None):
+@app.route('/api/v<int:version>/bus/<busId>/<getShape>/')
+def apiBusInfo(version, busId = None, getShape = "false"):
 	# busId is falsely optional here so that we can easily use url_for() for this endpoint in js
 	if int(version) == 1 and busId != None:
 
-		# TODO:
-		# - line name
-		# - Shape of the route
-		# - next stop?
-		# - estimated arrival?
-		# - what else?
-		print(busId)
+		lastModified, dynamicData = locator.getLastResponse()
 
-		# for now return a static json
-		data = loadJson('bus.json')
+		data = dynamicData["result"]["vehicles"][busId]
+
+		# add shape to the data
+		# route_short_name = lineref from data
+		if (getShape == "true"):
+			data["shape"] = gtfs.getShape(data["lineref"])
 		if data:
 			return jsonify(data)
 
diff --git a/server/gtfs.py b/server/gtfs.py
index ddb2e172807b788f0dd3ea54accb21f57844746c..8c6f2848aa8929590e912ea98618440a862103c6 100644
--- a/server/gtfs.py
+++ b/server/gtfs.py
@@ -80,6 +80,9 @@ class GtfsHandler(object):
 		loader = transitfeed.Loader(feedPath)
 		self.schedule = loader.Load()
 
+		#print("trips")
+		#print(self.schedule.trips)
+
 		# filter unused stops
 		for stopId, stop in self.schedule.stops.items():
 			if not stop.GetTrips(self.schedule):
@@ -342,6 +345,28 @@ class GtfsHandler(object):
 
 		return stop.stop_timezone
 
+	def getShape(self, lineref):
+		print("looking for shape from lineref " + lineref)
+
+		# find route id from routes.txt
+		# then find shape id from trips.txt
+		# with shape id find shape from shapes.txt
+		routeId = None
+		for key, route in self.schedule.routes.iteritems():
+			if (route.route_short_name == lineref):
+				routeId = key
+
+		print("found routeId ")
+		print(routeId)
+		shapeId = None
+		for key, trip in self.schedule.trips.iteritems():
+			if (trip.route_id == routeId):
+				shapeId = trip.shape_id
+				break
+
+		shape = self.schedule._shapes[shapeId].points
+		return shape
+
 	def setLocator(self, locatorService):
 		self.locator = locatorService
 
diff --git a/templates/map.html b/templates/map.html
index 31fd5cd66b86c7a7314b5ff6f8ff13906734a409..1fec184b7346fb65f1e3091bcfa280f6461ecaf8 100644
--- a/templates/map.html
+++ b/templates/map.html
@@ -71,6 +71,7 @@
 		var focusedMarker = undefined;
 		var focusedBus = undefined;
 		var focusedShape = undefined;
+		var focusedBusWindow = undefined;
 		var apiEndpoint = "{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}";
 		var trackingLoop = null;
 		var currentMode = null;
@@ -171,6 +172,10 @@
 					console.log('stopped from double click');
 					return;
 				}
+				if (focusedShape !== undefined) {
+					focusedShape.setMap(null);
+					focusedShape = undefined;
+				}
 			}
 
 			focusedMarker = marker.title;
@@ -210,7 +215,7 @@
 						markers[key] = tmpMarker;
 					});
 
-					console.log('markers: ', markers);
+					console.log('data: ', data);
 					gmarkers = markers;
 
 					busTrackingLoop("all");
@@ -269,38 +274,21 @@
 			// get information about the focused bus
 			var requestFocus = focusedMarker;
 			$.getJSON(
-				// cheat way? need the dynamic busId to the api, don't know how to do it any other way
-				 "{{ url_for('apiBusInfo', version = 1, _external = True) }}" + focusedMarker,
+				 "{{ url_for('apiBusInfo', version = 1, _external = True) }}" + focusedMarker + '/true',
 				function (data) {
 					// poor man's locking (the A in Ajax is for Asynchronous :))
 					if (requestFocus !== focusedMarker)
 						return;
 
-					focusedBus = {};
-					$.each( data, function( key, value ) {
-						focusedBus[key] = value;
-					});
+					focusedBus = data;
 
 					console.log("found this bus info: ", focusedBus);
 
-					// TODO is there a better way of doing this, this way is pretty ugly
-					var infoWindowContent = `
-					<h1>` + focusedBus.line_name + `</h1>
-					Next Stop: ` + focusedBus.next_stop + ` <br>
-					Estimated Arrival ` + focusedBus.estimated_arrival + `
-					`;
-
-					// open a popup window to show details of the bus
-					var infowindow = new google.maps.InfoWindow({
-						content: infoWindowContent
-					});
-					infowindow.open(gmap, gmarkers[focusedMarker]);
-
 					// draw the shape
 					var shapeCoordinates = [];
 					focusedBus.shape.map( value => {
-						console.log("value 2", value[2], " value 3", value[3]);
-						shapeCoordinates.push(positionToGoogleLatLng(value[2], value[3]));
+						//console.log("value 2", value[2], " value 3", value[3]);
+						shapeCoordinates.push(positionToGoogleLatLng(value[0], value[1]));
 					});
 					focusedShape = new google.maps.Polyline({
 						map: gmap,
@@ -309,8 +297,7 @@
 						strokeOpacity: 1.0,
 						strokeWeight: 2
 					});
-					console.log("shapeCoordinates ", shapeCoordinates);
-					console.log("busSHpae ", busShape);
+					updateInfoWindow();
 				}
 			);
 
@@ -325,26 +312,25 @@
 		};
 
 		var drawOneBus = function() {
-			$.getJSON(apiEndpoint,
-				function (data) {
+			$.getJSON(
+				"{{ url_for('apiBusInfo', version = 1, _external = True) }}" + focusedMarker + '/false',
+				function (resultData) {
 					// poor man's locking
 					if (trackingLoop === null)
 						return;
 
-					var resultData = data[focusedMarker];
 					// if the focused bus disappeared from the list, just go back to the 'all' mode
 					if (resultData === undefined) {
 						console.log('lost track of the bus, going back to normal mode');
-						currentMode = "all";
-						focusedMarker = undefined;
-						gmap.setZoom(mapZoom);
-						gmap.panTo(positionToGoogleLatLng(busStop.stop_lat, busStop.stop_lon));
-						return;
+						mapClicked();
 					} else {
 						// getting here means that the bus is still active
 						// => update its position
 						marker = gmarkers[focusedMarker];
+						//resultData.map(value, key => console.log("value", value, " key ", key));
+						focusedBus = resultData;
 
+						updateInfoWindow();
 						// get more information about the bus
 						position = positionToGoogleLatLng(resultData.latitude, resultData.longitude);
 						marker.setPosition(position);
@@ -354,6 +340,27 @@
 			)
 		};
 
+		// creates or updates the info window for focused bus
+		var updateInfoWindow = function() {
+			//console.log("dynamicdata: ", dynamicData);
+			// TODO is there a better way of doing this, this way is pretty ugly
+			var infoWindowContent = `
+			<h1>` + focusedBus.lineref + `</h1>
+			Next Stop: ` + focusedBus.next_stoppointname + ` <br>
+			Aimed Arrival: ` + focusedBus.next_aimedarrivaltime + ` <br>
+			Expected Arrival: ` + focusedBus.next_expectedarrivaltime + ` <br>
+			`;
+
+			if (focusedBusWindow === undefined) {
+				focusedBusWindow = new google.maps.InfoWindow({
+					content: infoWindowContent
+				});
+				focusedBusWindow.open(gmap, gmarkers[focusedMarker]);
+			} else {
+				focusedBusWindow.setContent(infoWindowContent);
+			}
+		}
+
 		$(document).ready(function() {
 			console.log(busStop);