<template>
  <div
    class="jigsaw-game"
  >
    <div class="left-wrapper">
      <div class="object-wrapper">
        <object
          ref="svgContainer"
          :data="require(`@/assets/images/jigsaw-game-${$route.query.sceneL2Idx}/compound.svg`)"
          type=""
        />
      </div>
      <div
        ref="forDrop"
        class="for-drop"
        :style="{
          left: leftForDrop + 'px',
          top: topForDrop + 'px',
          width: widthForDrop + 'px',
          height: heightForDrop + 'px',
        }"
        @dragover.prevent
        @drop.prevent="onDrop"
      />
    </div>

    <div class="jigsaw-list">
      <h1>
        <img
          class=""
          :src="require(`@/assets/images/title-level2-${$route.query.sceneL2Idx}.png`)"
          alt=""
          draggable="false"
        >
      </h1>
      <li
        v-for="(jigsawItem, idx) in jigsawItemsFlatten"
        :key="idx"
      >
        <img
          class=""
          :style="{
            cursor: !jigsawProgressSceneL2.isJigsawDone && jigsawItem.hasGot && !jigsawItem.hasPut ? 'grab' : 'default',
          }"
          :src="require(`@/assets/images/jigsaw-game-${$route.query.sceneL2Idx}/jigsaw${jigsawItem.hasGot ? '' : '-shade'}/${jigsawItem.name}`)"
          alt=""
          :draggable="!jigsawProgressSceneL2.isJigsawDone && jigsawItem.hasGot && !jigsawItem.hasPut ? true : false"
          @dragstart="(e) => {
            onDragStart(e, jigsawItem.name, idx)
          }"
          @dragend="onDragEnd(jigsawItem.name)"
        >
        <div
          class="jigsaw-name"
          :title="jigsawItem.name.split('.')[1]"
        >
          {{ jigsawItem.name.split('.')[1] }}
        </div>
      </li>
    </div>
  </div>
</template>

<script>
import useWindowSizeAdaptor from '@/useFunctions/useWindowSizeAdaptor.js'
import { ElMessageBox } from 'element-plus'

export default {
  name: 'JigsawGame',
  setup () {
    const { windowSizeWhenDesign, unit } = useWindowSizeAdaptor()

    return {
      windowSizeWhenDesign,
      unit
    }
  },
  data() {
    return {
      jigsawItemsFlatten: [],
      leftForDrop: 0,
      topForDrop: 0,
      widthForDrop: 0,
      heightForDrop: 0,
      imgFrameThicknessWhenDesign: '15',
    }
  },
  computed: {
    ...mapState([
      'gameProgress',
    ]),
    jigsawProgressSceneL2() {
      return this.gameProgress.jigsawProgress[Number(this.$route.query.sceneL2Idx)]
    },
  },
  mounted() {
    for (const jigsawProgressSceneL3 of this.jigsawProgressSceneL2.children) {
      for (const jigsawItem of jigsawProgressSceneL3.jigsawList) {
        this.jigsawItemsFlatten.push({
          name: jigsawItem,
          hasGot: jigsawProgressSceneL3.hasGotJigsaw,
          hasPut: false,
        })
      }
    }
    setTimeout(() => {
      console.log('进入timeout!')
      if (!this.jigsawProgressSceneL2.isJigsawDone) {
        console.log('要hide！')
        const objectDocument = this.$refs.svgContainer.contentDocument
        const gList = objectDocument.getElementsByTagName('g')
        for (let index = 1; index < gList.length; index++) {
          const element = gList[index]
          element.setAttribute('visibility', 'hidden')
        }
      }
    }, 300)
  },
  unmounted() {
  },
  methods: {
    ...mapMutations([
      'recordJigsawDone',
    ]),
    onDragStart(e, jigsawImgName, idx) {
      // 不知道为啥，在svg内部元素上无法触发drop事件，求助gpt也没用。只好用一个透明方块放在需要能drop的svg内部元素上面。

      // reset div for drop
      this.leftForDrop = 0
      this.topForDrop = 0
      this.widthForDrop = 0
      this.heightForDrop = 0

      // get id
      let temp = jigsawImgName.split('.')
      temp.pop()
      const id = `_${temp.join('.')}-剪影_图像`

      // get elements
      const objectDocument = this.$refs.svgContainer.contentDocument
      const svgEl = objectDocument.getElementsByTagName('svg')[0]
      const gTarget = objectDocument.getElementById(id)
      const imgTarget = gTarget.getElementsByTagName('image')[0]

      // get svg original size from viewBox attribute
      const svgWidth = Number(svgEl.getAttribute('viewBox').split(' ')[2])
      const svgHeight = Number(svgEl.getAttribute('viewBox').split(' ')[3])
      console.log('svg original size by viewBox attribute: ', svgWidth, svgHeight)

      // show g element
      gTarget.setAttribute('visibility', 'show')

      // save drag info
      e.dataTransfer.setData('text/plain', jigsawImgName)
      e.dataTransfer.setData('text/html', String(idx)) // 并非真的html类型，只是为了传输数据

      // get image's original size
      const imageWidthOriginal = Number(imgTarget.getAttribute('width'))
      const imageHeightOriginal = Number(imgTarget.getAttribute('height'))
      console.log("image's original size: ", imageWidthOriginal, imageHeightOriginal)

      // get image's original top left from transform attribute
      let imageLeftOriginal = 0
      let imageTopOriginal = 0
      const transformString = imgTarget.getAttribute('transform')
      if (transformString) {
        const regForTransform = /translate\((.+)\)/
        const matchRes = transformString.match(regForTransform)
        if (matchRes) {
          imageLeftOriginal = Number(matchRes[1].split(' ')[0])
          imageTopOriginal = Number(matchRes[1].split(' ')[1]) || 0
        } else {
          imageLeftOriginal = 0
          imageTopOriginal = 0
        }
      } else {
        imageLeftOriginal = 0
        imageTopOriginal = 0
      }
      console.log("image's original top left: ", imageLeftOriginal, imageTopOriginal)

      // 计算画框粗细
      let imageFrameThicknessActual = 0
      if (this.unit === '100vh') {
        imageFrameThicknessActual = Number(this.imgFrameThicknessWhenDesign) / 1080 * window.innerHeight
      } else {
        imageFrameThicknessActual = Number(this.imgFrameThicknessWhenDesign) / 1920 * window.innerWidth
      }
      console.log("image frame's actual thickness: ", imageFrameThicknessActual)

      // compute image's actual left top
      const topLeft = utils.mapPosFromDraftToWindow({
        x: imageLeftOriginal,
        y: imageTopOriginal,
      }, 'cover', svgWidth, svgHeight, this.$refs.svgContainer.clientWidth, this.$refs.svgContainer.clientHeight)
      console.log("image's actual left top: ", topLeft.x, topLeft.y)

      const rightBottom = utils.mapPosFromDraftToWindow({
        x: imageLeftOriginal + imageWidthOriginal,
        y: imageTopOriginal + imageHeightOriginal,
      }, 'cover', svgWidth, svgHeight, this.$refs.svgContainer.clientWidth, this.$refs.svgContainer.clientHeight)
      console.log("image's actual right top: ", rightBottom.x, rightBottom.y)

      this.leftForDrop = topLeft.x + imageFrameThicknessActual
      this.topForDrop = topLeft.y + imageFrameThicknessActual
      this.widthForDrop = rightBottom.x - topLeft.x
      this.heightForDrop = rightBottom.y - topLeft.y
      console.log("image's actual ltwh for render: ", this.leftForDrop, this.topForDrop, this.widthForDrop, this.heightForDrop)
    },
    onDragEnd(jigsawImgName) {
      let temp = jigsawImgName.split('.')
      temp.pop()
      const id = `_${temp.join('.')}-剪影_图像`
      const objectDocument = this.$refs.svgContainer.contentDocument
      objectDocument.getElementById(id).setAttribute('visibility', 'hidden')
    },
    onDrop(e) {
      e.preventDefault()
      let jigsawImgName = e.dataTransfer.getData('text/plain')
      let temp = jigsawImgName.split('.')
      temp.pop()
      const id = `_${temp.join('.')}_图像`
      const objectDocument = this.$refs.svgContainer.contentDocument
      objectDocument.getElementById(id).setAttribute('visibility', 'show')

      const idx = Number(e.dataTransfer.getData('text/html'))
      this.jigsawItemsFlatten[idx].hasPut = true

      if (!this.jigsawItemsFlatten.find((item) => {
        return !item.hasPut
      })) {
        ElMessageBox.alert('', '拼图完成！', {
          confirmButtonText: '确定',
          callback: (action) => {
            console.log(action)
          },
        })
        this.recordJigsawDone(Number(this.$route.query.sceneL2Idx))
      }
    },
    onDragOver(e) {
      e.preventDefault()
    },
  },
}
</script>

<style lang="less" scoped>
.jigsaw-game {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-image: url(@/assets/images/bg-game.jpg);
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  display: flex;
  justify-content: center;
  align-items: center;
  >.left-wrapper {
    width: calc(950 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    height: calc(628 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    background-image: url(@/assets/images/bg-jigsaw-game-page-frame.jpg);
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
    margin-right: calc(83 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    padding: calc(v-bind('imgFrameThicknessWhenDesign') / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    position: relative;
    >.object-wrapper {
      width: 100%;
      height: 100%;
      overflow: hidden;
      >object {
        user-select: none;
        // width: 100%;
      }
    }
    >.for-drop {
      position: absolute;
      // background-color: red;
      // opacity: 0.2;
      z-index: 1;
    }
  }
  >.jigsaw-list {
    position: relative;
    width: calc(580 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    height: calc(648 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    padding-top: calc(8 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
    overflow: auto;

    >h1 {
      position: absolute;
      left: 0;
      top: calc(-101 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
      height: calc(74 / v-bind('windowSizeWhenDesign') * v-bind('unit'));;
      font-size: 0;
      >img {
        height: 100%;
      }
    }
    >li {
      display: inline-block;
      margin-right: calc(28 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
      margin-bottom: calc(17 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
      text-align: center;
      >img {
        width: calc(157 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
        height: calc(157 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
        background: #fff;
        margin-bottom: calc(15 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
      }
      >.jigsaw-name {
        font-size: calc(20 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
        font-family: Source Han Sans CN-Bold, Source Han Sans CN;
        font-weight: bold;
        color: #C26827;
        overflow: hidden;
        white-space: pre;
        text-overflow: ellipsis;
        user-select: none;
      }
    }
  }
}
</style>