<template>
  <div class="video-control">
    <div v-if="video.play"
         ref="play_pause"
         class="button"
         title="Pause (SPACE)"
         @click="$emit('play', false)">
      <img alt="pause" src="@/assets/icons/pause.svg">
    </div>
    <div v-else
         ref="play_pause"
         class="button"
         title="Play (SPACE)"
         @click="$emit('play', true)">
      <img alt="play" src="@/assets/icons/play.svg">
    </div>

    <div class="input">
      <input type="range"
             min="0" :max="file.frames" :value="video.frame"
             @change="$emit('jump', $event.target.value)">

      <div v-for="(marker, key) in resultMarker"
           v-bind:key="key"
           class="marker"
           :class="marker.class"
           :style="marker.style"/>
    </div>

    <div ref="prev_frame"
         class="button"
         title="Previous Frame (LEFT ARROW)"
         @click="$emit('jump', video.frame - 1)">
      <img alt="previous frame" src="@/assets/icons/chevron-left.svg">
    </div>
    <div ref="next_frame"
         class="button"
         title="Next Frame (RIGHT ARROW)"
         @click="$emit('jump', video.frame + 1)">
      <img alt="next frame" src="@/assets/icons/chevron-right.svg">
    </div>

    <div class="spacer"/>

    <div ref="prev_prediction"
         class="button"
         title="Previous Prediction (UP ARROW)"
         @click="previousPrediction">
      <img alt="previous prediction" src="@/assets/icons/chevron-left.svg">
      <img alt="previous prediction" src="@/assets/icons/chevron-left.svg">
    </div>
    <div ref="next_prediction"
         class="button"
         title="Next Prediction (DOWN ARROW)"
         @click="nextPrediction">
      <img alt="next prediction" src="@/assets/icons/chevron-right.svg">
      <img alt="next prediction" src="@/assets/icons/chevron-right.svg">
    </div>
  </div>
</template>

<script>
export default {
  name: "video-control",
  props: ['file', 'video', 'results'],
  created: function () {
    window.addEventListener('keydown', this.keypress);
  },
  destroyed: function () {
    window.removeEventListener('keydown', this.keypress);
  },
  computed: {
    resultMarker: function () {
      const frames = this.results
          .filter(r => r.data && 'frame' in r.data)
          .map(r => {
            return {
              frame: r.data.frame,
              origin: r.origin
            }
          })
          .reduce((a, r) => {
            if (r.frame in a) {
              if (a[r.frame] !== r.origin) {
                a[r.frame] = 'mixed';
              }
            } else {
              a[r.frame] = r.origin;
            }

            return a;
          }, {});

      return Object.keys(frames)
          .map(key => {
            return {
              class: {
                user: frames[key] === 'user',
                pipeline: frames[key] === 'pipeline',
                mixed: frames[key] === 'mixed',
              },
              style: {
                left: `calc(7.5px + ${key / this.file.frames} * (100% - 15px))`
              }
            }
          });
    }
  },
  methods: {
    keypress: function (event) {
      switch (event.key) {
        case ' ':
          this.$refs.play_pause.click();
          break;
        case 'ArrowUp':
          this.$refs.prev_prediction.click();
          break;
        case 'ArrowDown':
          this.$refs.next_prediction.click();
          break;
        case 'ArrowLeft':
          this.$refs.prev_frame.click();
          break;
        case 'ArrowRight':
          this.$refs.next_frame.click();
          break;
      }
    },
    previousPrediction: function () {
      let targetFrame = -Infinity;

      for (let result of this.results) {
        if ('frame' in result.data && result.data.frame < this.video.frame && result.data.frame > targetFrame)
          targetFrame = result.data.frame;
      }

      if (targetFrame !== -Infinity) {
        this.$emit('jump', targetFrame);
      }
    },
    nextPrediction: function () {
      let targetFrame = Infinity;

      for (let result of this.results) {
        if ('frame' in result.data && result.data.frame > this.video.frame && result.data.frame < targetFrame)
          targetFrame = result.data.frame;
      }

      if (targetFrame !== Infinity) {
        this.$emit('jump', targetFrame);
      }
    }
  }
}
</script>

<style scoped>
.video-control {
  width: 100%;
  color: whitesmoke;
  background-color: rgba(0, 0, 0, 0.4);
  padding: 0 0.6rem;

  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

.button {
  width: 1.4rem;
  height: 2.4rem;

  display: flex;
  justify-content: center;
  align-items: center;
}

.spacer {
  width: 0.3rem;
}

img {
  filter: invert(1);
  width: 1rem;
  height: 1rem;
}

img:first-child:not(:last-child) {
  margin-right: -0.3rem;
}

img:last-child:not(:first-child) {
  margin-left: -0.3rem;
}

.input {
  flex-grow: 1;
  margin: 0 0.5rem;
  position: relative;

  display: flex;
  justify-content: center;
  align-items: center;
}

input {
  width: 100%;
  margin: 0;
  z-index: 5;
}

.marker {
  position: absolute;
  top: 50%;
  z-index: 4;

  width: 2px;
  height: 130%;
  transform: translateX(-1px) translateY(-50%);

  border-radius: 2px;
}

.marker.user,
.marker.mixed {
  background-color: #FF0000;
}

.marker.pipeline {
  background-color: #0000FF;
}

.marker.mixed:after {
  content: ' ';

  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;

  background-color: #0000FF;
  clip-path: polygon(0 0, 100% 0, 100% 70%, 0 30%);
}
</style>