var map;
var SoloGrafico = false;
var PuntiMappa = [];
var PuntiGrafico = [];
var TempiGrafico = [];
var VelocitaGrafico = [];
var polyline; 
var CentroLon, CentroLat;
var MaxLat = -1000, MaxLon = -1000, MinLat = 1000, MinLon = 1000;  
var ActPosition = null;
var PlotMappa; var PlotVelocita; var MoviePos = 999999;

function carica(NomeGPX) {
   if (GBrowserIsCompatible()) {
      map = new GMap2(document.getElementById('map'));
/*      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      var sw = new GLatLng(" . $node->LatMin . ",". $node->LonMin . ");
      var ne = new GLatLng(" . $node->LatMax .",". $node->LonMax . ");
      var bounds = new GLatLngBounds(sw, ne);
      var zoom = map.getBoundsZoomLevel(bounds);
      map.setCenter(new GLatLng(" . $node->Lat . "," . $node->Lon . "), zoom);*/
		map.setUIToDefault();
		map.setMapType(G_PHYSICAL_MAP) ; 
	  
		//	map.addControl(new GSmallMapControl());  //Caricamento controlli navigazione sulla mappa
		//	map.addControl(new GMapTypeControl()); //Caricamento controllo visualizzazione tipologia 
		//  map.addControl(new GScaleControl());
		//	controllo finestrella
		//	map.addControl(new GOverviewMapControl()); 
	  
      TourCreate(NomeGPX, false);
   }
}


// Estrae i dato dal file XML
// In Input : NomeFile: nome del file da scandire (per adesso solo xml)
//            GraphHeight
//            GraphWidth  : Altezza e Larghezza del DIV contenente il garfico (0 e 0 = no grafico)
//            GraphOnly   : Solo Grafico

function TourCreate(NomeFile, GraphOnly) {
    var Elementi, percorsi , Descrizione;
    SoloGrafico = GraphOnly;
      
    if (window.ActiveXObject) {
        // IE
        xmlhttp = new ActiveXObject("Msxml2.DOMDocument.3.0");
        xmlhttp.async = true;
        xmlhttp.onreadystatechange = function () {
                                         if (xmlhttp.readyState == 4 && xmlhttp.parseError.errorCode == 0) {
                                            ScansioneFile(xmlhttp);
                                         }
                                     };
        xmlhttp.load(NomeFile);
    }                          
    else if (document.implementation && document.implementation.createDocument) {
        // Mozilla
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
                                        if (xmlhttp.readyState == 4) {
                                           ScansioneFile(xmlhttp.responseXML);
                                         }
                                     };            
        xmlhttp.open("GET", NomeFile, true);
        xmlhttp.overrideMimeType("text/xml");
        xmlhttp.send(null)
    }
}

// Scandisce il file XML
function ScansioneFile(xmlDoc) {
   ConLimiti = false;

   // Limiti
   if (xmlDoc.getElementsByTagName("bounds").length != 0) {
      ConLimiti = true;
      MaxLat = parseFloat(xmlDoc.getElementsByTagName("bounds")[0].getAttribute("maxlat"));
      MinLat = parseFloat(xmlDoc.getElementsByTagName("bounds")[0].getAttribute("minlat"));
      MaxLon = parseFloat(xmlDoc.getElementsByTagName("bounds")[0].getAttribute("maxlon"));
      MinLon = parseFloat(xmlDoc.getElementsByTagName("bounds")[0].getAttribute("minlon"));
   }

   // Lettura dei waypoints
   var wpt= xmlDoc.getElementsByTagName("wpt");
   var ContaWP;
   for (ContaWP=0;ContaWP<wpt.length;ContaWP++) {

      if (wpt[ContaWP].getElementsByTagName("desc").length != 0 && wpt[ContaWP].getElementsByTagName("desc")[0].firstChild != null) {
         Descrizione = wpt[ContaWP].getElementsByTagName("desc")[0].firstChild.data
      } else
        Descrizione = "";
      if (wpt[ContaWP].getElementsByTagName("name").length != 0 && wpt[ContaWP].getElementsByTagName("name")[0].firstChild != null) 
         Nome = ContaWP + ") " + wpt[ContaWP].getElementsByTagName("name")[0].firstChild.data
      else
        Nome = ContaWP + ")";
              
      // Crea l'array con i link
      var ListaLink = [];
      if (wpt[ContaWP].getElementsByTagName("link")[0] != null) {
         for (var i=0; i < wpt[ContaWP].getElementsByTagName("link").length; i++) {
            var Text = wpt[ContaWP].getElementsByTagName("link")[i].getElementsByTagName("text")[0].firstChild.data;
            var Type = wpt[ContaWP].getElementsByTagName("link")[i].getElementsByTagName("type")[0].firstChild.data;
            var Href = wpt[ContaWP].getElementsByTagName("link")[i].getElementsByTagName("href")[0].firstChild.data;
            var Link = {text: Text, type: Type, href: Href};
            ListaLink.push(Link);
         }
      };
           
      // Creazione del Waypoint
      if (SoloGrafico == false)
         CreaWaypoint(ConLimiti, parseFloat(wpt[ContaWP].getAttribute("lat")), parseFloat(wpt[ContaWP].getAttribute("lon")),          Descrizione, Nome, ListaLink);
   }
        
   // Lettura dei trackpoints
   if (xmlDoc.getElementsByTagName("trkpt").length != 0);
      CreaTraccia(xmlDoc.getElementsByTagName("trkpt"), ConLimiti);
        
   // Lettura dei routepoint
   if (xmlDoc.getElementsByTagName("rtept").length != 0);
      CreaTraccia(xmlDoc.getElementsByTagName("rtept"), ConLimiti);

   var DeltaLat = MaxLat - MinLat;
   var DeltaLon = MaxLon - MinLon;
   CentroLat =  MinLat + (DeltaLat / 2);
   CentroLon =  MinLon + (DeltaLon / 2);
   
   // Opzioni per grfici altimetria/velocità
   var options = {
        lines: { show: true },
        legend: { position: "nw", type: 2},
        xaxis: { tickDecimals: 0 },
        grid: { onmouseover: true},
        selection: { color: "#e4e700"}
   };
   
   // Grafico delle altitudini tramite jquery plot
   if (document.getElementById('GraficoMappa') != null && PuntiGrafico.length != 0) {
      PlotMappa = $.plot($("#GraficoMappa"), [{label: "Altimetria", data: PuntiGrafico}], options);
   }
   else if (document.getElementById('GraficoMappa') != null) {
      document.getElementById('GraficoMappa').innerHTML = '<center>Grafico altitudine non presente</center>';
      document.getElementById('GraficoMappa').style.backgroundColor = "#eee"; 
   }
   
   // Grafico delle velocità tramite jquery plot
   if (document.getElementById('GraficoVelocita') != null && VelocitaGrafico.length != 0)  {
      // Allinea il margine destro a quello del grafico precedente
      options.legend = { position: "nw", type: 2, LeftOffset: PlotMappa.LeftOffset};
      PlotVelocita = $.plot($("#GraficoVelocita"), [{label: "Velocita'", data: VelocitaGrafico}], options);
   } else if (document.getElementById('GraficoVelocita') != null) {
      document.getElementById('GraficoVelocita').innerHTML = "<center>Grafico velocita' non presente</center>"; 
      document.getElementById('GraficoVelocita').style.backgroundColor = "#eee"; 
   }

   if (PuntiGrafico.length == 0 && VelocitaGrafico.length == 0) 
      document.images['StartStop'].src = '';
     
   if (SoloGrafico == false)
      CreaMappa();

}

var bike_icon = new GIcon(G_DEFAULT_ICON, "/images/gpx_position.png")

// OnMouseOver sull'altimetria
$("#GraficoMappa").bind("mouseover", function (e, pos) {
   if (pos != null && pos.pos!=0)  
      DrawActivePos(pos, 'm')
});
// OnMouseOver sulla velocità
$("#GraficoVelocita").bind("mouseover", function (e, pos) {
   if (pos != null && pos.pos!=0) 
      DrawActivePos(pos, 'v')
});

/* Disegna le rige verticali della posizione attuale e visualizza il marker sulla mappa
   type =    tipo di evento scatenante
   pos.pos = indice dell'array dei punti
   pos.x   = distanza del punto
   pos.y   = altitudine  */
function DrawActivePos(pos, type) {
  var time = TempiGrafico[pos.pos] ;
  var speed = Velocita(pos.pos);
  if (type == 'm') {
     // mouse mosso su mappa altitudine
     if (PlotVelocita != null) 
        PlotVelocita.drawPosition(pos.pageX);
  }
  else if (type == 'v')
     // mouse mosso su mappa altitudine
     PlotMappa.drawPosition(pos.pageX);
  else {
     // Automatico
     PlotMappa.drawPosition(pos.x, false);
     if (PlotVelocita != null)
        PlotVelocita.drawPosition(pos.x, false);
  }
  
  if (ActPosition != null)
     map.removeOverlay(ActPosition);
  ActPosition = new GMarker(PuntiMappa[pos.pos], {icon:bike_icon, zLayer:0});
  map.addOverlay(ActPosition);
// fumetto che indica velocità, dislivello, distanza percorsa - discommentare per vederlo
//  if (time == null)
//     var TimeHTML = ''
//  else
//     var TimeHTML = "<tr><th>Tempo</th><td>" + SecondsToString(time) + "</td></tr>" + 
//                    "<tr><th>Velocita'</th><td>" + speed + " Km./h.</td></tr>";
//  ActPosition.openInfoWindow("<table id='InfoPosition'><tr><th>Distanza</th><td>" + FillZeri(Math.round(pos.x*1000)/1000, 3, true) + ' Km.' + 
//                             "</td></tr><tr><th>Altitudine</th><td>" + Math.round(pos.y)  + ' m.' + 
//                             "</td></tr>"  + TimeHTML + "</table>", {maxWidth:205});
};

// Simulazione
function PlayMovie() {
   // Disegna un passo del video percorso
   if (MoviePos < PuntiGrafico.length-1) {
      var pos = {};
      pos.pos = MoviePos;
      pos.x = PuntiGrafico[MoviePos][0];
      pos.y = PuntiGrafico[MoviePos][1];
      DrawActivePos(pos, 'a');

      MoviePos = Math.min(MoviePos + Math.round(PuntiGrafico.length/80), PuntiGrafico.length-1);
      if (MoviePos < PuntiGrafico.length-1)
         setTimeout("PlayMovie();",500);
      else {
         PuntiGrafico.length+1;
         document.images['StartStop'].src = '/images/start.png';
      }
   }
   
}

// Da inizio alla simulazione
function StartMovie() {
   if (MoviePos > PuntiGrafico.length) {
      MoviePos=0;
      document.images['StartStop'].src = '/images/stop.png';
      PlayMovie();
   } else {
      MoviePos=PuntiGrafico.length+1;
      document.images['StartStop'].src = '/images/start.png';
   }
}

// Creazione di un waypoint
function CreaWaypoint(ConLimite, Lat, Lon, Descri, Title, Links) {
    // Estrae un punto
     var CodeHTML;
     if (!ConLimite) {
         if (Lat > MaxLat) MaxLat = Lat;
         if (Lat < MinLat) MinLat = Lat;
         if (Lon > MaxLon) MaxLon = Lon;
         if (Lon < MinLon) MinLon = Lon;
     };
     var point = new GPoint(Lon ,Lat);
     var marker = new GMarker(point);
     map.setCenter(new GLatLng(Lat,Lon));
     map.addOverlay(marker);

     if (Links.length > 0) {
        // Descrizione complessa
        CodeHTML = "<B>" +  Title + "</B><BR>";
        CodeHTML += Descri;
        CodeHTML += "<TABLE cellspacing=5 width=300><TR>";
        var Sound = '';
        var Image = '';
        for (var i=0; i < Links.length; i++) { 
          if (Links[i].type == 'image/jpeg')
             Image = Links[i].href
          else if (Links[i].type == 'audio/x-wav')
             Sound = Links[i].href;
        };
        CodeHTML += "<TD><A Href='http://www.duepunti.com/Wisoul-Contest/DettaglioWP.php?image=" + Image + "&sound=" + Sound + "' target='_blank'>Dettaglio</A></TD>";
        CodeHTML += "<TD><A Href='http://www.duepunti.com/Wisoul-Contest/DettaglioWP.php?image=" + Image + "&sound=" + Sound + "'><IMG src='http://www.duepunti.com/Wisoul-Contest/contests/" + Image + "' height=100 border=0></A></TD>";
        CodeHTML += "</TR></TABLE>";
     } else
        CodeHTML =  "<B>" +  Title + "</B><BR>" + Descri;
     
//     if (Link != "")
        //CodeHTML = CodeHTML + "<BR><A HREF='contests/" + Link + "' target='_blank'>Foto associata</A>";
     GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(CodeHTML);
     });
        
};

// Creazione di un percorso
function CreaTraccia(Elementi, ConLimiti) {
   
   TotLun = 0;   
   var DateIni = new Date();   
   var DateAtt = new Date();   
   // Disegna i punti
   TotLun = 0;
   for (var i = 0; i < Elementi.length; i++) {

      // Aggiunge un punto nell'array dei punti mappa
      if (Elementi[i].getElementsByTagName("desc").length != 0)
         Descrizione = Elementi[i].getElementsByTagName("desc")[0].firstChild.nodeValue
      else
         Descrizione = '';
      CreaPuntoMappa(ConLimiti, parseFloat(Elementi[i].getAttribute("lat")), parseFloat(Elementi[i].getAttribute("lon")), Descrizione);
   
      // Calcolo della distanza
      if (i != 0)
         TotLun = TotLun + Distanza(parseFloat(Elementi[i-1].getAttribute("lat")),
                                    parseFloat(Elementi[i].getAttribute("lat")),
                                    parseFloat(Elementi[i-1].getAttribute("lon")),
                                    parseFloat(Elementi[i].getAttribute("lon")) );

      
      // Se presente l'elevazione disegna il punto del grafico
      if (Elementi[i].getElementsByTagName("ele").length != 0) {
         Ele = Elementi[i].getElementsByTagName("ele")[0].firstChild.nodeValue;
         PuntiGrafico.push([TotLun, Ele]);
      };

      // Array dei Tempi e Velocità (se esiste il DIV GraficoVelocita)
      if (Elementi[i].getElementsByTagName("time").length != 0) {
         if (i == 0)
            DateIni.setISO8601(Elementi[0].getElementsByTagName("time")[0].firstChild.nodeValue);
         DateAtt.setISO8601(Elementi[i].getElementsByTagName("time")[0].firstChild.nodeValue);
         TempiGrafico.push(DateAtt-DateIni);
         
         if (document.getElementById('GraficoVelocita') != null && PuntiGrafico.length != 0 && DateAtt-DateIni != 0) 
            VelocitaGrafico.push([TotLun, Velocita(i, 20)]);
      }
   };
};


function CreaMappa() {
   // Creazione della mappa

   var sw = new GLatLng(MinLat, MinLon);
   var ne = new GLatLng(MaxLat, MaxLon);
   var bounds = new GLatLngBounds(sw, ne);
   var zoom = map.getBoundsZoomLevel(bounds);
   var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
   var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
   map.setCenter(new GLatLng(clat,clng), zoom);


   // Polilinea
   polyline = new GPolyline(PuntiMappa, "#0000ff", 4); 
   map.addOverlay(polyline);
};

function Distanza(lat1, lat2, lon1, lon2) {
	// Calcola la distamza fra 2 punti
   
   var R = 6371; // km
   var dLat = (lat2-lat1).toRad();
   var dLon = (lon2-lon1).toRad(); 
   var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
           Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
           Math.sin(dLon/2) * Math.sin(dLon/2); 
           var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
           return (R * c);
};

// Inserisce un punto nella linea
function CreaPuntoMappa(ConLimite, Lat, Lon, Descri) {
	if ((Lat != 0) && (Lon != 0)) {
		 if (!ConLimite) {
			 if (Lat > MaxLat) MaxLat = Lat;
			 if (Lat < MinLat) MinLat = Lat;
			 if (Lon > MaxLon) MaxLon = Lon;
			 if (Lon < MinLon) MinLon = Lon;
		 };
		var point = new GPoint(Lon ,Lat);
		PuntiMappa.push(point);
	};
};
// Aggiunge il metodo toRad (conversione da numero a radiante)
Number.prototype.toRad = function() {  // convert degrees to radians
  return this * Math.PI / 180;
}

// Aggiunge il metodo setISO8601 (conversione della stringa in formato ISO8601 a data)
Date.prototype.setISO8601 = function (string) {
    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
    try {
       var d = string.match(new RegExp(regexp));

       var offset = 0;
       var date = new Date(d[1], 0, 1);

       if (d[3]) { date.setMonth(d[3] - 1); }
       if (d[5]) { date.setDate(d[5]); }
       if (d[7]) { date.setHours(d[7]); }
       if (d[8]) { date.setMinutes(d[8]); }
       if (d[10]) { date.setSeconds(d[10]); }
       if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
       if (d[14]) {
           offset = (Number(d[16]) * 60) + Number(d[17]);
           offset *= ((d[15] == '-') ? 1 : -1);
       }

       offset -= date.getTimezoneOffset();
       time = (Number(date) + (offset * 60 * 1000));
       this.setTime(Number(time));
    } catch(e) {
       this.setTime(0);
    }
}

// Converte i millisecondi in stringa hh:mm;ss
function SecondsToString(milliseconds){
 var  currentDate = new Date(milliseconds);
 var currentHour = currentDate.getHours()-1;
 var currentMinute = FillZeri(currentDate.getMinutes(), 2);
 var currentSecond = FillZeri(currentDate.getSeconds(),2 );
 return currentHour + ':' + currentMinute + ':' + currentSecond;
}  

// Aggiunge Zeri
function FillZeri(value, len, after) {
   value = value + "";
   if (after) {
      var decimal = (value - parseInt(value, 10)) * Math.pow(10, 3);
      value = parseInt(value, 10) + '.' + parseInt(decimal,10);
   }
   else
      while (value.length != len)
         value = "0" + value;
   return value
}

// Calcolo della velocità
function Velocita(position, range) {
   if (position != 0) {
      if (range == null)
         range = 1;
      range = Math.min(position,range);
      var km = (PuntiGrafico[position][0]-PuntiGrafico[position-range][0]);
      var h = (parseInt(TempiGrafico[position])-parseInt(TempiGrafico[position-range])) / 3600000;
//alert(position + ') ' + TempiGrafico[position] + '<->' + TempiGrafico[position-range]);
      return Math.round(km/h*10)/10 
   } else
      return 0; 
}
