<style scoped>
  .operate-item {
    font-size: 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid #eee;
  }

  .operate-item:last-child {
    margin-bottom: 0;
    border-bottom: 0 none;
  }

  .line-height-28 {
    line-height: 28px;
  }

  .m-b {
    margin-bottom: 4px;
  }

  .btn {
    width: 100%;
  }

  .preview-wrap {
    width: 100%;
    height: 100%;
    overflow: auto;
    user-select: none;
    position: relative;
  }

  .canvas-wrap {
    position: absolute;
    background-repeat: no-repeat;
    background-size: contain;
    background-color: #fff;
  }

  .canvas-wrap .mosaic-canvas {
    width: 100%;
    height: 100%;
  }

  .canvas-wrap .mosaic-box {
    position: absolute;
    cursor: move;
    height: auto;
  }

  .mosaic-box .box-line {
    position: absolute;
  }

  .mosaic-box .box-line.top {
    top: 0;
    /*padding-bottom: 5px;*/
    background: url(~@static/assets/images/border-h.gif) repeat-x top left;
  }

  .mosaic-box .box-line.bottom {
    bottom: 0;
    /*padding-top: 5px;*/
    background: url(~@static/assets/images/border-h.gif) repeat-x bottom left;
  }

  .mosaic-box .box-line.top,
  .mosaic-box .box-line.bottom {
    left: 0;
    right: 0;
    height: 8px;
    /*cursor: n-resize;*/
  }

  .mosaic-box .box-line.left {
    left: 0;
    /*padding-right: 5px;*/
    background: url(~@static/assets/images/border-v.gif) repeat-y top left;
  }

  .mosaic-box .box-line.right {
    right: 0;
    /*padding-left: 5px;*/
    background: url(~@static/assets/images/border-v.gif) repeat-y top right;
  }

  .mosaic-box .box-line.left,
  .mosaic-box .box-line.right {
    top: 0;
    bottom: 0;
    width: 8px;
    /*cursor: w-resize;*/
  }
</style>

<template>
  <cutting-container :loading="isLoading">
    <div class="cut-operate">
      <el-row class="operate-item">
        <el-col :span="24">马赛克设置：</el-col>
        <el-col :span="8" class="m-b line-height-28">操作区宽：</el-col>
        <el-col :span="16" class="m-b">
          <el-input-number size="mini" v-model="setting.width" :min="1" :max="widthMax" :step="1"></el-input-number>
        </el-col>

        <el-col :span="8" class="m-b line-height-28">操作区高：</el-col>
        <el-col :span="16" class="m-b">
          <el-input-number size="mini" v-model="setting.height" :min="1" :max="heightMax" :step="1"></el-input-number>
        </el-col>

        <el-col :span="8" class="m-b line-height-28">粒度因子：</el-col>
        <el-col :span="16" class="m-b">
          <el-input-number size="mini" v-model="setting.granularity" :min="1" :max="20" :step="1"></el-input-number>
        </el-col>
      </el-row>

      <el-row class="operate-item">
        <el-col :span="8" :offset="8">
          <el-button type="primary" class="btn" @click="handleConfirm" :loading="confirmLoading">应用</el-button>
        </el-col>
      </el-row>
    </div>
    <div class="preview-wrap" ref="previewWrap" slot="preview">
      <div class="canvas-wrap" :style="{
          top: previewImageTop + 'px',
          left: previewImageLeft + 'px',
          width: realWidth + 'px',
          height: realHeight + 'px'
      }">
        <canvas class="mosaic-canvas" ref="mosaicCanvas"></canvas>
      </div>

      <div class="canvas-wrap" :style="{
          top: previewImageTop + 'px',
          left: previewImageLeft + 'px',
          width: realWidth + 'px',
          height: realHeight + 'px',
          background: 'transparent'
      }" @mousemove="handleBoxMove" @mouseup="handleBoxEnd" @mouseleave="handleBoxEnd">
        <div class="mosaic-box"
             :style="{
               top: this.setting.top + 'px',
               left: this.setting.left + 'px',
               width: this.setting.width + 'px',
               height: this.setting.height + 'px'
             }" @mousedown.stop="e => handleBoxStart('move', e)">
          <div class="box-line top"></div>
          <div class="box-line left"></div>
          <div class="box-line right"></div>
          <div class="box-line bottom"></div>
        </div>
      </div>

    </div>
  </cutting-container>
</template>

<script>
import util from '@src/common/util.js'
import imageCuttingContainer from './imageCuttingContainer.vue'
import { imageLoad, cutBoxOperate, uploadBase64Image } from './imageCuttingUtil'

let operateInfo = {
  type: ''
}

export default {
  name: 'imageMosaic',
  components: {
    'cutting-container': imageCuttingContainer
  },
  props: {
    imagePath: {
      type: String,
      default: '',
      required: true
    },
    activeTab: {
      type: String,
      default: ''
    },
    siteID: {
      type: [String, Number],
      required: true
    },
    path: {
      type: String,
      default: '',
      required: true
    }
  },
  data () {
    return {
      isLoading: false,
      confirmLoading: false,
      realWidth: 0,
      realHeight: 0,
      previewWrap: {
        width: 0,
        height: 0
      },
      setting: {
        top: 0,
        left: 0,
        width: 50,
        height: 50,
        granularity: 5 // 马赛克的粒度
      }
    }
  },
  watch: {
    activeTab (val) {
      if (val === 'mosaic') {
        this.init()
      }
    }
  },
  computed: {
    widthMax () {
      return this.realWidth - this.setting.left
    },
    heightMax () {
      return this.realHeight - this.setting.top
    },
    previewImageTop () {
      if (this.realHeight >= this.previewWrap.height) return 0

      return (this.previewWrap.height - this.realHeight) / 2
    },
    previewImageLeft () {
      if (this.realWidth >= this.previewWrap.width) return 0

      return (this.previewWrap.width - this.realWidth) / 2
    }
  },
  methods: {
    async init () {
      this.confirmLoading = false
      this.isLoading = true
      let img
      try {
        img = await imageLoad(this.imagePath)
      } catch (e) {
        return
      }

      this.realWidth = img.width
      this.realHeight = img.height

      Object.assign(this.setting, {
        width: 50,
        height: 50,
        granularity: 5
      })

      Object.assign(this.previewWrap, {
        width: this.$refs['previewWrap'].offsetWidth,
        height: this.$refs['previewWrap'].offsetHeight
      })

      let canvas = this.$refs['mosaicCanvas']

      let ctx = canvas.getContext('2d')
      canvas.width = img.width
      canvas.height = img.height
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      ctx.drawImage(img, 0, 0, img.width, img.height)

      this.isLoading = false
    },
    handleBoxStart (type, e) {
      operateInfo = {
        type: type,
        startPosition: { x: e.pageX, y: e.pageY },
        originalCutBox: {
          top: this.setting.top,
          left: this.setting.left,
          width: this.setting.width,
          height: this.setting.height
        },
        container: {
          width: this.realWidth,
          height: this.realHeight
        }
      }
    },
    handleBoxMove (e) {
      if (!operateInfo.type || operateInfo.type !== 'move') {
        return
      }

      let box = cutBoxOperate(operateInfo, {
        pageX: e.pageX,
        pageY: e.pageY
      }, false, false)

      Object.assign(this.setting, box)
    },
    handleBoxEnd  () {
      operateInfo = {
        type: ''
      }
    },
    async handleConfirm () {
      function getXY (obj, x, y) {
        let w = obj.width; let color = []

        color[0] = obj.data[4 * (y * w + x)]
        color[1] = obj.data[4 * (y * w + x) + 1]
        color[2] = obj.data[4 * (y * w + x) + 2]
        color[3] = obj.data[4 * (y * w + x) + 3]

        return color
      }

      function setXY (obj, x, y, color) {
        let w = obj.width

        obj.data[4 * (y * w + x)] = color[0]
        obj.data[4 * (y * w + x) + 1] = color[1]
        obj.data[4 * (y * w + x) + 2] = color[2]
        obj.data[4 * (y * w + x) + 3] = color[3]
      }

      this.confirmLoading = true

      let canvas = this.$refs['mosaicCanvas']

      let ctx = canvas.getContext('2d')

      // 获取坐边图像的局部坐标的部分像素
      let oImg = ctx.getImageData(this.setting.left, this.setting.top, this.setting.width, this.setting.height)

      let w = oImg.width

      let h = oImg.height

      let num = this.setting.granularity

      let stepW = Math.ceil(w / num)
      // 等分画布

      let stepH = Math.ceil(h / num)
      // console.log(oImg)

      // 这里是循环画布的像素点
      for (let i = 0; i < stepH; i++) {
        for (let j = 0; j < stepW; j++) {
          // 获取一个小方格的随机颜色，这是小方格的随机位置获取的
          let color = getXY(oImg,
            j * num + Math.floor(Math.random() * num),
            i * num + Math.floor(Math.random() * num))
          // 这里是循环小方格的像素点，
          for (let k = 0; k < num; k++) {
            for (let l = 0; l < num; l++) {
              // 设置小方格的颜色
              setXY(oImg, j * num + l, i * num + k, color)
            }
          }
        }
      }

      ctx.putImageData(oImg, this.setting.left, this.setting.top)

      const newImg = canvas.toDataURL()

      const res = await uploadBase64Image(newImg, this.path, this.siteID)
      util.showResponseMessage(res.data)
      if (res.data.status === 1) {
        this.$emit('update:imagePath', res.data.previewPath)
        this.$emit('update:path', res.data.path)
      }

      this.confirmLoading = false
    }
  },
  created () {}
}
</script>
