<template>
  <div
    class="home"
  >
    <div id="map" />

    <div class="panel">
      <el-select
        v-model="timeInDay"
        placeholder="Select"
        size="large"
      >
        <el-option
          v-for="item in timeOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-checkbox
        v-model="isShowLabels"
        label="show labels"
        size="large"
      />
      <el-checkbox
        v-model="isShowTerrain"
        label="show terrain"
        size="large"
      />
      <el-checkbox
        v-model="isShowFog"
        label="show fog"
        size="large"
      />
      <el-checkbox
        v-model="isAutoRotate"
        label="auto rotate"
        size="large"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from "vue"
import { useRoute, useRouter } from "vue-router"
import { useStore } from "vuex"
import mapboxgl from 'mapbox-gl'

const route = useRoute()
const router = useRouter()
const store = useStore()

mapboxgl.accessToken = 'pk.eyJ1IjoiamlidmFnIiwiYSI6ImNsdDVibmxvZDAwbjcyanAzNmpzOHpoeHUifQ.KKYv3iK0IiL37rNDYkb-dQ'

let map = null

onMounted(() => {
  map = new mapboxgl.Map({
    container: 'map', // container ID
    center: [2.294444, 48.858056], // starting position [lng, lat]
    zoom: 15.6, // starting zoom
    pitch: 72,
  })
  map.on('style.load', () => {
    // 隐藏标签。
    map.setConfigProperty('basemap', 'showPlaceLabels', false)
    map.setConfigProperty('basemap', 'showRoadLabels', false)
    map.setConfigProperty('basemap', 'showPointOfInterestLabels', false)
    map.setConfigProperty('basemap', 'showTransitLabels', false)

    // 准备 3D terrain source
    map.addSource('mapbox-dem', {
      'type': 'raster-dem',
      'url': 'mapbox://mapbox.terrain-rgb',
      'tileSize': 512,
      'maxzoom': 14
    })
  })

  map.on('click', (e) => {
    console.log(e.lngLat.wrap())
  })

  map.on('load', () => {
    // todo: 操控
    // 桥梁高亮
    map.addSource('bridge-demo-1', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'properties': {},
        'geometry': {
          'type': 'LineString',
          'coordinates': [
            [
              2.291370903863708,
              48.860291730262816
            ],
            [
              2.2926683589130334,
              48.85941742662925
            ],
          ]
        }
      }
    })
    map.addSource('bridge-demo-2', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'properties': {},
        'geometry': {
          'type': 'LineString',
          'coordinates': [
            [
              2.2867527694825185,
              48.85655006915218
            ],
            [
              2.28846012300869,
              48.85483140541177
            ],
          ]
        }
      }
    })
    map.addSource('bridge-demo-3', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'properties': {},
        'geometry': {
          'type': 'LineString',
          'coordinates': [
            [
              2.3016957824563633,
              48.86404969411541
            ],
            [
              2.3018487764027213,
              48.862882778017564
            ],
          ]
        }
      }
    })
    map.addLayer({
      'id': 'bridge-demo-1',
      'type': 'line',
      'source': 'bridge-demo-1',
      'layout': {
        'line-join': 'round',
        'line-cap': 'round'
      },
      'paint': {
        'line-color': 'rgba(244, 208, 133, 0.8)',
        'line-width': 40,
      }
    })
    map.addLayer({
      'id': 'bridge-demo-2',
      'type': 'line',
      'source': 'bridge-demo-2',
      'layout': {
        'line-join': 'round',
        'line-cap': 'round'
      },
      'paint': {
        'line-color': 'rgba(244, 208, 133, 0.8)',
        'line-width': 40,
      }
    })
    map.addLayer({
      'id': 'bridge-demo-3',
      'type': 'line',
      'source': 'bridge-demo-3',
      'layout': {
        'line-join': 'round',
        'line-cap': 'round'
      },
      'paint': {
        'line-color': 'rgba(244, 208, 133, 0.8)',
        'line-width': 40,
      }
    })

    // todo：操控
    // 操场高亮
    // Add a data source containing GeoJSON data.
    map.addSource('playground', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'geometry': {
          'type': 'Polygon',
          // These coordinates outline playground.
          'coordinates': [
            [
              [2.290685454637469, 48.85648212786501],
              [2.290678167471242, 48.85674317251818],
              [2.2909987705963886, 48.856988869994325],
              [2.2913584104396705, 48.85706691648497],
              [2.2926340590652217, 48.856240774123734],
              [2.2926899302722177, 48.85607261804398],
              [2.291903329216666, 48.85567435087097],
              [2.2916458346767286, 48.855731990701315],
            ]
          ]
        }
      }
    })
    map.addLayer({
      'id': 'playground',
      'type': 'fill',
      'source': 'playground', // reference the data source
      'layout': {},
      'paint': {
        'fill-color': '#0080ff', // blue color fill
        'fill-opacity': 0.5
      }
    })
  })
})

// 时间选择
const timeOptions = [
  {
    label: 'dusk',
    value: 'dusk',
  },
  {
    label: 'day',
    value: 'day',
  },
  {
    label: 'dawn',
    value: 'dawn',
  },
  {
    label: 'night',
    value: 'night',
  },
]
const timeInDay = ref(timeOptions[1].value)
watch(timeInDay, (v) => {
  map.setConfigProperty('basemap', 'lightPreset', v) // dusk, dawn, day, and night
  if (isShowFog.value) {
    if (timeInDay.value === 'day') {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': 'white',
        'high-color': '#add8e6',
        'space-color': '#d8f2ff',
        'star-intensity': 0.0
      })
    } else if (timeInDay.value === 'dusk' || timeInDay.value === 'dawn') {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': '#999',
        'high-color': '#add8e6',
        'space-color': '#d8f2ff',
        'star-intensity': 0.4
      })
    } else {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': '#242B4B',
        'high-color': '#161B36',
        'space-color': '#0B1026',
        'star-intensity': 0.8
      })
    }
  }
})


// 标签开关
const isShowLabels = ref(false)
watch(isShowLabels, (v) => {
  map.setConfigProperty('basemap', 'showPlaceLabels', v)
  map.setConfigProperty('basemap', 'showRoadLabels', v)
  map.setConfigProperty('basemap', 'showPointOfInterestLabels', v)
  map.setConfigProperty('basemap', 'showTransitLabels', v)
})

// 地形开关
const isShowTerrain = ref(false)
watch(isShowTerrain, (v) => {
  if (v) {
    map.setTerrain({
      'source': 'mapbox-dem',
      'exaggeration': 1
    })
  } else {
    map.setTerrain(null)
  }
})

// 雾开关
const isShowFog = ref(false)
watch(isShowFog, (v) => {
  if (v) {
    if (timeInDay.value === 'day') {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': 'white',
        'high-color': '#add8e6',
        'space-color': '#d8f2ff',
        'star-intensity': 0.0
      })
    } else if (timeInDay.value === 'dusk' || timeInDay.value === 'dawn') {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': '#999',
        'high-color': '#add8e6',
        'space-color': '#d8f2ff',
        'star-intensity': 0.4
      })
    } else {
      map.setFog({
        'range': [-1, 2],
        'horizon-blend': 0.3,
        'color': '#242B4B',
        'high-color': '#161B36',
        'space-color': '#0B1026',
        'star-intensity': 0.8
      })
    }
  } else {
    map.setFog(null)
  }
})

// 自动旋转开关
const isAutoRotate = ref(false)
let lastFrameTime = 0.0
let animationTotalTime = 0.0
let initialBearing = null

function frameTask(timeStamp) {
  if (isAutoRotate.value) {
    animationTotalTime += ((timeStamp - lastFrameTime) / 1000.0)
    const rotation = initialBearing + animationTotalTime * 2.0
    map.setBearing(rotation % 360)
    lastFrameTime = timeStamp
    window.requestAnimationFrame(frameTask)
  }
}

watch(isAutoRotate, (v) => {
  if (v) {
    lastFrameTime = 0.0
    animationTotalTime = 0.0
    initialBearing = map.getBearing()
    window.requestAnimationFrame(frameTask)
  }
})






// 一种style可有多个layer，每个layer有对应的source。

// todo: 日照控件

// todo: 道路显隐控件
// map.setPaintProperty('route', 'line-opacity', 0.9);

// 添加自定义图层。同一个slot内的各个图层用beforeId参数指定顺序。
// map.addLayer({ type: 'line', slot: 'middle' /* ... */ });



// 移除图层
//
</script>

<style lang="less" scoped>
.home {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  #map{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
  .panel{
    position: absolute;
    top: 0;
    left: 0;
    padding: 10px;
    display: flex;
    flex-direction: column;
    background-color: rgba(255, 255, 255, 0.5);
  }
}
</style>