<template>
  <div :class="$options.name" :disabled="disabled" draggable="false">
    <div :class="`resize-handle resize-${a}`" draggable="false" @mousedown.stop="clickResizeHandle(a)"
         @dblclick="dblclickResizeHandle(a, $event)" v-for="(a, i) in sizeIndexs" :key="i"></div>
  </div>
</template>
<script>
export default {
  name: 'sgDragSize',
  data() {
    return {
      tbHeight: 0,
      dragSizeIndex: '',
      originRect: {},
      dblclickOriginRect: {},
      sizeIndexs: [
        'top',
        'right',
        'bottom',
        'left',
        'top-left',
        'top-right',
        'bottom-left',
        'bottom-right',
      ],
    }
  },
  props: [
    "disabled",//屏蔽
    "taskbarHeight",//任务栏高度
    "minWidth",//拖拽的最小宽度
    "minHeight",//拖拽的最小高度
    "maxWidth",//拖拽的最大宽度
    "maxHeight",//拖拽的最大高度
  ],
  watch: {
    disabled: {
      handler(newValue, oldValue) {
        newValue && this.__removeWindowEvents();
      }, deep: true, immediate: true,
    },
    taskbarHeight: {
      handler(d) {
        this.tbHeight = d || 0;
      }, deep: true, immediate: true,
    },
  },
  destroyed() {
    this.__removeWindowEvents();
  },
  methods: {
    view_innerHeight() {
      return innerHeight - this.tbHeight;
    },
    clickResizeHandle(d) {
      this.dragSizeIndex = d;
      this.mousedown(d);
    },
    dblclickResizeHandle(d, $event) {
      let rect = this.$el.getBoundingClientRect();
      rect.width < innerWidth && rect.height < this.view_innerHeight() && (this.dblclickOriginRect = rect);
      this.dblResize(d, rect, $event);
    },
    __addWindowEvents() {
      this.__removeWindowEvents();
      addEventListener('mousemove', this.mousemove_window);
      addEventListener('mouseup', this.mouseup_window);
    },
    __removeWindowEvents() {
      removeEventListener('mousemove', this.mousemove_window);
      removeEventListener('mouseup', this.mouseup_window);
    },
    mousedown(e) {
      this.originRect = this.$el.getBoundingClientRect();
      this.originRect.bottomRightX = this.originRect.x + this.originRect.width;//右下角坐标.x
      this.originRect.bottomRightY = this.originRect.y + this.originRect.height;//右下角坐标.y
      this.$emit('dragStart', e);
      this.__addWindowEvents();
    },
    mousemove_window(e) {
      let { x, y } = e;
      let minWidth = this.minWidth || 50, minHeight = this.minHeight || 50, maxWidth = this.maxWidth || innerWidth, maxHeight = this.maxHeight || innerHeight;
      x < 0 && (x = 0), y < 0 && (y = 0), x > innerWidth && (x = innerWidth), y > this.view_innerHeight() && (y = this.view_innerHeight());
      let style = {};
      switch (this.dragSizeIndex) {
        case 'top-left':
          style.left = x;
          style.top = y;
          style.width = this.originRect.bottomRightX - x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
          style.height = this.originRect.bottomRightY - y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
          break;
        case 'top':
          style.left = this.originRect.x;
          style.top = y;
          style.width = this.originRect.width;
          style.height = this.originRect.bottomRightY - y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
          break;
        case 'top-right':
          style.left = this.originRect.x;
          style.top = y;
          style.width = x - this.originRect.x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
          style.height = this.originRect.bottomRightY - y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
          break;
        case 'left':
          style.left = x;
          style.top = this.originRect.y;
          style.width = this.originRect.bottomRightX - x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
          style.height = this.originRect.height;
          break;
        case 'right':
          style.left = this.originRect.x;
          style.top = this.originRect.y;
          style.width = x - this.originRect.x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
          style.height = this.originRect.height;
          break;
        case 'bottom-left':
          style.left = x;
          style.top = this.originRect.y;
          style.width = this.originRect.bottomRightX - x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
          style.height = y - this.originRect.y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
          break;
        case 'bottom':
          style.left = this.originRect.x;
          style.top = this.originRect.y;
          style.width = this.originRect.width;
          style.height = y - this.originRect.y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
          break;
        case 'bottom-right':
          style.left = this.originRect.x;
          style.top = this.originRect.y;
          style.width = x - this.originRect.x;
          style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
          style.height = y - this.originRect.y;
          style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
          break;
        default:
      }
      style.width > maxWidth && (style.width = maxWidth);
      style.height > maxHeight && (style.height = maxHeight);
      Object.keys(style).forEach(k => style[k] = `${style[k]}px`);
      style['transition-property'] = 'width,height';
      style['transition-duration'] = '0,0';
      this.$emit('dragging', { e, style });
    },
    dblResize(d, rect, e) {
      let style = {};
      switch (d) {
        case 'top-left':
          break;
        case 'top':
        case 'bottom':
          style.left = this.originRect.x;
          style.top = rect.height >= this.view_innerHeight() ? this.dblclickOriginRect.y : 0;
          style.width = this.originRect.width;
          style.height = rect.height >= this.view_innerHeight() ? this.dblclickOriginRect.height : this.view_innerHeight();
          break;
        case 'top-right':
          break;
        case 'left':
        case 'right':
          style.left = rect.width >= innerWidth ? this.dblclickOriginRect.x : 0;
          style.top = this.originRect.y;
          style.width = rect.width >= innerWidth ? this.dblclickOriginRect.width : innerWidth;
          style.height = this.originRect.height;
          break;
        case 'bottom-left':
          break;
        case 'bottom-right':
          break;
        default:
      }
      Object.keys(style).forEach(k => style[k] = `${style[k]}px`);
      style['transition-property'] = 'width,height';
      style['transition-duration'] = '0.1s,0.1s';
      this.$emit('dragging', { e, style });
    },
    mouseup_window(e) {
      this.$emit('dragEnd', e);
      this.__removeWindowEvents();
    },
  }
};
</script>
<style lang="scss" scoped>
.sgDragSize {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  pointer-events: none;

  .resize-handle {
    position: absolute;
    z-index: 100;
    display: block;
    pointer-events: auto;
  }

  &[disabled] {
    .resize-handle {
      pointer-events: none;
    }
  }

  .resize-top {
    cursor: n-resize;
    top: -3px;
    left: 0px;
    height: 7px;
    width: 100%;
  }

  .resize-right {
    cursor: e-resize;
    right: -3px;
    top: 0px;
    width: 7px;
    height: 100%;
  }

  .resize-bottom {
    cursor: s-resize;
    bottom: -3px;
    left: 0px;
    height: 7px;
    width: 100%;
  }

  .resize-left {
    cursor: w-resize;
    left: -3px;
    top: 0px;
    width: 7px;
    height: 100%;
  }

  .resize-top-right {
    cursor: ne-resize;
    width: 16px;
    height: 16px;
    right: -8px;
    top: -8px;
  }

  .resize-bottom-right {
    cursor: se-resize;
    width: 20px;
    height: 20px;
    right: -8px;
    bottom: -8px;
    background: url('/static/img/desktop/Windows7/sgDragSize/resize_corner.png') no-repeat;
  }

  .resize-bottom-left {
    cursor: sw-resize;
    width: 16px;
    height: 16px;
    left: -8px;
    bottom: -8px;
  }

  .resize-top-left {
    cursor: nw-resize;
    width: 16px;
    height: 16px;
    left: -8px;
    top: -8px;
  }
}
</style>
