<template>
  <div class="mark">
    <div class="style_container markContent" v-if="isShow">
      <div class="container">
        <ul>
          <li v-for="(item, index) in markList" :key="index" :class="item.class" @click="markEvent(item)">
            <p class="bg" :title="item.name" :class="{ active: item.active }"></p>
          </li>
        </ul>
      </div>
    </div>

    <div class="style_container markSettingContent" v-if="markSettingContentIsShow">
      <div class="container">
        <div class="title">
          标注设置
          <p class="close" @click="closeMarkSetting">×</p>
        </div>

        <div class="content">
          <el-row>
            <el-col :span="5" class="label">名称</el-col>
            <el-col :span="17">
              <el-input v-model="nowFeatureInfo.name" placeholder="请输入名称" :disabled="!nowFeatureInfo.editing">
              </el-input>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="5" class="label">描述</el-col>
            <el-col :span="17">
              <el-input v-model="nowFeatureInfo.describe" type="textarea" :rows="2" placeholder="请输入描述"
                :disabled="!nowFeatureInfo.editing"></el-input>
            </el-col>
          </el-row>
          <el-row v-if="nowFeatureInfo.editing">
            <el-row v-if="nowFeatureInfo.geometryType == 'Point'">
              <el-row>
                <el-col :span="5" class="label">图标</el-col>
                <el-col :span="17">
                  <div class="picture_store">
                    <ul>
                      <li v-for="(item, index) in renderSvgObj" :key="index" @click="resetPicture(item)" :style="{
                        backgroundImage:
                          'url(' + svgRootPath + item.value + ')',
                      }" :title="item.key">
                        <div>
                          {{ item.key }}
                        </div>

                      </li>
                    </ul>
                  </div>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="5" class="label">颜色</el-col>
                <el-col :span="18">
                  <el-color-picker v-model="nowFeatureInfo.styleConfig.color" color-format="rgb"
                    @active-change="resetColor($event, 'color')"></el-color-picker>
                </el-col>
              </el-row>
            </el-row>
            <el-row v-else-if="nowFeatureInfo.geometryType == 'LineString'">
              <!-- 颜色 -->
              <el-row>
                <el-col :span="5" class="label">颜色</el-col>
                <el-col :span="18">
                  <el-color-picker v-model="nowFeatureInfo.styleConfig.color" show-alpha color-format="rgb"
                    @active-change="resetColor($event, 'color')"></el-color-picker>
                </el-col>
              </el-row>
              <!-- 宽度 -->
              <el-row>
                <el-col :span="5" class="label">线宽</el-col>
                <el-col :span="18">
                  <el-slider v-model="nowFeatureInfo.styleConfig.width" :min="1" :max="20" show-input
                    @input="resetStyle"></el-slider>
                </el-col>
              </el-row>
            </el-row>
            <el-row v-else-if="nowFeatureInfo.geometryType == 'Polygon'">
              <!-- 线 颜色 -->
              <el-row>
                <el-col :span="5" class="label">边框颜色</el-col>
                <el-col :span="18">
                  <el-color-picker v-model="nowFeatureInfo.styleConfig.color" show-alpha color-format="rgb"
                    @active-change="resetColor($event, 'color')"></el-color-picker>
                </el-col>
              </el-row>
              <!-- 线 宽度 -->
              <el-row>
                <el-col :span="5" class="label">边框宽度</el-col>
                <el-col :span="18">
                  <el-slider v-model="nowFeatureInfo.styleConfig.width" :min="1" :max="20" show-input
                    @input="resetStyle"></el-slider>
                </el-col>
              </el-row>
              <!-- 面 颜色 -->
              <el-row>
                <el-col :span="5" class="label">填充颜色</el-col>
                <el-col :span="18">
                  <el-color-picker v-model="nowFeatureInfo.styleConfig.fill" color-format="rgb" show-alpha
                    @active-change="resetColor($event, 'fill')"></el-color-picker>
                </el-col>
              </el-row>
            </el-row>
          </el-row>
        </div>

        <div class="footer" v-show="nowFeatureInfo.editing">
          <el-button @click="sure">确认</el-button>
          <el-button @click="delMark">删除</el-button>
        </div>

        <div class="footer" v-show="!nowFeatureInfo.editing">
          <el-button @click="edit">编辑</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import api from "@/api/mark";

import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Feature from "ol/Feature";
import { Fill, Stroke, Icon, Style } from "ol/style";
import GeoJSON from "ol/format/GeoJSON";

import DrawTool from "@/utils/openlayer_plugins/draw";

export default {
  props: {
    isShow: {
      type: Boolean,
      default: false,
    },
    closeCallback: {
      type: Function,
      default: null,
    },
    closeMeasure: {
      type: Function,
      default: null,
    },
  },
  data() {
    return {
      svgRootPath: systemConfig.markImageUrl,
      markList: [
        { name: "我的标注", class: "OwnMark", active: false },
        { name: "点", class: "Point", active: false },
        { name: "线", class: "LineString", active: false },
        { name: "面", class: "Polygon", active: false },
      ],
      renderSvgObj: [],

      markSettingContentIsShow: false,
      draw: null,

      drawing_source: null,
      drawing_layer: null,
      saved_source: null,
      saved_layer: null,

      nowFeature: null,

      defaultStyle: {
        image: "",
        width: 2,
        color: "rgb(255, 69, 0)",
        fill: "rgb(255, 69, 0)",
      },
      nowFeatureInfo: {
        name: "",
        describe: "",
        editing: true,
        geometryType: "Point",
        style: {
          image: "",
          width: 2,
          color: "rgb(255, 69, 0)",
          fill: "rgb(255, 69, 0)",
        },
      },
      geometryType: {
        Point: 0,
        LineString: 1,
        Polygon: 2,
      },
    };
  },
  mounted() {
  },
  methods: {
    markEvent(obj) {
      obj.active = !obj.active;
      this.markList = this.markList.map(function (item) {
        if (item.class == "OwnMark" || obj.class == "OwnMark") return item;
        if (obj.class != item.class) {
          item.active = false;
        }
        return item;
      });

      // 初始化标绘
      if (!this.draw)
        this.draw = new DrawTool(globalVariable.map, this.drawCompleteCallback);
      // 绘制完成后，将插件将绘制的feature返回，并添加至绘制中标注层中的source中，设置feature样式和属性（状态为编辑中）
      // 保存时再提交至服务器（状态转为已保存），保存时将此标注添加到已有标注层中
      if (obj.active) {
        switch (obj.class) {
          case "OwnMark":
            // 获取用户标注数据后，向source中添加feature，feature中设置样式
            this.getNowUserMark();
            break;
          default:
            this.draw.stop();
            if (this.closeMeasure) this.closeMeasure();
            this.draw.start(obj.class);
            break;
        }
      } else {
        this.draw.stop();
        switch (obj.class) {
          case "OwnMark":
            // 移除标注图层
            this.removeSavedSource();
            break;
          default:
            break;
        }
      }
    },

    drawCompleteCallback(geometry) {
      let feature = this.createFeature(geometry, this.defaultStyle);
      this.markList = this.markList.map(function (item) {
        if (item.class == "OwnMark") return item;
        item.active = false;
        return item;
      });
      // 打开设置面板
      this.nowFeature = feature;
      this.nowFeatureInfo = feature.values_.properties;
      this.markSettingContentIsShow = true;

      this.resetStyle();
      this.drawing_source.addFeature(feature);
    },

    createFeature(geometry, styleConfig) {
      let feature = new Feature({
        geometry: geometry,
        properties: {
          name: "",
          describe: "",
          editing: true,
          isSaved: false,
          geometryType: geometry.getType(),
          styleConfig: JSON.parse(JSON.stringify(styleConfig)),
        },
        callback: this.clickFeatureCallback,
      });
      return feature;
    },

    clickFeatureCallback(feature, selectSingleClickFeatures) {
      this.nowFeature = feature;
      this.nowFeatureInfo = feature.values_.properties;
      // 打开设置面板
      this.markSettingContentIsShow = true;
    },

    // 样式设置
    styleSet(feature) {
      if (!feature) return;
      let style;
      let styleConfig = feature.values_.properties.styleConfig;
      let geometry = feature.getGeometry();
      switch (geometry.getType()) {
        case "Point":
          let svg = this.resetSVGColor(styleConfig.image, styleConfig.color);
          style = {
            image: new Icon({
              scale: 0.3,
              anchor: [0.5, 1],
              crossOrigin: "anonymous",
              src: "data:image/svg+xml," + escape(svg),
            }),
          };
          break;
        case "LineString":
          style = {
            stroke: new Stroke({
              color: styleConfig.color,
              width: styleConfig.width,
            }),
          };
          break;
        case "Polygon":
          style = {
            stroke: new Stroke({
              color: styleConfig.color,
              width: styleConfig.width,
            }),
            fill: new Fill({
              color: styleConfig.fill,
            }),
          };
        default:
          break;
      }
      return new Style(style);
    },

    resetPicture(item) {
      this.nowFeatureInfo.styleConfig.image = item.content;
      this.resetStyle();
    },

    resetColor(event, type) {
      let styleSetting = this.nowFeatureInfo.styleConfig;
      styleSetting[type] = event;
      this.resetStyle();
    },

    convertRGBToHEX(value) {
      const reg = /[0-9]\d+/g;
      const getArr = value.match(reg);
      let hexStr =
        "#" + ((getArr[0] << 16) | (getArr[1] << 8) | getArr[2]).toString(16);
      return hexStr;
    },

    resetSVGColor(svgText, color) {
      let parser = new DOMParser();
      let xmlDom = parser.parseFromString(svgText, "text/html");
      xmlDom.querySelector("g>path").setAttribute("fill", color);
      return new XMLSerializer().serializeToString(xmlDom.querySelector("svg"));
    },

    resetStyle() {
      let geometry = this.nowFeature.getGeometry();
      let styleSetting = this.nowFeatureInfo.styleConfig;
      let style;
      switch (geometry.getType()) {
        case "Point":
          let svg = this.resetSVGColor(styleSetting.image, styleSetting.color);
          style = new Style({
            image: new Icon({
              scale: 0.3,
              anchor: [0.5, 1],
              crossOrigin: "anonymous",
              src: "data:image/svg+xml," + escape(svg),
            }),
          });
          break;
        case "LineString":
          style = new Style({
            stroke: new Stroke({
              color: styleSetting.color,
              width: styleSetting.width,
            }),
          });
          break;
        case "Polygon":
          style = new Style({
            stroke: new Stroke({
              color: styleSetting.color,
              width: styleSetting.width,
            }),
            fill: new Fill({
              color: styleSetting.fill,
            }),
          });
        default:
          break;
      }
      this.nowFeature.setStyle(style);
      // this.nowFeature.changed();
    },

    // 标注清空
    clearFeature() {
      this.removeDrawingSource();
      this.removeSavedSource();
    },

    // 移除用户已保存的图层
    removeDrawingSource() {
      let that = this;
      if (this.drawing_source) {
        this.drawing_source.getFeatures().forEach((element) => {
          that.drawing_source.removeFeature(element);
        });
      }
    },

    // 移除用户已保存的图层
    removeSavedSource() {
      let that = this;
      if (this.saved_source) {
        this.saved_source.getFeatures().forEach((element) => {
          that.saved_source.removeFeature(element);
        });
      }
    },

    // 关闭设置面板
    closeMarkSetting() {
      this.markSettingContentIsShow = false;
      if (this.nowFeature) {
        if (this.nowFeature.values_.properties.isSaved) {
          this.nowFeature.values_.properties.editing = false;
        }
      }
    },

    // 关闭模块
    close() {
      this.clearFeature();
      this.nowFeature = null;
      this.markSettingContentIsShow = false;
      this.stop();
      this.closeCallback();
    },

    // 隐藏
    hide() {
      this.closeCallback();
      this.markSettingContentIsShow = false;
    },

    // 停止绘制
    stop() {
      if (this.draw) this.draw.stop();
      this.markList.map(function (item) {
        item.active = false;
        return item;
      });
    },

    // 获取当前用户的标注
    getNowUserMark() {
      let that = this;
      // 上传loading
      const loading = this.$loading({
        customClass: "allPageLoading",
        lock: true,
        text: "数据获取中，请稍后！",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      api
        .getMarkByUser({
          userId: 2,
          sourceId: systemConfig.sourceId,
          page: 0,
          pageSize: 10000,
        })
        .then((result) => {
          if (result.code == 200) {
            let data = result.content;
            let idArr = that.saved_source.getFeatures().map(function (feature) {
              return feature.values_.properties.id;
            });
            let features = [];
            data.forEach((item) => {
              if (idArr.length == 0) {
                features.push(shaxuan(item));
              } else {
                if (idArr.indexOf(item.id) <= -1) {
                  features.push(shaxuan(item));
                }
              }
            });
            function shaxuan(item) {
              let feature = JSON.parse(item.geojson);
              let properties = JSON.parse(JSON.stringify(feature.properties));
              properties.id = item.id;
              feature.properties = {
                callback: that.clickFeatureCallback,
                properties: properties,
              };
              return feature;
            }
            that.saved_source.addFeatures(
              new GeoJSON().readFeatures(
                {
                  type: "FeatureCollection",
                  features: features,
                },
                {
                  dataProjection: "EPSG:4326",
                  featureProjection: "EPSG:3857",
                }
              )
            );
            loading.close();
          } else {
            loading.close();
            that.$message({
              type: "warning",
              message: result.message,
            });
          }
        })
        .catch((err) => {
          loading.close();
        });
    },

    // 编辑
    edit() {
      this.nowFeature.values_.properties.editing = true;
      this.nowFeatureInfo.editing = true;
      // 转入绘制中图层
      this.saved_source.removeFeature(this.nowFeature);
      this.drawing_source.addFeature(this.nowFeature);
    },

    // 删除
    delMark() {
      let that = this;
      if (this.nowFeature.values_.properties.isSaved) {
        // 服务器删除
        const loading = this.$loading({
          customClass: "allPageLoading",
          lock: true,
          text: "数据删除中，请稍后！",
          spinner: "el-icon-loading",
          background: "rgba(0, 0, 0, 0.7)",
        });
        api
          .delMarkByID({
            id: this.nowFeature.values_.properties.id,
          })
          .then((result) => {
            loading.close();
            if (result.code == 200) {
              that.$message({
                type: "success",
                message: "标注删除成功！",
              });
              that.drawing_source.removeFeature(that.nowFeature);
              that.nowFeature = null;
              that.markSettingContentIsShow = false;
            } else {
              that.$message({
                type: "warning",
                message: result.message,
              });
            }
          })
          .catch((err) => { });
      } else {
        this.drawing_source.removeFeature(that.nowFeature);
        this.nowFeature = null;
        this.markSettingContentIsShow = false;
      }
    },

    // 上传
    sure() {
      let that = this;
      this.nowFeature.values_.properties.editing = false;
      let cloneGeometry = this.nowFeature.getGeometry().clone();
      if (!this.nowFeature.values_.properties.isSaved) {
        // 当 未存入服务器
        this.nowFeature.values_.properties.isSaved = true;
        const loading = this.$loading({
          customClass: "allPageLoading",
          lock: true,
          text: "数据上传中，请稍后！",
          spinner: "el-icon-loading",
          background: "rgba(0, 0, 0, 0.7)",
        });
        api
          .addNewMark({
            userId: 2,
            sourceId: 0,
            type: this.geometryType[cloneGeometry.getType()],
            geojson: JSON.stringify({
              type: "Feature",
              properties: this.nowFeature.values_.properties,
              geometry: {
                type: cloneGeometry.getType(),
                coordinates: cloneGeometry
                  .transform("EPSG:3857", "EPSG:4326")
                  .getCoordinates(),
              },
            }),
          })
          .then((result) => {
            loading.close();
            if (result.code == 200) {
              that.$message({
                type: "success",
                message: "标注上传成功！",
              });
              that.nowFeature.values_.properties["id"] = result.content.id;
              that.nowFeatureInfo = that.nowFeature.values_.properties;
              that.markSettingContentIsShow = false;
              // 转入已保存图层
              that.saved_source.addFeature(that.nowFeature);
              that.drawing_source.removeFeature(that.nowFeature);
            } else {
              that.$message({
                type: "warning",
                message: result.message,
              });
            }
          })
          .catch((err) => {
            loading.close();
          });
      } else {
        // 已存入服务器中，进行修改
        const loading = this.$loading({
          customClass: "allPageLoading",
          lock: true,
          text: "数据修改中，请稍后！",
          spinner: "el-icon-loading",
          background: "rgba(0, 0, 0, 0.7)",
        });
        api
          .updataMark({
            id: this.nowFeature.values_.properties.id,
            userId: 2,
            sourceId: 0,
            type: this.geometryType[cloneGeometry.getType()],
            geojson: JSON.stringify({
              type: "Feature",
              properties: this.nowFeature.values_.properties,
              geometry: {
                type: cloneGeometry.getType(),
                coordinates: cloneGeometry
                  .transform("EPSG:3857", "EPSG:4326")
                  .getCoordinates(),
              },
            }),
          })
          .then((result) => {
            loading.close();
            if (result.code == 200) {
              that.$message({
                type: "success",
                message: "标注修改成功！",
              });
              that.nowFeatureInfo = that.nowFeature.values_.properties;
              that.markSettingContentIsShow = false;
              // 转入已保存图层
              that.saved_source.addFeature(that.nowFeature);
              that.drawing_source.removeFeature(that.nowFeature);
            } else {
              that.$message({
                type: "warning",
                message: result.message,
              });
            }
          })
          .catch((err) => {
            loading.close();
          });
      }
    },
  },

  computed: {
    svgObj() {
      return this.$store.state.SVGObject;
    },
  },
  watch: {
    isShow(newVal) {
      if (newVal) {
        // 绘制中的图层
        if (!this.drawing_source) {
          this.drawing_source = new VectorSource({
            projection: "EPSG:4326",
          });
          this.drawing_layer = new VectorLayer({
            source: this.drawing_source,
            zIndex: 1000,
            // style: this.styleSet,
          });
          globalVariable.map.addLayer(this.drawing_layer);
        } else {
          // 已保存的图层
          if (!this.saved_source) {
            this.saved_source = new VectorSource({
              projection: "EPSG:4326",
            });
            this.saved_layer = new VectorLayer({
              source: this.saved_source,
              zIndex: 1000,
              // style: this.styleSet,
            });
            globalVariable.map.addLayer(this.saved_layer);
          }
        }
      }
    },
    svgObj(newVal) {
      if (newVal) {
        this.renderSvgObj = Object.assign({}, newVal);
        this.mapPointSvg = newVal;
        this.defaultStyle.image = newVal[Object.getOwnPropertyNames(newVal)[0]].content;
      }
    },
  },
};
</script>
<style lang="less" scoped>
@li_width: 30px;
@li_height: 30px;
@li_border_width: 2px;
@li_margin: 5px;
@container_width: (@li_width + @li_margin * 2 + @li_border_width * 2) * 4;

.markContent {
  position: absolute;
  top: 0;
  left: -175px;
}

.markContent .container {
  width: 160px;
  height: 40px;
  border-radius: 4px;

  li {
    position: relative;
    float: left;
    cursor: pointer;

    .bg {
      width: @li_width;
      height: @li_height;
      margin: @li_margin @li_margin;
      // border: @li_border_width solid #ffffff;
      border-radius: 4px;
    }

    &.OwnMark .bg,
    &.Point .bg,
    &.LineString .bg,
    &.Polygon .bg {
      background-position-x: center;
      background-position-y: center;
      background-repeat: no-repeat;
    }

    &.OwnMark .bg {
      background-image: url(../assets/images/mark/own_mark1.png);

      &:hover,
      &.active {
        background-image: url(../assets/images/mark/own_mark_active1.png);
      }
    }

    &.Point .bg {
      background-image: url(../assets/images/mark/point1.png);

      &:hover,
      &.active {
        background-image: url(../assets/images/mark/point_active1.png);
      }
    }

    &.LineString .bg {
      background-image: url(../assets/images/mark/polyline1.png);

      &:hover,
      &.active {
        background-image: url(../assets/images/mark/polyline_active1.png);
      }
    }

    &.Polygon .bg {
      background-image: url(../assets/images/mark/polygon1.png);

      &:hover,
      &.active {
        background-image: url(../assets/images/mark/polygon_active1.png);
      }
    }
  }
}

.markSettingContent {
  position: absolute;
  top: -60px;
  left: calc(100% - 70px - 400px);
}

.markSettingContent .container {
  border-radius: 4px;
  width: 400px;
  height: fit-content;

  .title {
    width: 100%;
    height: 39px;
    line-height: 40px;
    position: relative;
    text-indent: 10px;
    font-size: 16px;
    border-bottom: 1px solid #eeeeee;

    .close {
      width: 20px;
      height: 20px;
      line-height: 20px;
      text-align: center;
      margin: 10px 10px;
      font-size: 20px;
      float: right;
      cursor: pointer;
      text-indent: 0px;
      vertical-align: top;
    }
  }

  .header {
    border-bottom: 1px solid #eeeeee;
    padding: 10px 0px;
    text-align: center;
  }

  .content {
    position: relative;
    height: fit-content;
    max-height: 600px;
    overflow: hidden;
    overflow-y: auto;

    .el-row:first-child {
      margin-top: 15px;
    }

    .el-row {
      height: fit-content;
      margin-bottom: 15px;
    }

    .el-col.label {
      font-size: 16px;
      text-align: right;
      line-height: 40px;
      padding-right: 10px;
    }

    .picture_store {
      width: 272px;
      height: 300px;
      border: 1px solid #eeeeee;
      padding: 5px 10px;
      overflow: hidden;
      overflow-y: auto;

      li {
        float: left;
        width: 34px;
        height: 42px;
        background-position-x: center;
        background-position-y: top;
        background-repeat: no-repeat;
        margin: 0px 5px;
        margin-top: 10px;
        margin-bottom: 20px;
        background-size: 100% 100%;
        position: relative;
        cursor: pointer;

        div {
          position: absolute;
          bottom: -20px;
          width: 100%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
      }
    }
  }

  .footer {
    border-top: 1px solid #eeeeee;
    padding: 10px 0px;
    text-align: center;
  }
}
</style>