<template>
  <div>
    <div :id="'map-element' + elementId" class="map-element" style="width: 100%; height: 100%;"></div>
    <div :id="'draw-toolbar' + elementId" class='draw-toolbar' v-show="allowDraw">
      <el-row>
        <input :id="'drawPolygon' + elementId" class="ant-btn ant-btn-red" type="button" value="画图"/>&nbsp;&nbsp;
        <input :id="'drawRemove' + elementId" type="button" class="ant-btn ant-btn-red" value="取消画图"/>&nbsp;&nbsp;
        <input :id="'drawReset' + elementId" type="button" class="ant-btn ant-btn-red" value="重置画图"/>
      </el-row>
    </div>
    <div :id="'mark-toolbar' + elementId" class='draw-toolbar' v-show="allowMark">
      <el-row>
        <input :id="'markPoint' + elementId" class="ant-btn ant-btn-red" type="button" value="标记"/>&nbsp;&nbsp;
        <input :id="'markReset' + elementId" type="button" class="ant-btn ant-btn-red" value="重置标记"/>
      </el-row>
    </div>
  </div>
</template>

<script>
  import $ from "jquery";
  import {olMap} from "@/utils/ol_map";

  const TYPE_NONE = 0; // 无交互 默认
  const TYPE_DRAW = 1; // 绘制多边形 v-model为MultiPolygon的JSON
  const TYPE_SELECT = 2; // 选择, 必须指定list属性 v-model为list索引, 未选中为-1
  const TYPE_MARK = 3; // 标记点 v-model为[经度, 维度]数组

  export default {
    name: "MapField",
    props: {
      minMapZoom: {
        type: Number,
        default: 16,
      },
      maxMapZoom: {
        type: Number,
        default: 18.9,
      },
      allowDraw: {
        type: Boolean,
        default: false,
      },
      type: {
        type: [Number, String], // 0 原始 1 绘制 2 选择
        default: 0,
      },
      coord: {
        type: Array,
        default: function() {
          return [115.452752, 31.789033];
        },
      },
      value: {
        type: [String, Array, Number],
      },
      list: {
        type: Array,
        default: function() {
          return [];
        },
      },
      allowSelect: {
        type: Boolean,
        default: false,
      },
      allowMark: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        isInited: false,
        mapObject: null,
        mapResult: null,
        elementId: ('_' + Math.random()).replaceAll('.', ''),
        internalValue: null, // string only
      };
    },
    created() {
    },
    mounted() {
      this.Init();
      this.SetupCoord();
      if(this.list)
        this.mapObject.SetLayers(this.list);
      if(this.value)
        this.SetValue(this.value);
    },
    watch: {
      value: function(newVal, oldVal) {
        this.SetValue(newVal);
      },
      coord: {
        handler: function(newVal, oldVal) {
          this.SetupCoord();
        },
        deep: true,
      },
      list: {
        handler: function(newVal, oldVal) {
          if(this.type == TYPE_SELECT)
          {
            this.mapObject.ClearSelection();
            this.mapObject.SetLayers(newVal);
            if(this.internalValue >= 0 && this.internalValue < this.list.length)
              this.mapObject.SetSelection(this.list[this.internalValue].name);
          }
        },
        deep: true,
      },
    },
    methods: {
      SetValue(val) {
        if(this.internalValue === val)
          return;
        this.internalValue = val;
        this.UpdateValueToMap();
      },
      UpdateValueToMap() {
        this.SetupCoord();
        if(this.type == TYPE_SELECT)
        {
          this.mapObject.ClearSelection();
          if(this.internalValue >= 0 && this.internalValue < this.list.length)
            this.mapObject.SetSelection(this.list[this.internalValue].name);
        }
        else if(this.type == TYPE_MARK)
        {
          this.mapObject.RemoveDrawLayer();
          if(this.internalValue && this.internalValue.length > 0)
          {
            let json = olMap.gen_polygon([this.internalValue]);
            this.mapObject.SetLayer(olMap.MAP_FIELD_INIT_LAYER_NAME, json, null, null, {
              'style.stroke.width': 10,
              'style.stroke.color': '#FF0000',
            });
          }
          else
            this.mapObject.PopLayer(olMap.MAP_FIELD_INIT_LAYER_NAME);
        }
        else
        {
          this.mapObject.RemoveDrawLayer();
          this.mapObject.SetLayer(olMap.MAP_FIELD_INIT_LAYER_NAME, this.internalValue);
        }
      },
      Init() {
        if(this.isInited)
          return;
        this.mapObject = new olMap('map-element' + this.elementId);
        if(this.type == TYPE_DRAW)
        {
          this.mapObject.SetAllowDraw(this.allowDraw);
          let self = this;
          $("#drawPolygon" + this.elementId).click(function () {
            self.mapObject.StartDraw();
          });
          //清除画图鼠标点击事件
          $("#drawRemove" + this.elementId).click(function () {
            self.mapObject.ClearDraw();
          });
          //还原之前图层
          $("#drawReset" + this.elementId).click(function () {
            self.mapObject.ResetDraw();
          });
          this.mapObject.SetCallback("draw::start", () => {
            this.mapResult = null;
          });
          this.mapObject.SetCallback("draw::remove", () => {
          });
          this.mapObject.SetCallback("draw::end", (res) => {
            this.mapResult = res;
            this.SetInternalValue();
          });
          this.mapObject.SetCallback("draw::reset", () => {
            this.mapResult = null;
          });
        }
        else if(this.type == TYPE_SELECT)
        {
          this.mapObject.SetAllowSelect(this.allowSelect);
          this.mapObject.SetCallback("interactive::select", (name) => {
            console.log('select -> ' + name);
            this.mapResult = name;
            this.SetInternalValue();
            this.$emit('select', name);
          });
        }
        else if(this.type == TYPE_MARK)
        {
          this.mapObject.SetAllowMark(this.allowMark);
          let self = this;
          $("#markPoint" + this.elementId).click(function () {
            self.mapObject.StartMark();
          });
          //还原之前图层
          $("#markReset" + this.elementId).click(function () {
            self.mapObject.ResetMark();
          });
          this.mapObject.SetCallback("mark::start", () => {
            this.mapResult = null;
          });
          this.mapObject.SetCallback("mark::end", (res) => {
            this.mapResult = res;
            this.SetInternalValue();
          });
          this.mapObject.SetCallback("mark::reset", () => {
            this.mapResult = null;
          });
        }
        this.isInited = true;
        if(this.internalValue)
          this.UpdateValueToMap();
      },
      DestroyMap() {
        if(!this.mapObject)
          return;
        //delete this.mapObject;
        this.mapObject.DestroyMap();
        this.mapObject = null;
      },
      SetInternalValue() {
        if(this.type == TYPE_SELECT)
        {
          this.internalValue = this.mapResult;
          if(this.mapResult)
            this.internalValue = this.list.findIndex((x) => x.name == this.mapResult);
          else
            this.internalValue = -1;
          this.$emit('input', this.internalValue);
        }
        else if(this.type == TYPE_MARK)
        {
          this.internalValue = this.mapResult ? this.mapResult : [null, null];
          this.$emit('input', this.internalValue);
        }
        else
        {
          this.internalValue = JSON.stringify(this.mapResult);
          this.$emit('input', this.internalValue);
        }
        //console.log(this.type, this.mapResult, this.internalValue);
      },
      Update() {
        if(this.mapObject)
          this.mapObject.Update();
      },
      SetupCoord() {
        if(this.mapObject && this.coord && this.coord.length >= 2 && this.coord[0] && this.coord[1])
          this.mapObject.SetCoord(this.coord[0], this.coord[1]);
      }
    },
  }
</script>

<style scoped>

  .map-element {
    width: 100%;
    height: 100%;
  }

  .draw-toolbar {
    position: relative;
    width: 40%;
    left: 60%;
    bottom: 95%;
    z-index: 2000;
  }

  .ant-btn-red {
    position: relative;
    display: inline-block;
    background: #D0EEFF;
    border: 1px solid #99D3F5;
    border-radius: 4px;
    padding: 4px 12px;
    overflow: hidden;
    color: #1E88C7;
    text-decoration: none;
    text-indent: 0;
    line-height: 20px;
  }
</style>
