//global variables
var geocoder = null; //address handling
var map = null; //the map

//track generation variables
var points = []; //marked points on the polyline
var point_markers = []; //associated markers being displayed
var point_marker = null; //"green" point
var polyline = null; //blue polyline

//show tracks variables
var trial = null; //the currently displayed track
var loaded = []; //the ids of already retrieved tracks by the database


//=========================================================================
//Marker, Description and Polyline View Generation of retrieved Tracks

function parseMapPosts(data){

       var xml = GXml.parse(data);
       var markers = xml.documentElement.getElementsByTagName("posting");
       for (var i = 0; i < markers.length; i++) {
         var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                    parseFloat(markers[i].getAttribute("lng")));
	      var tmarker = createPostMarker(point,markers[i]);
         map.addOverlay(tmarker);
	      //GEvent.addListener(map, "click", function() {
			//	this.openInfoWindowHtml(this.info);
	      //});
	    }

}


function createPostMarker(point,data){
  var tIcon = new GIcon(G_DEFAULT_ICON);
  	tIcon.image = "tracking/images/info.png";
  	tIcon.shadow = "tracking/images/info.shadow.png";
 
  var marker = new GMarker(point,{icon:tIcon});
 
  marker.info = data.getAttribute("mappost");

  return marker;
}



function parseTracks(data){
            var xml = GXml.parse(data);
            var markers = xml.documentElement.getElementsByTagName("track");
            for (var i = 0; i < markers.length; i++) {
              loaded.push(markers[i].getAttribute("id"));
              var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                    parseFloat(markers[i].getAttribute("lng")));
	      var tmarker = createTrackMarker(point,markers[i]);
              map.addOverlay(tmarker);
	      GEvent.addListener(tmarker, "click", function() {
			this.openInfoWindowHtml(this.info);
			if (trial) {map.removeOverlay(trial);}
			trial=this.trial;
			map.addOverlay(trial);
	      });
	    }
}


function createTrackMarker(point,data){
  var tIcon = new GIcon(G_DEFAULT_ICON);
  if (data.getAttribute("type")==0) {
  	tIcon.image = "tracking/images/flag.png";
  	tIcon.shadow = "tracking/images/flag.shadow.png";
  } else {
  	tIcon.image = "tracking/images/cycling.png";
  	tIcon.shadow = "tracking/images/cycling.shadow.png";
  }

  var marker = new GMarker(point,{icon:tIcon});
  marker.trial = GPolyline.fromEncoded({color: "#0000FF",
                           weight: 3,
                           points: data.getAttribute("points"),
                           zoomFactor: 32,
                           levels: data.getAttribute("levels"),
                           numLevels: 4
                       });
  var light = document.languageInfo.no.value;
  if (data.getAttribute("light")==1) {light=document.languageInfo.yes.value;}

  var difficulty = "";
  for (var i=1; i<=5; i++){
     if (i<=data.getAttribute("difficulty")){
	difficulty += "<img src=\"tracking/images/star_on.gif\">";
     } else {
	difficulty += "<img src=\"tracking/images/star_off.gif\">";
     }
  }

  marker.info = "<b>"+data.getAttribute("name")
                 +"</b><br>\n<p style=\"font-family:Arial,sans-serif; font-size:10px; color:blue; width: 300px;\">"
                 +document.languageInfo.distance.value+": ca "+Math.ceil(marker.trial.getLength()/10.0)/100.0+"km<br>"
                 +document.languageInfo.light.value+": "+light+"<br>"
                 +document.languageInfo.pavement.value+": "+data.getAttribute("pavement")+"<br><br>"
                 +document.languageInfo.difficulty.value+": "+difficulty+"<br><br>"
                 +data.getAttribute("description")+"<br><br>"
					  +document.languageInfo.owner.value+": "+data.getAttribute("owner")+"<br>"
					  +"<a href=\"trackDetails.php?id="+data.getAttribute("id")+"\">Show more details</a></p><br>";

  return marker;
}





//===========================================================================
//Marker creation and editing of polylines and markers for track generation

function createPolylineMarker(point, color) {
  var f = new GIcon();
  f.image = "tracking/images/mm_20_" + color + ".png";
  f.shadow = "tracking/images/mm_20_shadow.png";
  f.iconSize = new GSize(12,20);
  f.shadowSize = new GSize(22,20);
  f.iconAnchor = new GPoint(6,20);
  f.infoWindowAnchor = new GPoint(6,1);
  f.infoShadowAnchor = new GPoint(13,13);

  newMarker = new GMarker(point,
    {icon: f,
     draggable: true});

  return newMarker;
}

// Add a point to the points list.
function addPoint() {
  if (point_marker==null) return;
  var newPoint = new GLatLng(point_marker.getPoint().lat(),point_marker.getPoint().lng());
  points.push(newPoint);

  marker = createPolylineMarker(newPoint, "blue");
  marker.disableDragging();
  point_markers.push(marker);
  map.addOverlay(marker);

  if (polyline) map.removeOverlay(polyline);
  polyline = new GPolyline(points, "#0000ff", 3);
  map.addOverlay(polyline);

  map.removeOverlay(point_marker);
  point_marker=null;
}

function removePoint() {
  if (points.length == 0) return;
  map.removeOverlay(point_markers.pop());
  points.pop();
  if (polyline) map.removeOverlay(polyline);
  polyline = new GPolyline(points, "#0000ff", 3);
  map.addOverlay(polyline);
}

function clearPath(){
  while (points.length>0){
    map.removeOverlay(point_markers.pop());
    points.pop();
  }
  if (polyline) map.removeOverlay(polyline);
  polyline = new GPolyline(points, "#0000ff", 3);
  map.addOverlay(polyline);
}

//==============================================================================
//Encoding of tracks for storage in the database

// Encode a signed number in the encode format.
function encodeSignedNumber(num) {
  var sgn_num = num << 1;

  if (num < 0) {
    sgn_num = ~(sgn_num);
  }

  return(encodeNumber(sgn_num));
}

// Encode an unsigned number in the encode format.
function encodeNumber(num) {
  var encodeString = "";

  while (num >= 0x20) {
    encodeString += (String.fromCharCode((0x20 | (num & 0x1f)) + 63));
    num >>= 5;
  }

  encodeString += (String.fromCharCode(num + 63));
  return encodeString;
}



// Create the encoded polyline and level strings. If moveMap is true
// move the map to the location of the first point in the polyline.
function createEncodings() {
  var i = 0;

  var plat = 0;
  var plng = 0;

  var encoded_points = "";
  var encoded_levels = "";

  for(i = 0; i < points.length; ++i) {
    //var point = points[i];
    var lat = points[i].lat();
    var lng = points[i].lng();;
    var level = 3;

    var late5 = Math.floor(lat * 1e5);
    var lnge5 = Math.floor(lng * 1e5);

    dlat = late5 - plat;
    dlng = lnge5 - plng;

    plat = late5;
    plng = lnge5;

    encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
    encoded_levels += encodeNumber(level);
  }
	//alert('1');
  //document.getElementById('encodedLevels').value = encoded_levels;
  //document.getElementById('encodedPolyline').value = encoded_points;
	document.EditingForm.encodedLevels.value = encoded_levels;
	//alert('2');
	document.EditingForm.encodedPolyline.value = encoded_points;
}

function fillForm() {
   if (points.length == 0) {
	alert('Your track needs to have at least one waypoint!');
	//return false;
   }
	//alert('a');
   createEncodings();
	//alert('b');
   //document.getElementById('lat').value = points[0].lat();
	//alert('3');
   //document.getElementById('lng').value = points[0].lng();
	document.EditingForm.lat.value = points[0].lat();
	document.EditingForm.lng.value = points[0].lng();
	document.EditingForm.length.value = Math.ceil(polyline.getLength()/10.0)/100.0;
	document.EditingForm.submit();

   //return true;
}




//============================================================================================
//Handling of tracks on the map, mapposts and tracks nearby

function retrieveMapPosts(id){
  var url = "tracking/src/getTrackPosts.php?id="+id+"&r="+Math.random();
  GDownloadUrl(url, function(data, responseCode) {
          if(responseCode == 200) {
                //removeTracks();
		parseMapPosts(data);
          } else if(responseCode == -1) {
	    alert("Data request timed out. Please try later.");
          } else { 
            alert("Request resulted in error. Check XML file is retrievable.");
          }
        
  });

}

function retrieveTracks(){
  var b = map.getBounds();
  var north = b.getNorthEast().lat();
  var south = b.getSouthWest().lat();
  var east = b.getNorthEast().lng();
  var west = b.getSouthWest().lng();
  var url = "tracking/src/getTracks.php?n=" +north+ "&s=" +south+"&e=" +east + "&w="+west+"&ids="+loaded.join(",");
  
  GDownloadUrl(url, function(data, responseCode) {
          if(responseCode == 200) {
                //removeTracks();
		parseTracks(data);
          } else if(responseCode == -1) {
	    alert("Data request timed out. Please try later.");
          } else { 
            alert("Request resulted in error. Check XML file is retrievable.");
          }
        
  });
}

function retrieveNearestTrackList(){
  var url = "tracking/src/nearestTracks.php?lat=" +map.getCenter().lat()+ "&lng=" +map.getCenter().lng();
  GDownloadUrl(url, function(data, responseCode) {
          if(responseCode == 200) {
		printTop10List(data);
          } else if(responseCode == -1) {
	    alert("Data request timed out. Please try later.");
          } else { 
            alert("Request resulted in error. Check XML file is retrievable.");
          }
        
  });
}

function printTop10List(data){
   var xml = GXml.parse(data);
   var tracks = xml.documentElement.getElementsByTagName("track");
   var content="<table cellpadding=\"6\">";//<tr><td colspan=\"2\">"+document.languageInfo.nearest_tracks.value+"</td></tr>\n";
   for (var i = 0; i < tracks.length; i++) {
     content += "<tr><td><a href=\"javascript:panToTrack("+tracks[i].getAttribute("lat")+","+tracks[i].getAttribute("lng")+")\">"+tracks[i].getAttribute("name")+"</a><br>";
     content += "</td><td>"+tracks[i].getAttribute("distance")+"km</td></tr>";
   }
   content += "</table>";
   document.getElementById('top10').innerHTML = content;
}

function panToTrack(lat,lng){
   map.panTo(new GLatLng(lat,lng));
}



//=======================================================================================0
//Map Creation

//Map to generate new tracks
function createEditingMap(lat,lng,z) {
  if (!GBrowserIsCompatible()) {
    alert('Your browser is not compatible with the Google Maps API');
    return;
  }

  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(new GLatLng(lat,lng), z);
  map.addControl(new GMapTypeControl());
  map.addControl(new GLargeMapControl());
  map.enableScrollWheelZoom();

  geocoder = new GClientGeocoder();

/*		document.Create.lat.value=map.getCenter().lat();
		document.Create.lng.value=map.getCenter().lng();
		document.Create.z.value=map.getZoom();
		document.Find.lat.value=map.getCenter().lat();
		document.Find.lng.value=map.getCenter().lng();
		document.Find.z.value=map.getZoom();
*/

  // Listen for the "moveend" event
/*GEvent.addListener(map, "moveend", function() {
	document.Create.lat.value=map.getCenter().lat();
		document.Create.lng.value=map.getCenter().lng();
		document.Create.z.value=map.getZoom();
		document.Find.lat.value=map.getCenter().lat();
		document.Find.lng.value=map.getCenter().lng();
		document.Find.z.value=map.getZoom();
  });*/

  GEvent.addListener(map, "click", function(overlay, point) {
    if (point==null) {return;}
    if (point_marker == null) {
      point_marker = createPolylineMarker(point, "green");
      map.addOverlay(point_marker);
    } else {
      point_marker.setPoint(point);
    }
  });

   GEvent.addListener(map, "singlerightclick", function(point,src,overlay) {
     if (point_marker!=null) {
       addPoint();
     }
  });

}

// Map to search tracks
function createSearchMap(lat,lng,z) {
  if (!GBrowserIsCompatible()) {
    alert('Your browser is not compatible with the Google Maps API');
    return;
  }

  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(new GLatLng(lat,lng), z);
  map.addControl(new GMapTypeControl());
  map.addControl(new GLargeMapControl());
  map.enableScrollWheelZoom();

  geocoder = new GClientGeocoder();

/*	document.Create.lat.value=map.getCenter().lat();
	document.Create.lng.value=map.getCenter().lng();
	document.Create.z.value=map.getZoom();
	document.Find.lat.value=map.getCenter().lat();
	document.Find.lng.value=map.getCenter().lng();
	document.Find.z.value=map.getZoom();
*/
  retrieveTracks();
  retrieveNearestTrackList();

  // Listen for the "moveend" event
  GEvent.addListener(map, "moveend", function() {
/*		document.Create.lat.value=map.getCenter().lat();
		document.Create.lng.value=map.getCenter().lng();
		document.Create.z.value=map.getZoom();
		document.Find.lat.value=map.getCenter().lat();
		document.Find.lng.value=map.getCenter().lng();
		document.Find.z.value=map.getZoom();
*/
      retrieveTracks();
      retrieveNearestTrackList();
  });
}

//Map that is shown prior to storing new tracks
function createVerifyMap() {
  if (!GBrowserIsCompatible()) {
    alert('Your browser is not compatible with the Google Maps API');
    return;
  }
  
  var marker = new GMarker(new GLatLng(document.Form.lat.value,document.Form.lng.value));
  var trial = GPolyline.fromEncoded({color: "#0000FF",
                                     weight: 3,
                                     points: document.Form.encodedPolyline.value,
                                     zoomFactor: 32,
                                     levels: document.Form.encodedLevels.value,
                                     numLevels: 4
                                    });

  map = new GMap2(document.getElementById("map_canvas"));
  map.disableDragging()
  map.setCenter(trial.getBounds().getCenter(), map.getBoundsZoomLevel(trial.getBounds()));

  
  map.addOverlay(marker);
  map.addOverlay(trial);

}

//Map that is shown prior to storing new tracks
function createDetailsMap() {
  if (!GBrowserIsCompatible()) {
    alert('Your browser is not compatible with the Google Maps API');
    return;
  }
  
  var marker = new GMarker(new GLatLng(document.Form.lat.value,document.Form.lng.value));
  var trial = GPolyline.fromEncoded({color: "#0000FF",
                                     weight: 3,
                                     points: document.Form.encodedPolyline.value,
                                     zoomFactor: 32,
                                     levels: document.Form.encodedLevels.value,
                                     numLevels: 4
                                    });

  map = new GMap2(document.getElementById("map_canvas"));
  map.addControl(new GMapTypeControl());
  map.addControl(new GLargeMapControl());
  map.enableScrollWheelZoom();

  geocoder = new GClientGeocoder();

  map.setCenter(trial.getBounds().getCenter(), map.getBoundsZoomLevel(trial.getBounds()));

  
  map.addOverlay(marker);
  map.addOverlay(trial);

  retrieveMapPosts(document.Form.id.value);

  GEvent.addListener(map, "click", function(overlay, point) {
	 if (overlay!=null) {
	 	if (overlay.info!==undefined){overlay.openInfoWindowHtml(overlay.info);}
	 } else {
		
		 if (point_marker==null){
	      		point_marker = createPolylineMarker(point, "green");
		   GEvent.addListener(point_marker, "dragend", function() {
				updateInfoText(point_marker);			
				point_marker.openInfoWindowHtml(point_marker.info);
		   });
		   GEvent.addListener(point_marker, "dragstart", function() {
				point_marker.closeInfoWindow();
		   });
		   	updateInfoText(point_marker);
			map.addOverlay(point_marker);
			point_marker.openInfoWindowHtml(point_marker.info);
	 	 } else {
	      		point_marker.setPoint(point);
			updateInfoText(point_marker);
			point_marker.openInfoWindowHtml(point_marker.info);
		 }
	}

  });

}


function updateInfoText(infomarker){
	point_marker.info="<br><form action=\"trackDetails.php\" method=\"get\">"
		+"<input type=\"hidden\" name=\"id\" value=\""+document.Form.id.value+"\">"
		+"<input type=\"hidden\" name=\"lat\" value=\""+infomarker.getPoint().lat()+"\">"
		+"<input type=\"hidden\" name=\"lng\" value=\""+infomarker.getPoint().lng()+"\">"
		+"<textarea name=\"mappost\" cols=\"30\" rows=\"5\"></textarea><br>"
		+"<input type=\"submit\" value=\"Send Message\"/></form>";

}



//=============================================================================0
//Address handling
function showAddress(address, zoom) {
   if (geocoder) {
      geocoder.getLatLng(address,function(point) {
        if (!point) {
           alert(address + " not found");
        } else {
           map.setCenter(point, zoom);
           var marker = new GMarker(point);
           map.addOverlay(marker);
        }
      });
    }
}


//=========================================================================0
//Form verification

function checkForm() {
  if (document.Form.title.value==""){
    alert('Please, enter a title for this track!');
    document.Form.title.focus();
    //return false;
  } else {
    //return true;
    document.Form.submit();
  }
}

function mapBrowse(content){
	document.browseMap.content.value=content;
	document.browseMap.lat.value=map.getCenter().lat();
	document.browseMap.lng.value=map.getCenter().lng();
	document.browseMap.z.value=map.getZoom();
	document.browseMap.submit();
}
