<!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 baseMaps = { "OpenStreetMap": osm_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();

      load_track();

      async function load_track() {

            lastLatLng = L.latLng(0.0, 0.0);

            const data = await fetchApiData({ url: "@@@GEO@@@" });
            
            trackLayer.clearLayers();
            trackLayer.addData(data);
            update_lastpos(false);
            if (trackLayer.getBounds().isValid()) map.fitBounds(trackLayer.getBounds());
            else map.openTooltip('No Data!',L.latLng(0.0,0.0));
      }

      // 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) {
            if (lastposLayer.getBounds().isValid()) map.fitBounds(lastposLayer.getBounds());
            else map.openTooltip('No Data!',L.latLng(0.0,0.0));
          }
        });
      }

      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>
