<script lang="ts">

  /**
   * Used to quickly calculate a distance by dragging a map (and selecting start- and endpoints)
   */

  import LocationInput from "./LocationInput.svelte"
  import { UIEventSource, Store } from "../../../Logic/UIEventSource"
  import type { MapProperties } from "../../../Models/MapProperties"
  import ThemeViewState from "../../../Models/ThemeViewState"
  import type { Feature } from "geojson"
  import type { RasterLayerPolygon } from "../../../Models/RasterLayers"
  import { RasterLayerUtils } from "../../../Models/RasterLayers"
  import { eliCategory } from "../../../Models/RasterLayerProperties"
  import { GeoOperations } from "../../../Logic/GeoOperations"
  import OpenBackgroundSelectorButton from "../../BigComponents/OpenBackgroundSelectorButton.svelte"
  import { Map as MlMap } from "maplibre-gl"
  import StaticFeatureSource from "../../../Logic/FeatureSource/Sources/StaticFeatureSource"
  import ShowDataLayer from "../../Map/ShowDataLayer"
  import * as conflation from "../../../../assets/layers/conflation/conflation.json"
  import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
  import Translations from "../../i18n/Translations"
  import Tr from "../../Base/Tr.svelte"

  export let value: UIEventSource<number>
  export let feature: Feature
  export let args: { background?: string, zoom?: number }
  export let state: ThemeViewState = undefined
  export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)

  let center = GeoOperations.centerpointCoordinates(feature)
  export let initialCoordinate: { lon: number, lat: number } = { lon: center[0], lat: center[1] }
  let mapLocation: UIEventSource<{ lon: number, lat: number }> = new UIEventSource(initialCoordinate)
  let bg = args?.background
  let rasterLayer = state?.mapProperties.rasterLayer
  if (bg !== undefined) {
    if (eliCategory.indexOf(bg) >= 0) {
      const availableLayers = state.availableLayers.store.data
      const startLayer: RasterLayerPolygon = RasterLayerUtils.SelectBestLayerAccordingTo(availableLayers, bg)
      rasterLayer = new UIEventSource(startLayer)
      state?.mapProperties.rasterLayer.addCallbackD(layer => rasterLayer.set(layer))
    }

  }
  let mapProperties: Partial<MapProperties> = {
    rasterLayer: rasterLayer,
    location: mapLocation,
    zoom: new UIEventSource(args?.zoom ?? 18)
  }

  let start: UIEventSource<{ lon: number, lat: number }> = new UIEventSource(undefined)

  function selectStart() {
    start.set(mapLocation.data)
  }

  let lengthFeature: Store<Feature[]> = start.map(start => {
    if (!start) {
      return []
    }
    // A bit of a double task: calculate the actual value _and_ the map rendering
    const end = mapLocation.data
    const distance = GeoOperations.distanceBetween([start.lon, start.lat], [end.lon, end.lat])
    value.set(distance.toFixed(2))


    return <Feature[]>[

      {
        type: "Feature",
        properties: {
          id: "distance_line_" + distance,
          distance: "" + distance
        },
        geometry: {
          type: "LineString",
          coordinates: [[start.lon, start.lat], [end.lon, end.lat]]
        }
      }
    ]

  }, [mapLocation])

  new ShowDataLayer(map, {
    layer: new LayerConfig(conflation),
    features: new StaticFeatureSource(lengthFeature)
  })

</script>

<div class="relative w-full h-64">
  <LocationInput value={mapLocation} {mapProperties} {map} />
  <div class="absolute bottom-0 left-0 p-4">
    <OpenBackgroundSelectorButton {state} {map} />
  </div>
</div>

<button class="primary" on:click={() => selectStart()}>
  <Tr t={Translations.t.input_helpers.distance.setFirst} />
</button>
