var map;
var panorama;
var time;
var bike = 'images/bike.png';
var bikeMarker = new google.maps.Marker({
                        icon: bike,
                        flat: true
                });

var markerArray = [];
var listenerArray = [];
var centerLat = 51.510452, centerLong = -0.124283;
var commisioned = "images/icons/largeTDBlueIcons/marker";
var full = "images/icons/largeTDYellowIcons/marker";
var uncommisioned = "images/icons/largeTDRedIcons/blank.png";
var infowindow = null;
var bounds = new google.maps.LatLngBounds();

function checkHash(){
	
        var re1 =/id=([0-9]*)/;
        var re2=/p=([0-9]*)/;
        var url=location.hash;
        
        var id=url.match(re1);
        var period=url.match(re2);
}

function initialize() {
	geocoder = new google.maps.Geocoder();
	var latlng = new google.maps.LatLng(centerLat, centerLong);
	    var myOptions = {
      		//zoom: 13,
      		//center: latlng,
      		mapTypeId: google.maps.MapTypeId.ROADMAP,
		streetViewControl: true
    		};
	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

	panorama = new google.maps.StreetViewPanorama(document.getElementById('map_canvas'));
        map.setStreetView(panorama);

        panorama.setOptions({
                        enableCloseButton: true,
                navigationControlOptions: {
                        position: google.maps.ControlPosition.TOP_LEFT,
                        style: google.maps.NavigationControlStyle.ZOOM_PAN
                }
        });
	panorama.setVisible(false);

	bikeMarker.setMap(panorama);
	google.maps.event.addListener(panorama, 'position_changed', function(){
                var brng = computeAngle(bikePoint,panorama.getPosition());
                var pov = panorama.getPov();
                pov.heading = brng;
                pov.pitch=-10;
                panorama.setPov(pov);
        });

	
	populate();
	//alert(bounds);
	map.fitBounds(bounds);
	setInterval("update()", 30000);
	return true; 
}


function populate(){
	//document.title="TfL Cycle Hire @ "+data.stations[1].time.substring(12);
	document.title="TfL updated feed @ "+data.summary[0].time.substring(11);

	document.getElementById("ba").innerHTML=data.summary[0].totAvailableBikes;
        document.getElementById("eds").innerHTML=data.summary[0].totNoBikes;
        document.getElementById("fds").innerHTML=data.summary[0].totFreeSpaces;
        document.getElementById("bds").innerHTML=data.summary[0].totLocked;
	document.getElementById("ads").innerHTML=data.summary[0].totStations;

	for (var index in data.stations){
	if(isNumber(data.stations[index].id)){
		
		var latlng = new google.maps.LatLng(data.stations[index].lat ,data.stations[index].long); 
		var id=data.stations[index].id;
		//alert(id);
		if(data.stations[index].lat !== undefined && data.stations[index].long !=="undefined")
			bounds.extend(latlng);
		if(data.stations[index].installed =="true" && data.stations[index].locked =="false"){
			//bounds.extend(latlng);
			if(data.stations[index].nbEmptyDocks != 0){
			markerArray[id] = new google.maps.Marker(
					{ position: latlng, 
					map: map, 
					title:data.stations[index].name, 
					icon: commisioned+data.stations[index].nbBikes+".png" 
					});
			}
			else{
			//bounds.extend(latlng);
			
			markerArray[id] = new google.maps.Marker(
                                       	{ position: latlng,
                                        map: map,
                                       	title:data.stations[index].name,
                                        icon: full+data.stations[index].nbBikes+".png"
                                        });
			}
						
			infoWindow(markerArray[id], id, data.stations[index],data.summary[0].time);
		}
	
		else{
			
			markerArray[id]= new google.maps.Marker(
                                        { position: latlng,
                                        map: map,
                                        title:"Out Of Order: "+data.stations[index].name,
                                        icon: uncommisioned
                                       	});
		}
	}
	}
}

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}
function infoWindow(marker, number,station,time) {
	var img="<a href='#'><img id='"+station.lat+""+station.long+"' width=180 height=180 onclick='sview("+station.lat+","+station.long+");' onerror='blankImg(this)' border=1px solid black; style='width: 145px; height 145px;' src='http://cbk0.google.com/cbk?output=thumbnail&w=195&h=195&ll="+station.lat+","+station.long+"&thumb=0'></a>";
	var ref=station.id;
	var str="<div align='center'>";
		str+="<table border=0 width=210px></table>";
		str+="<div id='"+ref+"_time'>"+time+"</div>";
		 str+="<div>"+station.name+"</div>";
		str+="<div><span id='"+ref+"_bikes'>"+station.nbBikes+"</span> bikes available</div>";
		str+="<div><span id='"+ref+"_spaces'>"+station.nbEmptyDocks+"</span> empty spaces</div>"
		str+="<div><a href='stats.php#id="+ref+"&p=24'>Site Statistics</a></div>"
		str+="<div>"+img+"</div>";
		str+="<i>(click image for streetview)</i>";
		str+="</div>";
	  
	listenerArray[ref]=google.maps.event.addListener(marker, 'click', function() {
	map.panTo(marker.getPosition());

	if (!infowindow) {
		infowindow = new google.maps.InfoWindow();
		infowindow.setContent(str);
		infowindow.open(map,marker);
	} else {
		infowindow.setContent(str);
		infowindow.open(map,marker);
	}
  	});
}

function update(){

new Ajax.Request('../cycleHire.json?'+Math.random()*12345678,
  {
    method:'get',
    onSuccess: function(transport){
      //var response = transport.responseText.evalJSON();
	var response = eval('(' + transport.responseText + ')');

      var ref;
 	var id;
	document.title="TfL updated feed @ "+response.summary[0].time.substring(11);
	
	for (var index in response.stations){
		id=response.stations[index].id;
		
		//check if existing marker is correct. If not, then fix it. 
		if(response.stations[index].installed=="true" && response.stations[index].locked=="false"){
			//according to the latest data, this site is live
			var iconString = markerArray[id].icon;
			var ref=response.stations[index].lat+""+response.stations[index].long;

			//remove the existing listener
			try{
				google.maps.event.removeListener(listenerArray[id]);
			}catch(err){}
			//update the infowindow with the latest timestamped data
			infoWindow(markerArray[id], id, response.stations[index],response.summary[0].time);

		//if the infowindow is open, then update it directly. Otherwise, we change the event listner	
		try{
			document.getElementById(id+"_time").innerHTML=response.summary[0].time;
			document.getElementById(id+"_bikes").innerHTML=response.stations[index].nbBikes;
			document.getElementById(id+"_spaces").innerHTML=response.stations[index].nbEmptyDocks;
			}
			catch(err){
			
			}
	
			if(iconString != commisioned+response.stations[index].nbBikes+".png"){
					var temp = new google.maps.MarkerImage(commisioned+response.stations[index].nbBikes+".png");
					if(response.stations[index].nbEmptyDocks == 0){
						temp = new google.maps.MarkerImage(full+response.stations[index].nbBikes+".png");
					}
					markerArray[id].setIcon(temp);
					markerArray[id].setTitle(response.stations[index].name);
			}
		}
		else{
		        var temp = new google.maps.MarkerImage(uncommisioned);
			markerArray[id].setIcon(temp);
			markerArray[id].setTitle("Out Of Order: "+response.stations[index].name);
			try{
				google.maps.event.removeListener(listenerArray[id]);
			}catch(err){}
		}

		document.getElementById("ba").innerHTML=response.summary[0].totAvailableBikes;
		document.getElementById("eds").innerHTML=response.summary[0].totNoBikes;
                document.getElementById("fds").innerHTML=response.summary[0].totFreeSpaces;
		document.getElementById("bds").innerHTML=response.summary[0].totNotInstalled+response.summary[0].totLocked;
		document.getElementById("ads").innerHTML=data.summary[0].totStations;

	}

    },
    onFailure: function(){ alert('Something went wrong...') }
  });

}

function blankImg(source){
        source.src="../images/Noimage.gif";
       	return true
}


function sview(lat,lng){
	
        var img=document.getElementById(lat+""+lng).src;
        if(img !="http://cycleHire.eu/images/cycleHire/Noimage.gif"){
                bikePoint = new google.maps.LatLng(lat,lng);
                bikeMarker.setPosition(bikePoint);
                panorama.setPosition(bikePoint);
                panorama.setVisible(true);
        }
}

function computeAngle(endLatLng, startLatLng) {
      var DEGREE_PER_RADIAN = 57.2957795;
      var RADIAN_PER_DEGREE = 0.01745329;

      var dlat = endLatLng.lat() - startLatLng.lat();
      var dlng = endLatLng.lng() - startLatLng.lng();
      // We multiply dlng with cos(endLat), since the two points are very closeby,
      // so we assume their cos values are approximately equal.
      var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat) * DEGREE_PER_RADIAN;
      return wrapAngle(yaw);
    }

function wrapAngle(angle) {
      if (angle >= 360) {
        angle -= 360;
      } else if (angle < 0) {
        angle += 360;
      }
      return angle;
    }


