<template>
  <div :class="classes">
    <div class="uif-split-left" ref="left" :style="getStyle(currentValue)">
      <slot name="left"></slot>
    </div>
    <div v-if="hidden === 'none'" class="uif-split-trigger" v-mouse="mouseEvent">
      <split-trigger :mode="mode" :is-moving="isMoving"></split-trigger>
    </div>
    <div class="uif-split-right">
      <slot name="right"></slot>
    </div>
  </div>
</template>

<script>
import mouse from '@uif/admin/lib/directives/mouse'
import {oneOf} from '@uif/hq/lib/utils/assist'
import {entries, addAttr} from '@uif/hq/lib/utils/object'
import {addBodyClass, removeBodyClass} from '@uif/hq/lib/utils/dom'
import SplitTrigger from './split-trigger'

export default {
  directives: {
    mouse
  },
  name: 'u-split',
  components: {
    SplitTrigger
  },
  props: {
    value: {
      type: Number,
      default: 0.5
    },
    mode: {
      validator (value) {
        return oneOf(value, ['horizontal', 'vertical'])
      },
      default: 'horizontal'
    },
    hidden: {
      validator (value) {
        return oneOf(value, ['none', 'left', 'right'])
      },
      default: 'none'
    },
    min: {
      type: Number,
      default: 0.25
    },
    max: {
      type: Number,
      default: 0.75
    }
  },
  data () {
    return {
      currentValue: this.value,
      isMoving: false
    }
  },
  computed: {
    classes () {
      return [
        'uif-split',
        'uif-split-mode-' + this.mode,
        'uif-split-hidden-' + this.hidden
      ]
    }
  },
  watch: {
    value (value) {
      if (this.currentValue !== value) {
        this.currentValue = value
      }
    }
  },
  methods: {
    getCursor () {
      return this.mode === 'horizontal' ? 'e-resize' : 's-resize'
    },
    mouseEvent (time, event) {
      switch (time) {
        case 'start':
          this.isMoving = true
          addBodyClass('no-select')
          addBodyClass(this.getCursor())
          this.elRect = this.$el.getBoundingClientRect()
          break
        case 'move':
          this.handleMove(event)
          break
        case 'end':
          this.isMoving = false
          removeBodyClass('no-select')
          removeBodyClass(this.getCursor())
          if (this.changeValue) {
            this.currentValue = this.changeValue
            this.$emit('input', this.currentValue)
          }
          break
      }
    },
    handleMove (event) {
      let value = 0
      if (this.mode === 'horizontal') {
        value = (event.clientX - this.elRect.left) / this.elRect.width
      } else {
        value = (event.clientY - this.elRect.top) / this.elRect.height
      }
      this.changeValue = Math.min(Math.max(value, this.min), this.max)
      const result = entries(this.getStyle(this.changeValue))[0]
      this.$refs.left.style[result[0]] = result[1]
    },
    // 通过value获取样式
    getStyle (value) {
      const attr = this.mode === 'horizontal' ? 'width' : 'height'
      const result = {}
      switch (this.hidden) {
        case 'left':
          addAttr(result, attr, 0)
          break
        case 'right':
          addAttr(result, attr, '100%')
          break
        default:
          addAttr(result, attr, value * 100 + '%')
      }
      return result
    }
  }
}
</script>
