<template>
  <div class="keyboard">
    <div class="keys">
      <div v-for="i in 40" :class="cls_of(i - 1)"
           :key="i" @click="press(i - 1)"
           @touchstart="touch_start(i - 1)" @touchend="touch_end">
        {{ key_of(i - 1) }}
      </div>
    </div>
    <div class="keys-bottom">
      <div class="pos-cancel" @click="cancel">取&nbsp;&nbsp;&nbsp;&nbsp;消</div>
      <div class="key-blank" @click="press(-1)">空&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;格</div>
      <div class="pos-upload" @click="submit">确&nbsp;&nbsp;&nbsp;&nbsp;定</div>
    </div>
  </div>
</template>

<script>
let LongPressTimer = null;
const Lower = "0123456789qwertyuiopasdfghjkl⇦⇑zxcvbnm.-", Upper = "0123456789QWERTYUIOPASDFGHJKL⇦⇓ZXCVBNM.-";

export default {
  name: "FullKeyboard",
  props: {
    max: {
      type: Number,
      default: 0
    },
    default: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      upper: false,
      val: this.default
    }
  },
  methods: {
    cls_of(index) {
      return (index === 29) ? "key-btn key-btn-delete" : "key-btn key-btn-normal"
    },
    key_of(index) {
      return this.upper ? Upper[index] : Lower[index];
    },
    press(index) {
      if (index === -1) {  // blank
        if (this.max > 0 && this.val.length >= this.max) return;
        this.val += " ";
      } else if (index === 29) {  // delete
        this.val = this.val.slice(0, -1);
      } else if (index === 30) {  // upper
        this.upper = !this.upper;
      } else {  // normal
        if (this.max > 0 && this.val.length >= this.max) return;
        this.val += this.upper ? Upper[index] : Lower[index];
      }
    },
    touch_start(index) {
      if (index === 29) {
        if (LongPressTimer !== null) clearInterval(LongPressTimer);
        LongPressTimer = setInterval(() => {
          if (this.val === "") {
            clearInterval(LongPressTimer);
            LongPressTimer = null;
            return;
          }
          this.val = this.val.slice(0, -1);
        }, 100);
      } else if (index !== 30) {
        if (LongPressTimer !== null) clearInterval(LongPressTimer);
        LongPressTimer = setInterval(() => {
          if (this.max > 0 && this.val.length >= this.max) {
            clearInterval(LongPressTimer);
            LongPressTimer = null;
            return;
          }
          this.val += this.upper ? Upper[index] : Lower[index];
        }, 100);
      }
    },
    touch_end() {
      if (LongPressTimer !== null) clearInterval(LongPressTimer);
    },
    cancel() {
      this.$emit("cancel");
    },
    submit() {
      this.$emit("submit", this.val);
    }
  },
  watch: {
    val(v) {
      this.$emit("change", v);
    }
  }
}
</script>

<style scoped>
.keyboard {
  width: 100%;
  font-size: 1.1em;
  font-weight: bold;
  box-sizing: border-box;
  padding: 10px 20px;
  background-color: white;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}

.keys {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}

.key-btn {
  width: 9.5%;
  height: 80px;
  display: flex;
  cursor: pointer;
  margin-bottom: 4px;
  justify-content: center;
  align-items: center;
  font-size: 1.2em;
  border: 1px solid lightgray;
  border-radius: 4px;
  background-color: ghostwhite;
}

.key-btn-normal {
  color: #122334;
}

.key-btn-delete {
  color: red;
}

.keys-bottom {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 11px;
}

.pos-cancel, .pos-upload, .key-blank {
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 4px;
  cursor: pointer;
}

.pos-cancel {
  width: 20%;
  border: 1px solid #AA0123;
  color: dimgray;
}

.pos-upload {
  width: 20%;
  border: 1px solid deepskyblue;
  background-color: lightskyblue;
  color: black;
}

.key-blank {
  width: 50%;
  border: 1px solid black;
  color: #122334;
}
</style>