<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8">
    <title>OwnTracks @@@LABEL@@@</title>
    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1.0">

    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <link rel="icon" sizes="192x192" href="../static/recorder.png">
    <link rel="apple-touch-icon" href="../static/recorder.png">

    <link rel="stylesheet" href="../utils/map.css">

    <link rel="stylesheet" href="../static/leaflet/leaflet.css">
    <script src="../static/leaflet/leaflet.js"></script>

    <script type="module">
      import { fetchApiData } from "../utils/network.js";
      import { generatePopupHTML } from "../utils/map.js";
      import { markerStyle, strokeStyle } from "../utils/map_leaflet.js";

      const map = L.map('map-canvas').setView([0.0, 0.0], 1);
      let lastLatLng = L.latLng(0.0, 0.0);

      const osm_layer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
      }).addTo(map);

      const hikebike_layer = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
        attribution: 'Map Data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Hillshading: SRTM3 v2 (<a href="https://www2.jpl.nasa.gov/srtm/">NASA</a>)',
      });

      const baseMaps = { "OpenStreetMap": osm_layer, "HikeBikeMap": hikebike_layer};

      L.control.layers(baseMaps).addTo(map);

      const empty_geojson = {
        type: "FeatureCollection",
        features: [],
      };

      const trackLayer = new L.GeoJSON( empty_geojson, {
        style: function(feature) {
          return strokeStyle;
        },
        coordsToLatLng: function(coords) {
          return coordsToLatLng(coords);
        },
      });

      // this defines how the data obtained from @@@LASTPOS@@@ will be rendered
      const lastposLayer = new L.GeoJSON( empty_geojson , {
        pointToLayer: function (feature, latlng) {
          return L.circleMarker(latlng, markerStyle);
        },
        onEachFeature: function(feature, layer) {
          if (feature.geometry.type === "Point") { 
            const description = generatePopupHTML({
              ...feature.properties,
              lat: feature.geometry.coordinates[1].toFixed(4),
              lon: feature.geometry.coordinates[0].toFixed(4),
            });

            layer.bindPopup(description);
          }
        },
        style: function(feature) {
          if (feature.geometry.type === "Point") {
            return {};
          } else {
            return strokeStyle;
          }
        },
        coordsToLatLng: function(coords) {
          return coordsToLatLng(coords);
        },
      });
      
      map.addLayer(trackLayer);
      map.addLayer(lastposLayer);
      lastposLayer.bringToFront();

      update_lastpos(true);

      // define the "Load track" button in the bottom left corner, design copied from vmap.html
      const LoadTrackControl = L.Control.extend({
        options: {
          position: 'bottomleft',
        },

        onAdd: function (map) {
          const controlDiv = L.DomUtil.create('div', 'leaflet-control-button');

          const controlUI = document.createElement('div');
          controlUI.style.backgroundColor = '#fff';
          controlUI.style.border = '2px solid #fff';
          controlUI.style.borderRadius = '3px';
          controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
          controlUI.style.cursor = 'pointer';
          controlUI.style.marginBottom = '22px';
          controlUI.style.textAlign = 'center';
          controlUI.title = 'Click to load the track onto the map';
          controlDiv.appendChild(controlUI);

          // Set CSS for the control interior
          const controlText = document.createElement('div');
          controlText.style.color = 'rgb(25,25,25)';
          controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
          controlText.style.fontSize = '16px';
          controlText.style.lineHeight = '38px';
          controlText.style.paddingLeft = '5px';
          controlText.style.paddingRight = '5px';
          controlText.innerHTML = 'Load track';
          controlUI.appendChild(controlText);

          // when the button is clicked load the @@@GEO@@@ data and display it on the trackLayer passed as an option to the LoadTrackControl
          controlDiv.onclick = (async function() {

            const trackLayer = this.options.trackLayer;
            lastLatLng = L.latLng(0.0, 0.0);

            const data = await fetchApiData({ url: "@@@GEO@@@" });
            
            trackLayer.clearLayers();
            trackLayer.addData(data);
            update_lastpos(false);
            map.fitBounds(trackLayer.getBounds());

          }).bind(this);
          
          return controlDiv;
        },
      });

      map.addControl(new LoadTrackControl({ trackLayer: trackLayer }));

      // this will update the lastposLayer to fetch and show updated latest positions
      async function update_lastpos(fitBounds) {

        const data = await fetchApiData({ url: "@@@LASTPOS@@@" });

        data.data.forEach(function(latest) {
          const latLng = coordsToLatLng([latest.lon, latest.lat]);
          const latest_geojson = {
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [ latLng.lng, latLng.lat ],
            },
            "properties": latest,
          };

          lastposLayer.clearLayers();
          lastposLayer.addData(latest_geojson);
          if(fitBounds) {
            map.fitBounds(lastposLayer.getBounds());
          }
        });
      }

      function coordsToLatLng([ lon, lat ]) {
        const dist0 = Math.abs(lon - lastLatLng.lng);
        const dist1 = Math.abs(lon + 360.0 - lastLatLng.lng);
        const dist2 = Math.abs(lon - 360.0 - lastLatLng.lng);
        if (dist0 > dist1 || dist0 > dist2) {
          if (dist0 > dist1) {
            lon += 360.0;
          } else {
            lon -= 360.0;
          }
        }
        const latLng = L.GeoJSON.coordsToLatLng([lon, lat]);
        lastLatLng = latLng;
        return latLng;
      }

    </script>
    
  </head>
  <body>
    <div id="map-canvas"></div>
  </body>
</html>
