<script lang="ts">
  import { UIEventSource } from "../../../Logic/UIEventSource"
  import type { MapProperties } from "../../../Models/MapProperties"
  import { Map as MlMap } from "maplibre-gl"
  import { MapLibreAdaptor } from "../../Map/MapLibreAdaptor"
  import MaplibreMap from "../../Map/MaplibreMap.svelte"
  import Direction_stroke from "../../../assets/svg/Direction_stroke.svelte"
  import type { SpecialVisualizationState } from "../../SpecialVisualization"
  import type Feature from "geojson"
  import { GeoOperations } from "../../../Logic/GeoOperations"
  /**
   * A visualisation to pick a direction on a map background.
   */
  export let value: UIEventSource<undefined | string>
  export let state: SpecialVisualizationState = undefined
  export let args: any[] = []
  export let feature: Feature
  let [lon, lat] = GeoOperations.centerpointCoordinates(feature)
  let mapProperties: MapProperties = {
    location: new UIEventSource({ lon, lat }),
    zoom: new UIEventSource(args[0] !== undefined ? Number(args[0]) : 17),
    rasterLayer: state.mapProperties.rasterLayer,
    rotation: state.mapProperties.rotation,
  }
  let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)
  let mla = new MapLibreAdaptor(map, mapProperties)
  mla.allowMoving.setData(false)
  mla.allowZooming.setData(false)
  let rotation = new UIEventSource(value.data)
  rotation.addCallbackD(rotation => {
    const r = (rotation + mapProperties.rotation.data + 360) % 360
    console.log("Setting value to", r)
    value.setData(""+Math.floor(r))
  }, [mapProperties.rotation])
  let directionElem: HTMLElement | undefined
  $: rotation.addCallbackAndRunD((degrees) => {
    if (!directionElem?.style) {
      return
    }
    directionElem.style.rotate = degrees + "deg"
  })

  let mainElem: HTMLElement


  function onPosChange(x: number, y: number) {
    const rect = mainElem.getBoundingClientRect()
    const dx = -(rect.left + rect.right) / 2 + x
    const dy = (rect.top + rect.bottom) / 2 - y
    const angle = (180 * Math.atan2(dy, dx)) / Math.PI
    const angleGeo = Math.floor((450 - angle) % 360)
    rotation.setData(angleGeo)
  }

  let isDown = false
</script>

<div
  bind:this={mainElem}
  class="relative h-48 min-w-48 w-full cursor-pointer overflow-hidden rounded-xl"
  on:click={(e) => onPosChange(e.x, e.y)}
  on:mousedown={(e) => {
    isDown = true
    onPosChange(e.clientX, e.clientY)
  }}
  on:mousemove={(e) => {
    if (isDown) {
      onPosChange(e.clientX, e.clientY)
      e.preventDefault()
    }
  }}
  on:mouseup={() => {
    isDown = false
  }}
  on:touchmove={(e) => {
    onPosChange(e.touches[0].clientX, e.touches[0].clientY)
    e.preventDefault()
  }}
  on:touchstart={(e) => onPosChange(e.touches[0].clientX, e.touches[0].clientY)}
>
  <div class="absolute left-0 top-0 h-full w-full cursor-pointer">
    <MaplibreMap mapProperties={mla} {map} />
  </div>

  <div bind:this={directionElem} class="absolute left-0 top-0 h-full w-full p-1">
    <Direction_stroke />
  </div>
</div>
