<template>
  <div class="qf-num-pad">
    <table>
      <tr v-for="items in buttons">
        <td v-for="item in items" :rowspan="item.span ? 2 : 1" :style="colStyle">
          <button @click="clickNum(item)" :class="[{span: item.span}, item.class]">{{ getText(item) }}</button>
        </td>
      </tr>
    </table>
  </div>
</template>

<script>
import KeydownMgr from '../../util/KeydownMgr';
import NumberUtil from '../../util/number';

export default {
  name: 'QfNumPad',
  props: {
    type: {
      type: String,
      default: 'number'
    },
    onConfirm: Function,
    onCancel: Function
  },
  data() {
    return {
      oldValue: '',
      input: Object
    };
  },
  computed: {
    buttons() {
      switch (this.type) {
        case 'number':
          return [
            [7, 8, 9, { key: '确定', span: true, class: 'confirm' }],
            [4, 5, 6],
            [1, 2, 3, { key: '取消', span: true, class: 'cancel' }],
            [0, '.', { text: '', key: '<-', class: 'iconfont ic-ic_delete' }]
          ];
        case 'shortcut':
          return [
            [7, 8, 9, { key: '￥100', class: 'shortcut' }],
            [4, 5, 6, { key: '￥50', class: 'shortcut' }],
            [1, 2, 3, { key: '￥20', class: 'shortcut' }],
            [0, '.', { text: '', key: '<-', class: 'iconfont ic-ic_delete' }, { key: '￥10', class: 'shortcut' }]
          ];
        case 'calc':
          return [
            [7, 8, 9, { key: '+', span: true }, { key: '确定', span: true, class: 'confirm' }],
            [4, 5, 6],
            [1, 2, 3, { text: '', key: '<-', span: true, class: 'iconfont ic-ic_delete' }, {
              key: '取消',
              span: true,
              class: 'cancel'
            }],
            ['00', 0, '.']
          ];
      }
    },
    colStyle() {
      let length = 1;
      this.buttons.forEach(item => {
        if (item.length > length) {
          length = item.length;
        }
      });
      return {
        width: (1 / length * 100) + '%'
      };
    }
  },

  created() {
    if (this.type === 'calc') {
      KeydownMgr.bind(this, this.onKeydown);
    }
  },

  beforeDestroy() {
    if (this.type === 'calc') {
      KeydownMgr.unbind(this, this.onKeydown);
    }
  },

  methods: {
    clickNum(title) {
      let str = this.getKey(title);
      if (str === '确定') {
        this.$emit('confirm');
        return;
      } else if (str === '取消') {
        this.$emit('cancel');
        return;
      }
      let oldVal = this.input.currentValue;
      if (typeof (oldVal) === 'number') {
        oldVal = oldVal.toString();
      } else if (!oldVal) {
        oldVal = '';
      }
      let newVal = '';
      let caret = { start: this.input.getSelectionStart(), end: this.input.getSelectionEnd() };

      if (str === '<-') { // 删除操作
        newVal = this.backspace(caret, oldVal);
      } else if (str.toString().indexOf('￥') !== -1) { // 快捷数字
        if (!oldVal) {
          newVal = str.substring(1);
        } else {
          newVal = (parseFloat(oldVal) + parseFloat(str.substring(1))).toString();
        }
        caret.start = newVal.length;
        caret.end = caret.start;
      } else { // 输入
        newVal = this.insertChar(caret, oldVal, str);
      }

      if (this.isValid(newVal)) {
        this.input.doInput(newVal);
      } else {
        caret = null;
      }
      this.$nextTick(() => {
        this.setFocusToInput(caret);
      });
    },

    // 删除键
    backspace(caret, text) {
      let start = caret.start === caret.end ? caret.start - 1 : caret.start;
      text = text.substring(0, start) + text.substring(caret.end);
      caret.start = start;
      caret.end = caret.start;
      return text;
    },

    // 设置聚焦
    setFocusToInput(caret) {
      this.input.focus(caret);
    },

    getKey(item) {
      if (item.key) {
        return item.key;
      } else {
        return item;
      }
    },

    getText(item) {
      if (item.text !== undefined) {
        return item.text;
      } else {
        return this.getKey(item);
      }
    },

    // 插入字符
    insertChar(caret, text, ch) {
      text = text.substr(0, caret.start) + ch.toString() + text.substr(caret.end);
      caret.start += ch.toString().length;
      caret.end = caret.start;
      return text;
    },

    isValid(value) {
      if (value.length > this.input.maxlength) {
        return false;
      }
      if (this.type === 'calc') {
        var sum = 0;
        if (value) {
          var valid = value.indexOf('+') !== 0 && value.indexOf('++') < 0 && value.indexOf('..') < 0;
          let groups = value.split('+');
          valid = valid && !groups.some(item => !NumberUtil.isNumber(item) && item !== '');
          if (!valid) {
            return false;
          }
          groups.forEach(item => {
            sum = sum + Number(item);
          });
          if (this.max && sum > this.max) {
            return false;
          }
        }
        this.$emit('input', sum);
      }
      return true;
    },

    onKeydown(event) {
      if (event.keyCode >= 48 && event.keyCode <= 57) {
        this.clickNum(String.fromCharCode(event.keyCode));
      }
      if (event.keyCode >= 96 && event.keyCode <= 108 && event.keyCode !== 106) {
        this.clickNum(String.fromCharCode(event.keyCode - 48));
      }
      if (event.keyCode === 110 || event.keyCode === 190) {
        this.clickNum('.');
      }
      if (event.keyCode === 8) {
        this.clickNum('<-');
      }
      if (event.keyCode === 13) {
        this.$emit('confirm');
      }
      if (this.type === 'calc' && ((event.shiftKey && event.keyCode === 187) || event.keyCode === 107)) {
        this.clickNum('+');
      }
    }
  }
};
</script>

