<template>
  <a-modal
    title="编辑选区"
    :visible="visible"
    :width="600"
    :zIndex="99"
    centered
    @cancel="handleCancel"
  >
    <div class="dec-img-tap" v-if="visible">
      <img class="img-block" :src="img" alt />
      <div
        class="tap-wrap"
        draggable="false"
        @mousemove.stop="childMove"
        @mouseup.stop="childUp"
      >
        <!-- 选区块 -->
        <a
          class="a-tap"
          v-for="(a, i) in editTapList"
          :key="i"
          @mousedown.stop="(e) => childDown(e, a)"
          @mousemove.stop="childMove"
          @mouseup.stop="childUp"
          @dblclick="dblclick($event, a)"
          :style="{
            top: a.top,
            left: a.left,
            width: a.width,
            height: a.height,
          }"
        >
          <a-icon @click="delTap(i)" class="tap-close" type="close-circle" />
          <div class="tap-link" v-if="$isEmptyObj(a.linkArg)">双击设链接</div>
          <template v-else>
            <div class="tap-link dec-truncate">
              {{ getLinkName(a.linkArg) }}
            </div>
            <span class="link-edit" @click.stop="selectLink($event, a)"
              >修改</span
            >
          </template>
        </a>
      </div>
    </div>
    <div slot="footer" style="padding-top: 20px; text-align: right">
      <a-button type="primary" @click="addTap">添加热区</a-button>
      <a-button
        type="primary"
        style="margin-left: 10px; width: 80px"
        @click="saveTap"
        >保存</a-button
      >
    </div>
    <!-- <linkBox ref="decLinkBoxRef" v-if="visible"/> -->
  </a-modal>
</template>
<script>
import Vue from "vue";
// import linkBox from './linkBox.vue'
function getPercent2Px(val, total) {
  try {
    const arr = (val || "").split("%");
    const px = Math.floor((arr[0] || 0) * total) / 100 + "px";
    return px;
  } catch (error) {
    console.log("getPercent2Px数据转换失败");
    return "0px";
  }
}
function getPxNum(val) {
  const arr = (val || "").split("px");
  return parseFloat(arr[0]) || 0;
}
function getPercent(val, total) {
  // %号后保留两位小数
  const num = getPxNum(val);
  try {
    const percent = Math.floor((num * 10000) / total) / 100;
    return percent + "%";
  } catch (error) {
    console.log("getPercent数据转换失败");
    return "1%";
  }
}
export default {
  inject: ["$isEmptyObj"],
  components: {
    // linkBox
  },
  data() {
    return {
      visible: false,
      editTapList: [],
      img: "",
      temp: {},
      imgH: 0,
      imgW: 0,
      mouseTarget: "", // changeBoxPosition-box位置调整;changeBoxSize-box大小调整;
      selectTarget: null,
      movingFinish: true,
      animationFinish: true,
      startX: 0,
      startY: 0,
      moveX: 0,
      moveY: 0,
      maxY: 0,
      maxX: 0,
    };
  },
  methods: {
    show(img, imgW, imgH, taps, temp) {
      this.img = img;
      this.imgH = (imgH * 552) / imgW;
      this.imgW = 552;
      this.temp = temp;
      taps = taps || [];
      this.editTapList = taps.map((item) => {
        // %转px
        const top = getPercent2Px(item.top, this.imgH);
        const left = getPercent2Px(item.left, this.imgW);
        const width = getPercent2Px(item.width, this.imgW);
        const height = getPercent2Px(item.height, this.imgH);
        return Object.assign({}, item, { top, left, width, height });
      });
      this.clear();
      this.visible = true;
    },
    getLinkName(item) {
      if (!this.$isEmptyObj(item)) {
        return item.pathName + (item.argName ? `-${item.argName}` : "");
      } else {
        return "选择链接";
      }
    },
    addTap() {
      const arr = [
        { top: "0px", left: "0px" },
        {
          top: this.imgH - this.imgW * 0.2 + "px",
          left: this.imgW * 0.8 + "px",
        },
        { top: "0px", left: this.imgW * 0.8 + "px" },
        { top: this.imgH - this.imgW * 0.2 + "px", left: "0px" },
      ];
      const position = arr[this.editTapList.length || 0] || arr[0];
      const obj = {
        ...position,
        height: this.imgW * 0.2 + "px",
        width: this.imgW * 0.2 + "px",
      };
      // 模版数据
      this.editTapList.push({
        ...this.temp,
        ...obj,
      });
      this.mouseTarget = "";
    },
    saveTap() {
      const taps = this.editTapList.map((item) => {
        // %号后保留两位小数
        const top = getPercent(item.top, this.imgH);
        const left = getPercent(item.left, this.imgW);
        const width = getPercent(item.width, this.imgW);
        const height = getPercent(item.height, this.imgH);
        return Object.assign({}, item, { top, left, width, height });
      });
      this.$emit("promise", { success: true, taps });
      this.clear();
      this.visible = false;
      this.editTapList = [];
    },
    // 删除热区
    delTap(i) {
      this.editTapList.splice(i, 1);
    },
    dblclick(e, target) {
      if (!this.$isEmptyObj(target.linkArg)) return;
      else this.selectLink(e, target, "a-tap");
    },
    selectLink(e, target, className) {
      Vue.prototype.$decLinkBoxRef.show(e, className);
      Vue.prototype.$decLinkBoxRef.$once("promise", (res) => {
        if (res.success) {
          target.linkArg = res;
        }
      });
    },
    childDown(e, a) {
      this.clear();
      this.mouseTarget = "changeBoxPosition";
      this.selectTarget = a;
      this.startX = e.x;
      this.startY = e.y;
      let { width, height } = a;
      width = getPxNum(width);
      height = getPxNum(height);
      this.maxY = this.imgH - height;
      this.maxX = this.imgW - width;

      // 看是否点击的是左下角，点左下角是改变大小
      const _width = width - 14;
      const _height = height - 14;
      if (e.offsetX > _width && e.offsetY > _height) {
        this.mouseTarget = "changeBoxSize";
      }
    },
    childMove(e) {
      if (this.mouseTarget) {
        this.moveX = e.x;
        this.moveY = e.y;
        if (this.movingFinish) {
          this.movingFinish = false;
          window.requestAnimationFrame(() => {
            this.movingFinish = true;
            this.setStyle();
          });
        }
      }
    },
    childUp(e) {
      if (this.mouseTarget) {
        this.moveX = e.x;
        this.moveY = e.y;
        this.setStyle("up");
        this.clear();
      }
    },
    setStyle() {
      if (this.animationFinish && this.mouseTarget) {
        this.animationFinish = false;
        const mouseTarget = this.mouseTarget;
        const a = this.selectTarget;
        window.requestAnimationFrame(() => {
          this.animationFinish = true;
          if (mouseTarget == "changeBoxPosition") {
            let _left = this.moveX - this.startX + getPxNum(a.left);
            let _top = this.moveY - this.startY + getPxNum(a.top);
            this.startX = this.moveX;
            this.startY = this.moveY;
            if (_left < 0) {
              _left = 0;
            }
            if (_top < 0) {
              _top = 0;
            }
            if (_left > this.maxX) {
              _left = this.maxX;
            }
            if (_top > this.maxY) {
              _top = this.maxY;
            }
            a.left = _left + "px";
            a.top = _top + "px";
          } else if (mouseTarget == "changeBoxSize") {
            let _width = this.moveX - this.startX + getPxNum(a.width);
            let _height = this.moveY - this.startY + getPxNum(a.height);
            this.startX = this.moveX;
            this.startY = this.moveY;
            if (_width < 10) {
              _width = 10;
            }
            if (_height < 10) {
              _height = 10;
            }
            if (_width > this.imgW) {
              _width = this.imgW;
            }
            if (_height > this.imgH) {
              _height = this.imgH;
            }
            a.width = _width + "px";
            a.height = _height + "px";
          }
        });
      }
    },
    handleCancel() {
      this.$emit("promise", { success: false });
      this.clear();
      this.visible = false;
      this.editTapList = [];
    },
    clear() {
      this.startX = 0;
      this.startY = 0;
      this.moveX = 0;
      this.moveY = 0;
      this.mouseTarget = "";
      this.selectTarget = null;
    },
  },
};
</script>
