<template>
  <n-layout class="n-split" :vertical="vertical" :class="splitClasses">
    <template #header>
      <div v-if="!sider || sider === 'left'" class="n-split-left" ref="left" :style="styles">
        <slot name="left"></slot>
      </div>
      <div v-if="!sider" class="n-split-trigger flex-center" :class="triggerClasses" v-mouse="onMouseEvent">
        <span class="dot"></span>
        <span class="dot"></span>
        <span class="dot"></span>
      </div>
    </template>
    <n-content v-if="!sider || sider === 'right'" class="n-split-right">
      <slot name="right"></slot>
    </n-content>
  </n-layout>
</template>

<script>
import NLayout from '@uif/next/lib/components/layout'
import NContent from '@uif/next/lib/components/content'
import mouse from '@uif/next/lib/directives/mouse'
import {prop, addBodyClass, removeBodyClass} from '@uif/next/lib/utils/tools'
import vModel from '_common/vModel'

export default {
  name: 'n-split',
  mixins: [vModel],
  directives: {
    mouse
  },
  components: {
    NLayout,
    NContent
  },
  props: {
    // 分割比例
    value: prop.number(0.5),
    // 是否为垂直方向
    vertical: prop.boolean(),
    // 仅可见面板，可选值为`left`, `right`, false
    sider: prop.inArray(['left', 'right'], false, true),
    // 最小比例
    min: prop.number(0.25),
    // 最大比例
    max: prop.number(0.75)
  },
  data () {
    return {
      nValue: this.value,
      isMoving: false
    }
  },
  computed: {
    splitClasses ({vertical, sider}) {
      return {
        'n-split-vertical': vertical,
        'n-split-sider': sider
      }
    },
    triggerClasses ({vertical, isMoving}) {
      return {
        'n-split-trigger-vertical': vertical,
        'n-split-trigger-moving': isMoving
      }
    },
    styles ({sider, nValue, vertical}) {
      if (vertical) {
        return {height: (sider === 'left' ? 100 : nValue * 100) + '%'}
      }
      return {width: (sider === 'left' ? 100 : nValue * 100) + '%'}
    }
  },
  methods: {
    onMouseStart (event) {
      this.isMoving = true
      addBodyClass('no-select')
      addBodyClass(this.getCursor())
      const {top, left, height, width} = this.$el.getBoundingClientRect()
      const offset = this.vertical ? event.target.offsetHeight / 2 : event.target.offsetWidth / 2
      this.scope = {top, left, height, width, offset}
    },
    onMouseMove (event) {
      let value = 0
      if (this.vertical) {
        value = (event.clientY - this.scope.top - this.scope.offset) / this.scope.height
      } else {
        value = (event.clientX - this.scope.left - this.scope.offset) / this.scope.width
      }
      this.scope.value = Math.min(Math.max(value, this.min), this.max)
      this.$refs.left.style[this.vertical ? 'height' : 'width'] = (this.scope.value * 100) + '%'
    },
    onMouseEnd () {
      this.isMoving = false
      removeBodyClass('no-select')
      removeBodyClass(this.getCursor())
      if (this.scope.value && this.nValue !== this.scope.value) {
        this.nValue = this.scope.value
        this.$emit('u-change', this.nValue)
      }
    },
    onMouseEvent (time, event) {
      switch (time) {
        case 'start':
          return this.onMouseStart(event)
        case 'move':
          return this.onMouseMove(event)
        case 'end':
          return this.onMouseEnd(event)
      }
    },
    getCursor () {
      return this.vertical ? 's-resize' : 'e-resize'
    }
  }
}
</script>
