<script>
import VueDragResizeRotate from "@gausszhou/vue-drag-resize-rotate";
import ImgSetting from './imgSetting.vue'
import bus from '@/bus'
import PrintDialog from "@/views/design/head/printDialog.vue";
import {debounce} from 'lodash'

const img = require('../../../assets/bg_tshirt_shadow.png')
export default {
  components: {
    PrintDialog,
    VueDragResizeRotate,
    ImgSetting,
  },

  computed: {
    sysSetting() {
      return this.$store.getters.systemSetting
    },
    gridSpacing() {
      return this.$store.getters.systemSetting.gridSpacing.slice(0, 2) + 'px'
    },
    computedGridSize() {
      const getter = this.$store.getters.systemSetting
      const num = getter.gridSpacing.slice(0, 2)
      return 10 + 'px'
    },

    returnItem() {
      return this.imgList[this.selectIndex]
    }
  },
  data() {
    return {
      actionList: [],
      parentWidth: 0,
      imgHeight: 0,
      selectImgList: [],
      selectImgIndex: 0,
      bus: 0,
      showImgSetting: false,
      parentHeight: 0,
      width: 0,
      selectIndex: 0,
      height: 0,
      x: 0,
      y: 0,
      imgList: [],
      row: 8,
      img,
      col: 7
    }
  },
  watch: {

    imgList: {
      handler() {
        this.$store.commit('changeImgList', this.imgList)
      },
      deep: true,
      immediate: true
    },
    selectIndex() {
      if (this.selectIndex >= 0) {
        if (!this.showImgSetting) {
          this.showImgSetting = true
        }
      } else {
        this.showImgSetting = false
      }
    }
  },
  methods: {
    debounce,
    indexChange(v) {
      console.log(v)
      if (this.imgList.length === 0) return;
      let index = !this.imgList[this.selectIndex] ? 0 : this.selectIndex

      let item = this.$store.state.actionList[v]
      if (!item) return;

      if (item.t === 'drag') {
        this.$set(this.imgList[index], 'x', item.x)
        this.$set(this.imgList[index], 'y', item.y)
      } else if (item.t === 'resize') {
        this.$set(this.imgList[index], 'x', item.x)
        this.$set(this.imgList[index], 'y', item.y)
        this.$set(this.imgList[index], 'w', item.w)
        this.$set(this.imgList[index], 'h', item.h)
      }
      console.log()
    },
    getOneMmsPx() {
      // 创建一个1mm宽的元素插入到页面，然后坐等出结果
      let div = document.createElement("div");
      div.id = "mm";
      div.style.width = "1mm";
      document.querySelector("body").appendChild(div);
      // 原生方法获取浏览器对元素的计算值
      let mm1 = document.getElementById("mm").getBoundingClientRect();

      return mm1.width;
    },
    selectImg(it, i) {
      this.selectImgIndex = i
      this.imgList = []
      this.getBackFile([it])
    },
    ev(type) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return

      let w = document.getElementById('line').clientWidth / 2
      let h = document.getElementById('line').clientHeight / 2

      switch (type) {
        case 'center':
          this.$set(this.imgList[this.selectIndex], 'x', Number(w) - (Number(this.imgList[this.selectIndex].w) / 2))
          this.$set(this.imgList[this.selectIndex], 'y', Number(h) - (Number(this.imgList[this.selectIndex].h) / 2))
          break;
        case 'x_center':
          this.$set(this.imgList[this.selectIndex], 'x', Number(w) - (Number(this.imgList[this.selectIndex].w) / 2))
          break;
        case 'y_center':
          this.$set(this.imgList[this.selectIndex], 'y', Number(h) - (Number(this.imgList[this.selectIndex].h) / 2))
          break;
        case 'add_index':
          this.$set(this.imgList[this.selectIndex], 'zIndex', this.imgList[this.selectIndex].zIndex + 1)
          break;
        case 'reduce_index':
          this.$set(this.imgList[this.selectIndex], 'zIndex', this.imgList[this.selectIndex].zIndex - 1)
          break;
        default:
          break
      }
    },
    formChange(form) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return
      let f = JSON.parse(JSON.stringify(form))
      let x_mm = f.x
      let w_mm = f.w
      let h_mm = f.h
      let y_mm = f.y
      this.$set(this.imgList[this.selectIndex], 'x', x_mm)
      this.$set(this.imgList[this.selectIndex], 'y', y_mm)
      this.$set(this.imgList[this.selectIndex], 'w', w_mm)
      this.$set(this.imgList[this.selectIndex], 'h', h_mm)
      this.$set(this.imgList[this.selectIndex], 'r', f.r)
    },
    close() {
      this.showImgSetting = false
    },
    onDragDebounce(left, top) {
      // console.log(left,top,'2')
      // if (!this.imgList[this.selectIndex]) return
      // this.imgList[this.selectIndex].x = left
      // this.imgList[this.selectIndex].y = top
      // this.$set(this.imgList[this.selectIndex], 'x', left)
      // this.$set(this.imgList[this.selectIndex], 'y', top)
    },

    dragStop(left, top) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return
      this.$set(this.imgList[this.selectIndex], 'x', left)
      this.$set(this.imgList[this.selectIndex], 'y', top)
      this.actionList.unshift({
        t: 'drag',
        x: left,
        y: top
      })
      this.$store.commit('changeActionList', this.actionList)
    },
    resizeStop(x, y, w, h) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return
      this.$set(this.imgList[this.selectIndex], 'w', w)
      this.$set(this.imgList[this.selectIndex], 'h', h)
      this.$set(this.imgList[this.selectIndex], 'x', x)
      this.$set(this.imgList[this.selectIndex], 'y', y)
      this.actionList.unshift({
        t: 'resize',
        x,
        y,
        w,
        h
      })
      this.$store.commit('changeActionList', this.actionList)
    },
    resizing(x, y, w, h) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return
      this.$set(this.imgList[this.selectIndex], 'w', w)
      this.$set(this.imgList[this.selectIndex], 'h', h)
    },
    rotating(angle) {
      if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return
      this.$set(this.imgList[this.selectIndex], 'r', angle)
    },
    outsideClick(e) {
      if (!e.target.className.includes('sucaitu-img')) {
        this.selectIndex = -1
        this.close()
      }
    },
    selectItem(index) {
      this.selectIndex = index
    },
    delImg(index) {
      this.imgList.splice(index, 1)
    },
    fileToBase64(file) {
      return new Promise((resolve, reject) => {
        // 创建一个新的 FileReader 对象
        const reader = new FileReader();
        // 读取 File 对象
        reader.readAsDataURL(file);
        // 加载完成后
        reader.onload = function () {
          // 将读取的数据转换为 base64 编码的字符串
          const base64String = reader.result;
          // 解析为 Promise 对象，并返回 base64 编码的字符串
          resolve(base64String);
        };

        // 加载失败时
        reader.onerror = function () {
          reject(new Error("Failed to load file"));
        };
      });
    },
    getBackFile(files) {
      console.log(files)
      let that = this
      for (let i = 0; i < files.length; i++) {
        files[i].url = files[i].productionFile
        that.$nextTick(() => {
          that.getImageSize(files[i].url).then(data => {
            let w = document.getElementById('line').clientWidth / 2
            let rate = data.height / data.width
            that.imgList.push({
              url: files[i].url,
              fileName: files[i].fileName,
              rate,
              w: 100,
              zIndex: that.imgList.length,
              x: w - 75,
              y: 0,
              h: 100 * rate,
              r: 0,
            });
            that.selectIndex = that.imgList.length - 1
            that.showImgSetting = true
          })
        })
      }
    },
    addFile(file) {
      let that = this
      that.$nextTick(() => {
        that.getImageSize(file.url).then(data => {
          let w = document.getElementById('line').clientWidth / 2
          let rate = data.height / data.width
          that.imgList.push({
            url: file.url,
            w: 100,
            rate,
            fileName: file.fileName,
            zIndex: that.imgList.length,
            x: w - 75,
            y: 0,
            h: 100 * rate,
            r: 0,
          });
          that.selectIndex = that.imgList.length - 1
          that.showImgSetting = true
        })
      })
    },
    listenUpload() {
      let that = this
      that.parentWidth = document.getElementById('img').clientWidth
      that.parentHeight = document.getElementById('img').clientHeight
      let dp = document.getElementsByClassName('container')[0]
      dp.addEventListener('dragover', function (e) {
        e.stopPropagation();
        //阻止浏览器默认打开文件的操作
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
      });
      dp.addEventListener("drop", async function (e) {
        e.stopPropagation();
        //阻止浏览器默认打开文件的操作
        e.preventDefault();
        console.log(e)
        const files = e.dataTransfer.files;
        if (files.length === 0) return
        if (files[0].type !== 'image/png') {
          return that.$message.warning('只能上传png格式文件')
        }
        let formData = new FormData()
        console.log(files)
        formData.append('file', files[0])
        let {data} = await that.$api.post('/uploadImage', formData, {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded"
          }
        })
        that.imgList = []
        that.selectImgList = []
        that.selectImgIndex = 0
        that.addFile(data)
      });
    },
    getImageSize(url) {
      return new Promise(function (resolve, reject) {
        let image = new Image();
        image.onload = function () {
          resolve({
            width: image.width,
            height: image.height
          });
        };
        image.onerror = function () {
          reject(new Error('error'));
        };
        image.src = url;
      });
    },

    /**
     * 根据主题颜色修改图片颜色
     * @param  {[type]}   imgUrl    图片url
     * @param  {[type]}  color 主题颜色
     * @param  {Function} callback  返回值 返回base64
     */
    changeImageColor(color = "#00ff7f", callback) {
      let threshold = 114; //默认颜色阀值 为 114 －>和默认图相关
      let img = new Image()
      img.src = require('../../../assets/bg_tshirt_shadow.png');
      let newR = parseInt("0x" + color.substr(1, 2));
      let newG = parseInt("0x" + color.substr(3, 2));
      let newB = parseInt("0x" + color.substr(5, 2));
      //图片加载后进行处理
      img.onload = function () {

        let width = img.width, height = img.height, canvas = document.createElement("canvas"),
            ctx = canvas.getContext("2d");
        canvas.width = width;
        canvas.height = height;
        // 将源图片复制到画布上
        ctx.drawImage(img, 0, 0, width, height);
        // 获取画布的像素信息
        let imageData = ctx.getImageData(0, 0, width, height), data = imageData.data;
        // 对像素集合中的单个像素进行循环，每个像素是由4个通道组成，所以要注意
        let i = 0;
        while (i < data.length) {
          let r = data[i++],
              g = data[i++],
              b = data[i++],
              a = data[i++];
          //计算透明度
          let alp = (255 - r) / (255 - threshold);
          //判断是否透明
          let isTransparent = r == 255 && g == 255 && b == 255 && a == 255;
          if (isTransparent) {
            data[i - 1] = 0;
          } else {
            data[i - 4] = newR;
            data[i - 3] = newG;
            data[i - 2] = newB;
            data[i - 1] = a !== 255 ? 255 - a : alp * 255; //处理透明的图片和不透明的图片
          }
        }
        // 将修改后的代码复制回画布中
        ctx.putImageData(imageData, 0, 0);
        // 图片导出为 png 格式
        let imgType = "png";
        let imgData = canvas.toDataURL(imgType);

        callback && callback(imgData);
      };
      return img;
    }
  }
  ,

  mounted() {
    this.imgHeight = window.screen.height + 'px'

    bus.$on('busEmit', (v) => {
      let {type, value} = v
      switch (type) {
        case 'grid':
          this.row = value.row
          this.col = value.col
          break;
        case 'index':
          this.indexChange(value)
          break;
        case 'bg':
          this.changeImageColor(value, (res) => {
            this.img = res
          })
          break;
        case 'uploadImage':
          this.imgList = []
          this.selectImgList = []
          this.selectImgIndex = 0
          this.addFile(value)
          break;
        case 'sendFile':
          this.imgList = []
          this.selectIndex = -1
          if (value.length > 0) {
            console.log(value)
            this.selectImgList = value
            this.selectImgIndex = 0
            this.getBackFile([value[0]])
            // this.addFile([value[0].file])
          }
          break;
        default:
          break;
      }
    })

    document.addEventListener('keyup', (e) => {
      if (e.keyCode === 8) {
        if (this.selectIndex >= 0) {
          this.imgList.splice(this.selectIndex, 1)
        }
      }
    })
    this.listenUpload()

    document.getElementById('img').onmousedown = function (e) {
      e.preventDefault()
    }
  }
}
</script>

<template>
  <div class="page-main">
    <div @click="outsideClick" class="main-bg">
      <div class="container">
        <div class="select-img" v-if="selectImgList.length>1">
          <div @click="selectImg(it,i)" :class="{'select-img-index':selectImgIndex===i}" v-for="(it,i) in selectImgList"
               :key="i"
               class="img-item">
            <el-image style="width: 100px;height: auto;" :src="it.productionFile"
            ></el-image>
            <span>{{ it.designId }}</span>
          </div>
        </div>
        <div :style="{height:imgHeight}" id="img">
          <div id="line" v-if="sysSetting.gridShow">
            <div class="sucaitu">
              <vue-drag-resize-rotate
                  :w="item.w"
                  class-name="my-drag-resize-rotate"
                  :prevent-deactivation="true"
                  :h="item.h"
                  :parent="false"
                  :x="item.x"
                  :z="item.zIndex"
                  :lock-aspect-ratio="true"
                  :active="index===selectIndex"
                  :y="item.y"
                  v-for="(item,index) in imgList"
                  :key="index"
                  :draggable="true"
                  :resizable="true"
                  :rotatable="true"
                  @dragging="onDragDebounce"
                  @dragstop="dragStop"
                  @resizing="resizing"
                  @resizestop="resizeStop"
                  @rotating="rotating"
                  :r="item.r"
              >
                <div ref="sucaitu-img" @click="selectItem(index)"
                     :class="{'active': index === selectIndex}"
                     class="sucaitu-img img element">
                  <img :src="item.url" alt="" class="sucaitu-img">
                  <i @click="delImg(index)" v-if="index===selectIndex" class=" close el-icon-close"></i>
                  <div v-if="index===selectIndex" class="control-point control-rotator"></div>
                </div>
              </vue-drag-resize-rotate>

            </div>
            <div v-if="$store.getters.systemSetting.gridShow" style="width:482px;height:542px" class="grid">
              <div :style="{height:gridSpacing,lineHeight:gridSpacing}" class="grid-row" v-for="it in 100" :key="it">
                <div :style="{width:gridSpacing,height:gridSpacing}"
                     class="grid-col" v-for="it in 100" :key="it">

                </div>
              </div>
            </div>
            <!--          <table v-if="$store.getters.systemSetting.gridShow"   border="none">-->
            <!--            <tr :style="{height:computedGridSize}" style="width: 482px;overflow: hidden;"-->
            <!--                v-for="it in Number((543/Number($store.getters.systemSetting.gridSpacing.slice(0,2))).toFixed(0))">-->
            <!--              <td v-for="it in Number((482/Number($store.getters.systemSetting.gridSpacing.slice(0,2))).toFixed(0))"-->
            <!--                  :style="{width:computedGridSize ,height:computedGridSize}">-->

            <!--              </td>-->
            <!--            </tr>-->
            <!--          </table>-->
          </div>
          <img class="template-img" draggable="false" :src="img" alt="">
        </div>

        <print-dialog :byPlatenSize="$store.getters.systemSetting.gridValue"/>
      </div>
    </div>
    <img-setting @ev="ev" @change="formChange" :item="returnItem" @close="close"
                 :visible="showImgSetting"></img-setting>
  </div>
</template>

<style scoped>
.page-main {
  flex: 1;
  flex-shrink: 0;
  overflow: hidden;
  box-sizing: border-box;

}

.main-bg {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

#line {
  position: absolute;
  z-index: 2;

}

.grid {
  border: 1px solid gray;
  overflow: hidden;
}

.grid-row {
  width: 100%;
  overflow: hidden;
  height: 10px;
  line-height: 10px;
  white-space: nowrap;
}

.grid-row:nth-of-type(1) .grid-col {
  border-top: none !important;
}

.grid-row:nth-last-of-type(1) .grid-col {
  border-bottom: none !important;;
}

.grid-row .grid-col:nth-of-type(1) {
  border-left: none !important;
}

.grid .grid-row .grid-col {
  display: inline-block;
  border: 1px solid gray;
  border-right: none;
}


#img {
  position: absolute;
  z-index: 1;
  left: 130px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: auto;
}

.container {
  display: flex;
  width: 100%;
  height: 100%;
  justify-content: center;
  align-items: center;
  position: relative;
}

.sucaitu {
  position: absolute;
  z-index: 3;
  width: 100%;
  //display: flex;
  //justify-content: center;
  //align-items: center;
  height: 100%;

}

.sucaitu img {
  width: 100%;
  height: 100%;

}

.select-img {
  border-color: #409eff;
}

.sucaitu .close {
  position: absolute;
  top: -11px;
  right: -12px;
  color: white;
  width: 20px;
  cursor: pointer;
  height: 20px;
  background: red;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.sucaitu .img {
  height: fit-content;
  width: 100%;
  height: 100%;
  cursor: move;
  border: 1px dashed transparent;

}

#img img {
  pointer-events: none;
  width: auto;
  height: 100%;
}

img {

  -webkit-user-drag: none;

  -webkit-user-select: none;

  -moz-user-select: none;

  -ms-user-select: none;

  user-select: none;

}

img {

  -webkit-user-drag: none;

  -moz-user-drag: none;

  -ms-user-drag: none;

  user-drag: none;

}

::v-deep .active, .active {
  border-color: #66b1ff !important;
}

.select-img-index {


  box-sizing: border-box;
  border-color: #409EFF !important;
}

.img-item span {
  margin: 5px 0;
  color: white;
}

.img-item {
  padding: 5px;
  display: flex;
  cursor: pointer;
  margin-bottom: 20px;
  border: 2px dashed transparent;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.select-img {
  width: 120px;
  z-index: 5;
  overflow: auto;
  background-color: #333;
  height: calc(100% - 72px);
  padding: 10px;
  position: fixed;
  box-sizing: border-box;
  left: 0;
  bottom: 0;
  border-right: 1px solid #ececec;
}
</style>
<style>
.el-upload {
  height: 100%;
}

.my-drag-resize-rotate {
  border-color: transparent;
}

.handle-rot::before, .handle-rot::after {
  display: none;
}
</style>