<template>
  <div :class="['el-resize-box', {'el-resize-disabled': disabled}]" style="height: 200px">
    <!-- class="el-resize-line el-resize-border_top" -->
    <div
        v-if="move.top"
        :class="['el-resize-line',border==='fill'?'el-resize-border_top-rect':'el-resize-border_top-line']"
        data-type="top"
        @mousedown.prevent="mousedownHanlder"
    >
      <img :src="require('examples/assets/images/resize.svg')" v-if="border==='fill'" class="el-resize-icon"/>
      <div v-else class="el-resize-border-line"/>
    </div>
    <div
        v-if="move.left"
        :class="['el-resize-line',border==='fill'?'el-resize-border_left-rect':'el-resize-border_left-line']"
        data-type="left"
        @mousedown.prevent="mousedownHanlder"
    >
      <img :src="require('examples/assets/images/resize.svg')" v-if="border==='fill'" class="el-resize-icon"/>
      <div v-else class="el-resize-border-line"/>
    </div>
    <div
        v-if="move.right"
        :class="['el-resize-line',border==='fill'?'el-resize-border_right-rect':'el-resize-border_right-line']"
        data-type="right"
        @mousedown.prevent="mousedownHanlder"
    >
      <img :src="require('examples/assets/images/resize.svg')" v-if="border==='fill'" class="el-resize-icon"/>
      <div v-else class="el-resize-border-line"/>
    </div>
    <!-- class="el-resize-line el-resize-border_bottom" -->
    <div
        v-if="move.bottom"
        :class="['el-resize-line',border==='fill'?'el-resize-border_bottom-rect':'el-resize-border_bottom-line']"
        data-type="bottom"
        @mousedown.prevent="mousedownHanlder"
    >
      <img :src="require('examples/assets/images/resize.svg')" v-if="border==='fill'" class="el-resize-icon"/>
      <div v-else class="el-resize-border-line"/>
    </div>
    <slot/>
  </div>
</template>

<script>
export default {
  name: 'ElResizeBox',
  props: {
    max: {
      type: Object,
      default: function () {
        return {
          width: 0,
          height: 0
        }
      },
      validator: function (obj) {
        if (typeof obj.width === 'number' || typeof obj.height === 'number') {
          if (obj.width >= 0 && obj.height >= 0) {
            return true
          } else {
            return false
          }
        } else {
          return false
        }
      }
    },
    min: {
      type: Object,
      default: () => {
        return {
          width: 39,
          height: 13
        }
      },
      validator: function (obj) {
        if (typeof obj.width === 'number' || typeof obj.height === 'number') {
          if (obj.width >= 0 && obj.height >= 0) {
            return true
          } else {
            return false
          }
        } else {
          return false
        }
      }
    },
    border: {
      type: String,
      default: 'fill'
    },
    move: {
      type: Object,
      default: () => {
        return {
          top: true,
          left: true,
          right: true,
          bottom: true
        }
      },
      validator: function (obj) {
        if (
            typeof obj.top === 'boolean'
            || typeof obj.left === 'boolean'
            || typeof obj.right === 'boolean'
            || typeof obj.bottom === 'boolean'
        ) {
          return true
        } else {
          return false
        }
      }
    },
    speed: {
      type: Number,
      default: 2,
      validator: function (num) {
        return num >= 1
      }
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  created() {
    document.body.addEventListener('mouseup', this.mouseupHanlder)
  },
  destroyed() {
    document.body.removeEventListener('mouseup', this.mouseupHanlder)
  },
  methods: {
    getStyle(element) {
      if (element.currentStyle) {
        return element.currentStyle
      } else {
        return getComputedStyle(element, false)
      }
    },
    mousedownHanlder(event) {
      let {cursor} = this.getStyle(event.target)
      this.dataType = event.target.parentElement.getAttribute('data-type') || event.target.getAttribute('data-type')
      this.event = event
      document.body.addEventListener('mousemove', this.mousemoveHandler)
      document.body.style.cursor = cursor
    },
    mouseupHanlder() {
      document.body.removeEventListener('mousemove', this.mousemoveHandler)
      document.body.style.cursor = 'default'
    },
    mousemoveHandler(event) {
      if (this.disabled) {
        return
      }
      let {width, height} = this.getStyle(this.$el)
      width = parseInt(width)
      height = parseInt(height)
      this[this.dataType]({event, width, height})
      this.event = event
    },
    top({event, height}) {
      if (event.y > this.event.y) {
        const ht = this.min.height
            ? Math.max(this.min.height, height - (event.pageY - this.event.y) * this.speed)
            : height - (event.y - this.event.y) * this.speed
        this.$el.style.height = ht < this.min.height ? `${this.min.height}px` : `${ht}px`
      } else {
        this.$el.style.height = this.max.height
            ? `${Math.min(this.max.height, height + (this.event.y - event.y) * this.speed)}px`
            : `${height + (this.event.y - event.y) * this.speed}px`
      }
    },
    left({event, width}) {
      if (event.x > this.event.x) {
        this.$el.style.width = this.min.width
            ? `${Math.max(this.min.width, width - (event.x - this.event.x) * this.speed)}px`
            : `${width - (event.x - this.event.x) * this.speed}px`
      } else {
        this.$el.style.width = this.max.width
            ? `${Math.min(this.max.width, width + (this.event.x - event.x) * this.speed)}px`
            : `${width + (this.event.x - event.x) * this.speed}px`
      }
    },
    right({event, width}) {
      if (event.x > this.event.x) {
        this.$el.style.width = this.max.width
            ? `${Math.min(this.max.width, width + (event.x - this.event.x) * this.speed)}px`
            : `${width + (event.x - this.event.x) * this.speed}px`
      } else {
        this.$el.style.width = this.min.width
            ? `${Math.max(this.min.width, width - (this.event.x - event.x) * this.speed)}px`
            : `${width - (this.event.x - event.x) * this.speed}px`
      }
    },
    bottom({event, height}) {
      if (event.y > this.event.y) {
        this.$el.style.height = this.max.height
            ? `${Math.min(this.max.height, height + (event.y - this.event.y) * this.speed)}px`
            : `${height + (event.y - this.event.y) * this.speed}px`
      } else {
        this.$el.style.height = this.min.height
            ? `${Math.max(this.min.height, height - (this.event.y - event.y) * this.speed)}px`
            : `${height - (this.event.y - event.y) * this.speed}px`
      }
    }
  }
}
</script>
