<template>
  <div ref="item" class="vue-grid-item" :class="classObj" :style="style">
    <slot></slot>
    <span v-if="resizableAndNotStatic" ref="handle" :class="resizableHandleClass"></span>
    <!--<span v-if="draggable" ref="dragHandle" class="vue-draggable-handle"></span>-->
  </div>
</template>

<script>
import {
  setTopLeft,
  setTopRight,
  setTransformRtl,
  setTransform
} from '../helpers/utils'
import { getControlPosition, createCoreData } from '../helpers/draggableUtils'
import { getDocumentDir } from '../helpers/DOM'
//    var eventBus = require('./eventBus');

let interact = require('interactjs')

export default {
  name: 'GridItem',
  props: {
    /*cols: {
             type: Number,
             required: true
             },*/
    /*containerWidth: {
             type: Number,
             required: true

             },
             rowHeight: {
             type: Number,
             required: true
             },
             margin: {
             type: Array,
             required: true
             },
             maxRows: {
             type: Number,
             required: true
             },*/
    isDraggable: {
      type: Boolean,
      required: false,
      default: null
    },
    isResizable: {
      type: Boolean,
      required: false,
      default: null
    },
    /*useCssTransforms: {
             type: Boolean,
             required: true
             },
             */
    static: {
      type: Boolean,
      required: false,
      default: false
    },
    minH: {
      type: Number,
      required: false,
      default: 1
    },
    minW: {
      type: Number,
      required: false,
      default: 1
    },
    maxH: {
      type: Number,
      required: false,
      default: Infinity
    },
    maxW: {
      type: Number,
      required: false,
      default: Infinity
    },
    x: {
      type: Number,
      required: true
    },
    y: {
      type: Number,
      required: true
    },
    w: {
      type: Number,
      required: true
    },
    h: {
      type: Number,
      required: true
    },
    i: {
      required: true
    },
    dragIgnoreFrom: {
      type: String,
      required: false,
      default: 'a, button'
    },
    dragAllowFrom: {
      type: String,
      required: false,
      default: null
    },
    resizeIgnoreFrom: {
      type: String,
      required: false,
      default: 'a, button'
    },
    type: {
      type: String
    },
    isFullHeight: {
      type: Boolean,
      default: false
    },
    isHeightFit: {
      //是否高度适配
      type: Boolean,
      default: true
    },
    HPosition: {
      type: [Boolean, String],
      default: false
    },
    isNoTop: {
      // 不置顶
      type: Boolean,
      default: false
    },
    formId: {
      // 真实环境下
      type: String,
      default: ''
    }
  },
  inject: ['eventBus'],
  data: function() {
    return {
      cols: 1,
      containerWidth: 100,
      containerHeight: 100,
      rowHeight: 30,
      margin: [10, 10],
      maxRows: Infinity,
      draggable: null,
      resizable: null,
      useCssTransforms: true,
      isDragging: false,
      dragging: null,
      isResizing: false,
      resizing: null,
      lastX: NaN,
      lastY: NaN,
      lastW: NaN,
      lastH: NaN,
      style: {},
      rtl: false,

      dragEventSet: false,
      resizeEventSet: false,

      previousW: null,
      previousH: null,
      previousX: null,
      previousY: null,
      innerX: this.x,
      innerY: this.y,
      innerW: this.w,
      innerH: this.h
    }
  },
  created() {
    let self = this

    // Accessible refernces of functions for removing in beforeDestroy
    self.updateWidthHandler = function(width) {
      self.updateWidth(width)
    }
    self.updateHeightHandler = function(height) {
      self.updateHeight(height)
    }
    self.compactHandler = function(layout) {
      self.compact(layout)
    }

    self.setDraggableHandler = function(isDraggable) {
      if (self.isDraggable === null) {
        self.draggable = isDraggable
      }
    }

    self.setResizableHandler = function(isResizable) {
      if (self.isResizable === null) {
        self.resizable = isResizable
      }
    }

    self.setRowHeightHandler = function(rowHeight) {
      self.rowHeight = rowHeight
    }

    self.setMaxRowsHandler = function(maxRows) {
      self.maxRows = maxRows
    }
    self.directionchangeHandler = () => {
      this.rtl = getDocumentDir() === 'rtl'
      this.compact()
    }

    self.setColNum = colNum => {
      self.cols = parseInt(colNum)
    }

    this.eventBus.$on('updateWidth', self.updateWidthHandler)
    if (this.i !== -1) {
      this.eventBus.$on('updateHeight' + this.formId, self.updateHeightHandler)
    }
    this.eventBus.$on('compact', self.compactHandler)
    this.eventBus.$on('setDraggable', self.setDraggableHandler)
    this.eventBus.$on('setResizable', self.setResizableHandler)
    this.eventBus.$on('setRowHeight', self.setRowHeightHandler)
    this.eventBus.$on('setMaxRows', self.setMaxRowsHandler)
    this.eventBus.$on('directionchange', self.directionchangeHandler)
    this.eventBus.$on('setColNum', self.setColNum)

    // this.$eventBus.$on('changeOldHY', self.changeOldHY)
    this.rtl = getDocumentDir() === 'rtl'
  },
  beforeDestroy: function() {
    let self = this
    //Remove listeners
    // this.$eventBus.$off('changeOldHY', self.changeOldHY)
    this.eventBus.$off('updateWidth', self.updateWidthHandler)
    this.eventBus.$off('updateHeight', self.updateHeightHandler)
    this.eventBus.$off('compact', self.compactHandler)
    this.eventBus.$off('setDraggable', self.setDraggableHandler)
    this.eventBus.$off('setResizable', self.setResizableHandler)
    this.eventBus.$off('setRowHeight', self.setRowHeightHandler)
    this.eventBus.$off('setMaxRows', self.setMaxRowsHandler)
    this.eventBus.$off('directionchange', self.directionchangeHandler)
    this.eventBus.$off('setColNum', self.setColNum)
    if (this.interactObj) {
      this.interactObj.unset() // destroy interact intance
    }
  },
  mounted: function() {
    this.cols = this.$parent.colNum
    this.rowHeight = this.$parent.rowHeight
    this.containerWidth = this.$parent.width ? this.$parent.width : 100
    // this.containerHeight = this.$parent.height ? this.$parent.height : 100
    this.containerHeight = this.$parent.$el.offsetHeight
    this.margin =
      this.$parent.margin !== undefined ? this.$parent.margin : [10, 10]
    this.maxRows = this.$parent.maxRows
    if (this.isDraggable === null) {
      this.draggable = this.$parent.isDraggable
    } else {
      this.draggable = this.isDraggable
    }
    if (this.isResizable === null) {
      this.resizable = this.$parent.isResizable
    } else {
      this.resizable = this.isResizable
    }
    this.useCssTransforms = this.$parent.useCssTransforms
    if (!this.isHeightFit) {
      this.changeOldHY() // 改变旧版HY
    }
    this.createStyle()
    this.$emit('item-mounted', this.i)
  },
  watch: {
    isFullHeight: {
      handler(n) {
        this.createStyle()
        this.emitContainerResized()
      }
    },
    // isHeightFit: {
    //   handler(n) {
    //     console.log('nnnnn', n)
    //     if (!n) {
    //       this.changeOldHY()
    //     }
    //   }
    // },
    HPosition: {
      // 高度类型
      handler(n) {
        if (n == '01') {
          n = true
        }
        this.changeHPosition()
        this.createStyle()
        // this.eventBus.$emit(
        //   'dragEvent',
        //   'dragend',
        //   this.i,
        //   this.x,
        //   1,
        //   10,
        //   this.w
        // )
      }
    },
    isDraggable: function() {
      this.draggable = this.isDraggable
    },
    static: function() {
      this.tryMakeDraggable()
      this.tryMakeResizable()
    },
    draggable: function() {
      this.tryMakeDraggable()
    },
    isResizable: function() {
      this.resizable = this.isResizable
    },
    resizable: function() {
      this.tryMakeResizable()
    },
    rowHeight: function() {
      this.createStyle()
      this.emitContainerResized()
    },
    cols: function() {
      this.tryMakeResizable()
      this.createStyle()
      this.emitContainerResized()
    },
    containerWidth: function() {
      this.tryMakeResizable()
      this.createStyle()
      this.emitContainerResized()
      // 父宽度变化
      this.$emit('containerWidthUpdated', this.i)
    },
    containerHeight: function() {
      this.tryMakeResizable()
      this.createStyle()
      this.emitContainerResized()
    },
    x: function(newVal) {
      this.innerX = newVal
      this.createStyle()
    },
    y: function(newVal) {
      this.innerY = newVal
      this.createStyle()
    },
    h: function(newVal) {
      this.innerH = newVal
      this.createStyle()
    },
    w: function(newVal) {
      this.innerW = newVal
      this.createStyle()
    },
    renderRtl: function() {
      this.tryMakeResizable()
      this.createStyle()
    },
    minH: function() {
      this.tryMakeResizable()
    },
    maxH: function() {
      this.tryMakeResizable()
    },
    minW: function() {
      this.tryMakeResizable()
    },
    maxW: function() {
      this.tryMakeResizable()
    },
    '$parent.margin': function(margin) {
      if (
        !margin ||
        (margin[0] == this.margin[0] && margin[1] == this.margin[1])
      ) {
        return
      }
      this.margin = margin.map(m => Number(m))
      this.createStyle()
      this.emitContainerResized()
    }
  },
  computed: {
    classObj() {
      return {
        'vue-resizable': this.resizableAndNotStatic,
        static: this.static,
        resizing: this.isResizing,
        'vue-draggable-dragging': this.isDragging,
        cssTransforms: this.useCssTransforms,
        'render-rtl': this.renderRtl,
        'disable-userselect': this.isDragging,
        'no-touch': this.isAndroid && this.draggableOrResizableAndNotStatic
      }
    },
    resizableAndNotStatic() {
      return this.resizable && !this.static
    },
    draggableOrResizableAndNotStatic() {
      return (this.draggable || this.resizable) && !this.static
    },
    isAndroid() {
      return navigator.userAgent.toLowerCase().indexOf('android') !== -1
    },
    renderRtl() {
      return this.$parent.isMirrored ? !this.rtl : this.rtl
    },
    resizableHandleClass() {
      if (this.renderRtl) {
        return 'vue-resizable-handle vue-rtl-resizable-handle'
      } else {
        return 'vue-resizable-handle'
      }
    }
  },
  methods: {
    createStyle: function() {
      if (this.x + this.w > this.cols) {
        this.innerX = 0
        this.innerW = this.w > this.cols ? this.cols : this.w
      } else {
        this.innerX = this.x
        this.innerW = this.w
      }
      let pos = this.calcPosition(
        this.innerX,
        this.innerY,
        this.innerW,
        this.innerH
      )
      if (this.isDragging) {
        pos.top = this.dragging.top
        //                    Add rtl support
        if (this.renderRtl) {
          pos.right = this.dragging.left
        } else {
          pos.left = this.dragging.left
        }
      }
      if (this.isResizing) {
        pos.width = this.resizing.width
        pos.height = this.resizing.height
      }
      let style
      // CSS Transforms support (default)
      if (this.useCssTransforms) {
        //                    Add rtl support
        if (this.renderRtl) {
          style = setTransformRtl(pos.top, pos.right, pos.width, pos.height)
        } else {
          style = setTransform(pos.top, pos.left, pos.width, pos.height)
        }
      } else {
        // top,left (slow)
        //                    Add rtl support
        if (this.renderRtl) {
          style = setTopRight(pos.top, pos.right, pos.width, pos.height)
        } else {
          style = setTopLeft(pos.top, pos.left, pos.width, pos.height)
        }
      }
      if (!this.draggable && this.isFullHeight) {
        //置顶
        style.height = 'calc(100% - ' + pos.top + 'px)'
      }
      // 满屏情况下
      if (!this.draggable && this.cols == this.w && this.type != 'filter') {
        style.width = 'calc(100% - ' + this.margin[0] * 2 + 'px)'
      }
      // 筛选器，置顶
      if (!this.draggable && this.type == 'filter' && !this.isNoTop) {
        let fixedMarginLeft = this.$parent.$el.getBoundingClientRect().left
        // fix固定的处理
        if (this.formId) {
          // 真实情况下,非预览
          // if(this.cols == this.w)style.width = 'calc(100% - ' + (fixedMarginLeft + 20 + 10) + 'px)'
          style.marginLeft = fixedMarginLeft + 'px'
        }
      }

      this.style = style
    },
    // 切换绝对和相对高度
    changeHPosition(n, o) {
      // if (n) {
      //   // 绝对
      //   this.innerH = this.HRelativeToPositionH(this.innerH)
      // } else {
      //   this.innerH = this.$parent.HPositionToRelativeH(this.innerH)
      // }
      // this.eventBus.$emit(
      //   'dragEvent',
      //   'dragend',
      //   this.i,
      //   this.innerX,
      //   this.innerY,
      //   this.innerH,
      //   this.innerW
      // )
    },
    // 相对定位高度转成绝对定位高度
    HRelativeToPositionH(h) {
      const scaleHeight = this.calcScaleHeight(colWidth)
      let height = Math.round(
        scaleHeight * h + Math.max(0, h - 1) * this.margin[0]
      )
      h = Math.round((height + this.margin[0]) / (10 + this.margin[0]))
      return h
    },
    // 改变旧高度的HY
    changeOldHY(isHeightFit) {
      if (isHeightFit) {
        return
      }
      if (this.x + this.w > this.cols) {
        this.innerX = 0
        this.innerW = this.w > this.cols ? this.cols : this.w
      } else {
        this.innerX = this.x
        this.innerW = this.w
      }
      let pos = this.calcPosition(
        this.innerX,
        this.innerY,
        this.innerW,
        this.innerH,
        10
      )
      let posWH = this.calcWH(pos.height, pos.width)
      let posXY = this.calcXY(pos.top, pos.left)
      this.$parent.changeYH(
        'dragend',
        this.i,
        posXY.x,
        posXY.y,
        posWH.h,
        posWH.w
      )
      // this.$emit('moved', this.i, posXY.x, posXY.y)
    },

    emitContainerResized() {
      let styleProps = {}
      for (let prop of ['width', 'height']) {
        let val = this.style[prop]
        let matches = val.match(/^(\d+)px$/)
        if (!matches) return
        styleProps[prop] = matches[1]
      }
      this.$emit(
        'container-resized',
        this.i,
        this.h,
        this.w,
        styleProps.height,
        styleProps.width
      )
    },
    handleResize: function(event) {
      if (this.static) return
      const position = getControlPosition(event)
      // Get the current drag point from the event. This is used as the offset.
      if (position == null) return // not possible but satisfies flow
      const { x, y } = position

      const newSize = { width: 0, height: 0 }
      let pos
      switch (event.type) {
        case 'resizestart': {
          this.previousW = this.innerW
          this.previousH = this.innerH
          pos = this.calcPosition(
            this.innerX,
            this.innerY,
            this.innerW,
            this.innerH
          )
          newSize.width = pos.width
          newSize.height = pos.height
          this.resizing = newSize
          this.isResizing = true
          break
        }
        case 'resizemove': {
          const coreEvent = createCoreData(this.lastW, this.lastH, x, y)
          if (this.renderRtl) {
            newSize.width = this.resizing.width - coreEvent.deltaX
          } else {
            newSize.width = this.resizing.width + coreEvent.deltaX
          }
          newSize.height = this.resizing.height + coreEvent.deltaY

          this.resizing = newSize
          break
        }
        case 'resizeend': {
          pos = this.calcPosition(
            this.innerX,
            this.innerY,
            this.innerW,
            this.innerH
          )
          newSize.width = pos.width
          newSize.height = pos.height
          this.resizing = null
          this.isResizing = false
          break
        }
      }

      // Get new WH
      pos = this.calcWH(newSize.height, newSize.width)
      if (pos.w < this.minW) {
        pos.w = this.minW
      }
      if (pos.w > this.maxW) {
        pos.w = this.maxW
      }
      if (pos.h < this.minH) {
        pos.h = this.minH
      }
      if (pos.h > this.maxH) {
        pos.h = this.maxH
      }

      if (pos.h < 1) {
        pos.h = 1
      }
      if (pos.w < 1) {
        pos.w = 1
      }

      this.lastW = x
      this.lastH = y

      if (this.innerW !== pos.w || this.innerH !== pos.h) {
        this.$emit(
          'resize',
          this.i,
          pos.h,
          pos.w,
          newSize.height,
          newSize.width
        )
      }
      if (
        event.type === 'resizeend' &&
        (this.previousW !== this.innerW || this.previousH !== this.innerH)
      ) {
        this.$emit(
          'resized',
          this.i,
          pos.h,
          pos.w,
          newSize.height,
          newSize.width
        )
      }
      this.eventBus.$emit(
        'resizeEvent',
        event.type,
        this.i,
        this.innerX,
        this.innerY,
        pos.h,
        pos.w
      )
    },
    handleDrag(event) {
      if (this.static) return
      if (this.isResizing) return

      const position = getControlPosition(event)

      // Get the current drag point from the event. This is used as the offset.
      if (position === null) return // not possible but satisfies flow
      const { x, y } = position

      // let shouldUpdate = false;
      let newPosition = { top: 0, left: 0 }
      switch (event.type) {
        case 'dragstart': {
          this.previousX = this.innerX
          this.previousY = this.innerY
          let parentRect = event.target.offsetParent.getBoundingClientRect()
          let clientRect = event.target.getBoundingClientRect()
          if (this.renderRtl) {
            newPosition.left = (clientRect.right - parentRect.right) * -1
          } else {
            newPosition.left = clientRect.left - parentRect.left
          }
          newPosition.top = clientRect.top - parentRect.top
          this.dragging = newPosition
          this.isDragging = true
          break
        }
        case 'dragend': {
          if (!this.isDragging) return
          let parentRect = event.target.offsetParent.getBoundingClientRect()
          let clientRect = event.target.getBoundingClientRect()
          //                        Add rtl support
          if (this.renderRtl) {
            newPosition.left = (clientRect.right - parentRect.right) * -1
          } else {
            newPosition.left = clientRect.left - parentRect.left
          }
          newPosition.top = clientRect.top - parentRect.top
          this.dragging = null
          this.isDragging = false
          break
        }
        case 'dragmove': {
          const coreEvent = createCoreData(this.lastX, this.lastY, x, y)
          if (this.renderRtl) {
            newPosition.left = this.dragging.left - coreEvent.deltaX
          } else {
            newPosition.left = this.dragging.left + coreEvent.deltaX
          }
          newPosition.top = this.dragging.top + coreEvent.deltaY
          this.dragging = newPosition
          break
        }
      }
      let pos = this.calcXY(newPosition.top, newPosition.left)

      this.lastX = x
      this.lastY = y
      if (this.innerX !== pos.x || this.innerY !== pos.y) {
        this.$emit('move', this.i, pos.x, pos.y)
      }
      if (
        event.type === 'dragend' &&
        (this.previousX !== this.innerX || this.previousY !== this.innerY)
      ) {
        this.$emit('moved', this.i, pos.x, pos.y)
      }
      this.eventBus.$emit(
        'dragEvent',
        event.type,
        this.i,
        pos.x,
        pos.y,
        this.innerH,
        this.innerW
      )
    },
    calcPosition: function(x, y, w, h, key) {
      const colWidth = this.calcColWidth()
      const scaleHeight = key || this.calcScaleHeight(colWidth)
      let out
      if (this.renderRtl) {
        out = {
          right: Math.round(colWidth * x + (x + 1) * this.margin[0]),
          top: Math.round(scaleHeight * y + (y + 1) * this.margin[0]),
          width:
            w === Infinity
              ? w
              : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),
          height:
            h === Infinity
              ? h
              : Math.round(
                  (this.HPosition ? 10 : scaleHeight) * h +
                    Math.max(0, h - 1) * this.margin[1]
                )
        }
      } else {
        out = {
          left: Math.round(colWidth * x + (x + 1) * this.margin[0]),
          top: Math.round(scaleHeight * y + (y + 1) * this.margin[0]),
          width:
            w === Infinity
              ? w
              : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),
          height:
            h === Infinity
              ? h
              : Math.round(
                  (this.HPosition ? 10 : scaleHeight) * h +
                    Math.max(0, h - 1) * this.margin[0]
                )
        }
      }

      return out
    },
    /**
     * Translate x and y coordinates from pixels to grid units.
     * @param  {Number} top  Top position (relative to parent) in pixels.
     * @param  {Number} left Left position (relative to parent) in pixels.
     * @return {Object} x and y in grid units.
     */
    // TODO check if this function needs change in order to support rtl.
    calcXY(top, left) {
      const colWidth = this.calcColWidth()
      const scaleHeight = this.calcScaleHeight(colWidth)
      let x = Math.round((left - this.margin[0]) / (colWidth + this.margin[0]))
      let y = Math.round(
        (top - this.margin[0]) /
          ((this.HPosition ? 10 : scaleHeight) + this.margin[0])
      )
      x = Math.max(Math.min(x, this.cols - this.innerW), 0)
      y = Math.max(Math.min(y, this.maxRows - this.innerH), 0)
      return { x, y }
    },
    calcColWidth() {
      const colWidth =
        (this.containerWidth - this.margin[0] * (this.cols + 1)) / this.cols
      return colWidth
    },
    calcScaleHeight(colWidth) {
      // this.containerWidth/this.containerHeight=colWidth/？

      const scaleHeight =
        (this.containerHeight - this.margin[0] * (100 + 1)) / 100 // 比例
      // const scaleHeight = this.containerHeight*colWidth/this.containerWidth
      return scaleHeight
      // const colWidth =
      //   (this.containerWidth - this.margin[0] * (this.cols + 1)) / this.cols
      // return colWidth
    },
    calcWH(height, width) {
      const colWidth = this.calcColWidth()
      const scaleHeight = this.HPosition ? 10 : this.calcScaleHeight(colWidth)
      let w = Math.round((width + this.margin[0]) / (colWidth + this.margin[0]))
      let h = Math.round(
        (height + this.margin[0]) / (scaleHeight + this.margin[0])
      )
      w = Math.max(Math.min(w, this.cols - this.innerX), 0)
      h = Math.max(Math.min(h, this.maxRows - this.innerY), 0)
      return { w, h }
    },
    updateWidth: function(width, colNum) {
      this.containerWidth = width
      if (colNum !== undefined && colNum !== null) {
        this.cols = colNum
      }
    },
    updateHeight: function(height) {
      // 监听高度变化
      // if (!this.static) {
      this.containerHeight = height
      // }
    },
    compact: function() {
      this.createStyle()
    },
    tryMakeDraggable: function() {
      const self = this
      if (this.interactObj === null || this.interactObj === undefined) {
        this.interactObj = interact(this.$refs.item)
      }
      if (this.draggable && !this.static) {
        const opts = {
          ignoreFrom: this.dragIgnoreFrom,
          allowFrom: this.dragAllowFrom
        }
        this.interactObj.draggable(opts)
        if (!this.dragEventSet) {
          this.dragEventSet = true
          this.interactObj.on('dragstart dragmove dragend', function(event) {
            self.handleDrag(event)
          })
        }
      } else {
        this.interactObj.draggable({
          enabled: false
        })
      }
    },
    tryMakeResizable: function() {
      const self = this
      if (this.interactObj === null || this.interactObj === undefined) {
        this.interactObj = interact(this.$refs.item)
      }
      if (this.resizable && !this.static) {
        let maximum = this.calcPosition(0, 0, this.maxW, this.maxH)
        let minimum = this.calcPosition(0, 0, this.minW, this.minH)
        const opts = {
          preserveAspectRatio: true,
          edges: {
            left: false,
            right: '.' + this.resizableHandleClass,
            bottom: '.' + this.resizableHandleClass,
            top: false
          },
          ignoreFrom: this.resizeIgnoreFrom,
          restrictSize: {
            min: {
              height: minimum.height,
              width: minimum.width
            },
            max: {
              height: maximum.height,
              width: maximum.width
            }
          }
        }

        this.interactObj.resizable(opts)
        if (!this.resizeEventSet) {
          this.resizeEventSet = true
          this.interactObj.on('resizestart resizemove resizeend', function(
            event
          ) {
            self.handleResize(event)
          })
        }
      } else {
        this.interactObj.resizable({
          enabled: false
        })
      }
    },
    autoSize: function() {
      this.previousW = this.innerW
      this.previousH = this.innerH

      let newSize = this.$slots.default[0].elm.getBoundingClientRect()
      let pos = this.calcWH(newSize.height, newSize.width)
      if (pos.w < this.minW) {
        pos.w = this.minW
      }
      if (pos.w > this.maxW) {
        pos.w = this.maxW
      }
      if (pos.h < this.minH) {
        pos.h = this.minH
      }
      if (pos.h > this.maxH) {
        pos.h = this.maxH
      }

      if (pos.h < 1) {
        pos.h = 1
      }
      if (pos.w < 1) {
        pos.w = 1
      }
      if (this.innerW !== pos.w || this.innerH !== pos.h) {
        this.$emit(
          'resize',
          this.i,
          pos.h,
          pos.w,
          newSize.height,
          newSize.width
        )
      }
      if (this.previousW !== pos.w || this.previousH !== pos.h) {
        this.$emit(
          'resized',
          this.i,
          pos.h,
          pos.w,
          newSize.height,
          newSize.width
        )
        this.eventBus.$emit(
          'resizeEvent',
          'resizeend',
          this.i,
          this.innerX,
          this.innerY,
          pos.h,
          pos.w
        )
      }
    }
  }
}
</script>
<style lang="scss" >
.vue-grid-item {
  touch-action: none;
  transition: all 200ms ease;
  transition-property: left, top, right;
  box-sizing: border-box;
  /* add right for rtl */
}

.vue-grid-item.no-touch {
  -ms-touch-action: none;
  touch-action: none;
}

.vue-grid-item.cssTransforms {
  transition-property: transform;
  left: 0;
  right: auto;
}

.vue-grid-item.cssTransforms.render-rtl {
  left: auto;
  right: 0;
}

.vue-grid-item.resizing {
  opacity: 0.6;
  z-index: 3;
}

.vue-grid-item.vue-draggable-dragging {
  transition: none;
  z-index: 3;
}

.vue-grid-item.vue-grid-placeholder {
  background: red;
  opacity: 0.2;
  transition-duration: 100ms;
  z-index: 2;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.vue-grid-item > .vue-resizable-handle {
  position: absolute;
  width: 20px;
  height: 20px;
  bottom: 0;
  right: 0;
  background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');
  background-position: bottom right;
  padding: 0 3px 3px 0;
  background-repeat: no-repeat;
  background-origin: content-box;
  box-sizing: border-box;
  cursor: se-resize;
  z-index: 4;
}

.vue-grid-item > .vue-rtl-resizable-handle {
  bottom: 0;
  left: 0;
  background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);
  background-position: bottom left;
  padding-left: 3px;
  background-repeat: no-repeat;
  background-origin: content-box;
  cursor: sw-resize;
  right: auto;
}

.vue-grid-item.disable-userselect {
  user-select: none;
}
</style>