<template>
  <div class="form-group micro-qrcode">
    <label v-if="caption" class="form-label" :for="`inputQrCaption${_uid}`">
      {{ caption }}
    </label>

    <div class="input-group">
      <input v-model="scannedValue" @input="handleInput" :placeholder="placeholder" type="text" class="form-control">

      <div class="input-group-append">
        <button v-show="scanning" type="button" :class="`btn ${stopButtonClass}`" @click="toggleScanning">
          Stop
        </button>

        <button :class="`btn ${scanButtonClass}`" type="button" @click="toggleScanning">
          <span class="mdi mdi-qrcode-scan"></span>
        </button>
      </div>
    </div>

    <div class="canvas-container">
      <canvas :id="`inputQrCanvas${_uid}`" hidden />
      <video v-show="scanning" :id="`inputQrVideo${_uid}`" />
    </div>

    <small class="form-text text-muted">
      {{ description }}
    </small>
  </div>
</template>

<script>
import jsQR from 'jsqr'

export default {
  props: {
    caption: String, 
    placeholder: String, 
    value: [ String ],
    description: String, 
    field: Object, 
    continueAfterResult: Boolean, 
    showResults: {
      type: Boolean,
      default: true,
    },
    scanButtonClass: {
      type: String,
      default: 'btn-primary',
    },
    stopButtonClass: {
      type: String,
      default: 'btn-outline-danger',
    },
  },

  data() {
    return {
      hasCamera: false,
      scanner: null,
      video: null,
      canvasElement: null,
      scanning: false,
      scannedValue: '',
    }
  },

  mounted () {
    const vm = this

    vm.video = document.getElementById(`inputQrVideo${vm._uid}`)
    vm.canvasElement = document.getElementById(`inputQrCanvas${vm._uid}`)

    vm.scannedValue = vm.value
  },

  beforeDestroy () {
    const vm = this

    vm.video.pause()

    if (vm.video && vm.video.srcObject && vm.video.srcObject.getTracks()) {
      vm.video.srcObject.getTracks().forEach(track => track.stop());
      vm.video.removeAttribute('src')
      vm.video.load()
    }

    if (vm.scanner) {
      // vm.scanner.destroy()
    }
  },

  methods: {
    /*
    drawLine(begin, end, color) {
      const vm = this

      let canvas = vm.canvasElement.getContext("2d")

      canvas.beginPath();
      canvas.moveTo(begin.x, begin.y);
      canvas.lineTo(end.x, end.y);
      canvas.lineWidth = 4;
      canvas.strokeStyle = color;
      canvas.stroke();
    },
    */

    handleInput (e) {
      this.$emit('input', e.target.value)
    },

    tick () {
      const vm = this

      if (vm.video.readyState === vm.video.HAVE_ENOUGH_DATA) {
        vm.canvasElement.height = vm.video.videoHeight;
        vm.canvasElement.width = vm.video.videoWidth;

        let canvas = vm.canvasElement.getContext('2d')
        canvas.drawImage(vm.video, 0, 0, vm.canvasElement.width, vm.canvasElement.height);
        let imageData = canvas.getImageData(0, 0, vm.canvasElement.width, vm.canvasElement.height);
        let code = jsQR(imageData.data, imageData.width, imageData.height, {
          inversionAttempts: 'dontInvert',
        });

        if (code) {
          // vm.drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF3B58");
          // vm.drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF3B58");
          // vm.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF3B58");
          // vm.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF3B58");
          let result = code.data

          let result_exists = false

          if (! result_exists) {
            vm.scannedValue = result
            vm.$emit('input', vm.scannedValue)
          }

          if (! vm.continueAfterResult) {
            vm.toggleScanning()
          }

        } else {
        }
      }

      requestAnimationFrame(vm.tick)
    },

    toggleScanning () {
      const vm = this

      if (vm.scanning) {
        vm.video.pause()
        vm.video.srcObject.getTracks().forEach(track => track.stop());
        vm.video.removeAttribute('src')
        vm.video.load()
      } else {
        navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }).then(function(stream) {
          vm.video.srcObject = stream;
          vm.video.setAttribute('playsinline', true); // required to tell iOS safari we don't want fullscreen
          vm.video.play()
          requestAnimationFrame(vm.tick)
        })
      }

      vm.scanning = ! vm.scanning
    },
  }
}
</script>

<style lang="scss">
.micro-qrcode {
  position: relative;

  .canvas-container {
    position: absolute;
    width: 100%;
    text-align: right;
    z-index: 100000;

    video {
      margin-top: 3px;
      border-radius: 5px;
      width: 150px;
      height: 150px;
      object-fit: cover;
    }
  }
}
</style>