function GPSControl() {
}
GPSControl.prototype = new GControl();
GPSControl.prototype.initialize = function(map) {
	var container = document.createElement("div");
	var zoomInDiv = document.createElement("div");
	this.setStyle(zoomInDiv);
	container.appendChild(zoomInDiv);
	this.zoomInDiv = zoomInDiv;
	zoomInDiv.appendChild(document.createTextNode("GPS: Loading..."));
	map.getContainer().appendChild(container);
	return container;
}
GPSControl.prototype.setStatus = function(status) {
	this.zoomInDiv.innerHTML = "GPS: <font color='red'>" + status + "</font>";
}
GPSControl.prototype.setStyle = function(el) {
	el.style.color = "#000000";
	el.style.backgroundColor = "white";
	el.style.border = "1px solid black";
	el.style.padding = "2px";
}
GPSControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(100, 7));
}
    
var centerBeforeInfoOpen;
function createMarker(point,html, type, map) {      
	var icon = new GIcon();
	icon.image = "icons/gmap/" + type + ".png";
	icon.shadow = "icons/gmap/" + type + ".shadow.png";
	icon.iconSize = new GSize(32, 32);
	icon.shadowSize = new GSize(32, 32);
	icon.iconAnchor = new GPoint(6, 32);
	icon.infoWindowAnchor = new GPoint(17, 10);
	var marker = new GMarker(point, icon); 
	GEvent.addListener(marker, "click", function() {
	  centerBeforeInfoOpen = map.getCenter();
	  marker.openInfoWindowHtml(html);
	});
	return marker;
}

function GetQuadtreeAddress(long, lat)
{
	var PI = 3.1415926535897;
	var digits = 18; // how many digits precision
	// now convert to normalized square coordinates
	// use standard equations to map into mercator projection
	var x = (180.0 + parseFloat(long)) / 360.0;
	var y = -parseFloat(lat) * PI / 180; // convert to radians
	y = 0.5 * Math.log((1+Math.sin(y)) / (1 - Math.sin(y)));
	y *= 1.0/(2 * PI); // scale factor from radians to normalized 
	y += 0.5; // and make y range from 0 - 1
	var quad = "t"; // google addresses start with t
	var lookup = "qrts"; // tl tr bl br
	var norm = "x: " + x + ", y: " + y;
	while (digits--)
	{
		// make sure we only look at fractional part
		x -= Math.floor(x);
		y -= Math.floor(y);
		quad = quad + lookup.substr((x>=0.5?1:0) + (y>=0.5?2:0), 1);
		// now descend into that square
		x *= 2;
		y *= 2;
	}
	return quad + norm;
}



function getTile(map) {
	var center = map.getCenter();
	var point = new GLatLng(center.lat(),center.lng());
//    map.addOverlay(new GMarker(point));

    var cp = map.getCurrentMapType().getProjection().fromLatLngToPixel(point, map.getZoom());
    
    var latLngBnds = map.getBounds();  
    var sw = latLngBnds.getSouthWest();
    var ne = latLngBnds.getNorthEast();
    
    var swp = map.getCurrentMapType().getProjection().fromLatLngToPixel(sw, map.getZoom());
    var nep = map.getCurrentMapType().getProjection().fromLatLngToPixel(ne, map.getZoom());
   
    var minDist = Math.max(Math.abs(swp.x - nep.x), Math.abs(swp.y - nep.y));
    var level = Math.ceil(Math.log(minDist) / Math.log(2));
    var gridSize = Math.pow(2, level) / 2;
    
    var idx = Math.floor(cp.x / gridSize); 
    var idy = Math.floor(cp.y / gridSize);
    
    var nwp = new GPoint((idx - 1) * gridSize, (idy - 1) * gridSize);
	var nw = map.getCurrentMapType().getProjection().fromPixelToLatLng(nwp, map.getZoom())
//	map.addOverlay(new GMarker(nw));

    var nep = new GPoint((idx + 2) * gridSize, (idy - 1) * gridSize);
	var ne = map.getCurrentMapType().getProjection().fromPixelToLatLng(nep, map.getZoom())
//	map.addOverlay(new GMarker(ne));

    var swp = new GPoint((idx - 1) * gridSize, (idy + 2) * gridSize);
	var sw = map.getCurrentMapType().getProjection().fromPixelToLatLng(swp, map.getZoom())
//	map.addOverlay(new GMarker(sw));

    var sep = new GPoint((idx + 2) * gridSize, (idy + 2) * gridSize);
	var se = map.getCurrentMapType().getProjection().fromPixelToLatLng(sep, map.getZoom())
//	map.addOverlay(new GMarker(se));
	
	return new GLatLngBounds(sw, ne);
}
      
function paintTrack(map,id) {
	
	var tile = getTile(map);	
	sw = tile.getSouthWest();
	ne = tile.getNorthEast();
	
	map.gpsControl.setStatus("Receiving satellite data...");
	start = (new Date()).getTime();
	
	GDownloadUrl("tracksList.html?s=" + sw.lat() + "&w=" + sw.lng() + "&n=" + ne.lat() + "&e=" + ne.lng() + "&z=" + map.getZoom() + "&r=" + /* Math.random() + */ "&episode_id=" + id, function(data) {
		
		var netTime = ((new Date()).getTime() - start);	
		var render = (new Date()).getTime();

		var xml = GXml.parse(data);
		
		var zoom = xml.documentElement.getElementsByTagName("zoom");
		if(map.getZoom() != zoom[0].getAttribute("value")) {
			// Old request -> discard
			return;
		}
		        	        
		// Remove old
		for(var i = 0; map.paintedTracks != null && i < map.paintedTracks.length; i++) {
			map.removeOverlay(map.paintedTracks[i]);
		}
		map.paintedTracks = new Array();
		        	          
		var tracks = xml.documentElement.getElementsByTagName("track");
		for (var i = 0; i < tracks.length; i++) {
			if(tracks[i].getAttribute("points") != "") {  
				var polyline = new GPolyline.fromEncoded({
				color: tracks[i].getAttribute("color"),
				weight: 4,
				opacity: 0.8,
				points: tracks[i].getAttribute("points"),
				levels: tracks[i].getAttribute("levels"),
				zoomFactor: 2,
				numLevels: 18
				});										
				try {
					map.addOverlay(polyline);
				}
				catch(e) {}
				map.paintedTracks[map.paintedTracks.length] = polyline;	  
			}           
		}	   	 
		
		map.gpsControl.setStatus("Receive: " + netTime + "ms, Render: " + ((new Date()).getTime() - render) + "ms");
		
	}); 	            
}	         
	  
