<script>
  import * as L from 'leaflet';
  import 'leaflet-minimap';
  import 'leaflet/dist/leaflet.css';
  import 'leaflet-minimap/dist/Control.MiniMap.min.css';

  import { get } from 'svelte/store';
  import { map_store } from '../lib/stores.js';
  import MapPosition from '../components/MapPosition.svelte';

  export let display_minimap = false;
  export let current_result = null;
  export let position_marker = null;

  let dataLayers = [];

  function createMap(container) {
    const attribution = Nominatim_Config.Map_Tile_Attribution;
    let map = new L.map(container, {
      attributionControl: (attribution && attribution.length),
      scrollWheelZoom: true, // !L.Browser.touch,
      touchZoom: false,
      center: [
        Nominatim_Config.Map_Default_Lat,
        Nominatim_Config.Map_Default_Lon
      ],
      zoom: Nominatim_Config.Map_Default_Zoom
    });

    L.tileLayer(Nominatim_Config.Map_Tile_URL, {
      attribution: attribution
    }).addTo(map);

    if (display_minimap) {
      let osm2 = new L.TileLayer(Nominatim_Config.Map_Tile_URL, {
        minZoom: 0,
        maxZoom: 13,
        attribution: attribution
      });
      new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
    }

    const MapPositionControl = L.Control.extend({
      options: { position: 'topright' },
      onAdd: () => { return document.getElementById('show-map-position'); }
    });
    map.addControl(new MapPositionControl());

    return map;
  }

  function mapAction(container) {
    let map = createMap(container);
    map_store.set(map);
    setMapData(current_result);

    return {
      destroy: () => {
        map_store.set(null);
        map.remove();
      }
    };
  }

  function parse_and_normalize_geojson_string(part) {
    // normalize places the geometry into a featurecollection, similar to
    // https://github.com/mapbox/geojson-normalize
    var parsed_geojson = {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: part,
          properties: {}
        }
      ]
    };
    return parsed_geojson;
  }

  function resetMapData() {
    let map = get(map_store);
    if (!map) { return; }

    dataLayers.forEach(function (layer) {
      map.removeLayer(layer);
    });
  }

  function setMapData(aFeature) {
    let map = get(map_store);
    if (!map) { return; }

    resetMapData();

    if (position_marker) {
      // We don't need a marker, but L.circle would change radius when you zoom in/out
      let cm = L.circleMarker(
        position_marker,
        {
          radius: 5,
          weight: 2,
          fillColor: '#ff7800',
          color: 'red',
          opacity: 0.75,
          zIndexOffset: 100,
          clickable: false
        }
      );
      cm.addTo(map);
      dataLayers.push(cm);
    }

    var search_params = new URLSearchParams(window.location.search);
    var viewbox = search_params.get('viewbox');
    if (viewbox) {
      let coords = viewbox.split(','); // <x1>,<y1>,<x2>,<y2>
      let bounds = L.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]);
      L.rectangle(bounds, {
        color: '#69d53e',
        weight: 3,
        dashArray: '5 5',
        opacity: 0.8,
        fill: false
      }).addTo(map);
    }

    if (!aFeature) return;

    let lat = aFeature.centroid ? aFeature.centroid.coordinates[1] : aFeature.lat;
    let lon = aFeature.centroid ? aFeature.centroid.coordinates[0] : aFeature.lon;
    let geojson = aFeature.geometry || aFeature.geojson;

    if (lat && lon) {
      let circle = L.circleMarker([lat, lon], {
        radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75
      });
      map.addLayer(circle);
      dataLayers.push(circle);
    }


    if (geojson) {
      var geojson_layer = L.geoJson(
        // https://leafletjs.com/reference-1.7.1.html#path-option
        parse_and_normalize_geojson_string(geojson),
        {
          style: function () {
            return { interactive: false, color: 'blue' };
          }
        }
      );
      map.addLayer(geojson_layer);
      dataLayers.push(geojson_layer);
      map.fitBounds(geojson_layer.getBounds());
    } else if (lat && lon && position_marker) {
      map.fitBounds([[lat, lon], position_marker], { padding: [50, 50] });
    } else if (lat && lon) {
      map.setView([lat, lon], 10);
    }
  }

  $: setMapData(current_result);

  function show_map_position_click(e) {
    e.target.style.display = 'none';
    document.getElementById('map-position').style.display = 'block';
  }
</script>

<MapPosition />
<div id="map" use:mapAction />
<div id="show-map-position" class="leaflet-bar btn btn-sm btn-outline-secondary"
      on:click|stopPropagation={show_map_position_click}
>show map bounds</div>

<style>
  #map {
    height: 100%;
    background:#eee;
  }

  .btn-outline-secondary {
    background-color: white;
  }

  .btn-outline-secondary:hover {
    color: #111;
  }

  @media (max-width: 768px) {
    #map {
      height: 300px;
    }
  }

</style>