<template>
  <div class="options-bar">
    <div ref="draw_box"
         class="image"
         title="draw bounding box (Q)"
         :class="{active: interaction === 'draw-box'}"
         @click="$emit('interaction', 'draw-box')">
      <img alt="draw bounding box" src="@/assets/icons/screen-full.svg">
    </div>

    <div ref="extreme_clicking"
         class="image"
         title="extreme clicking (E)"
         :class="{active: interaction === 'extreme-clicking'}"
         @click="$emit('interaction', interaction === 'extreme-clicking' ? 'draw-box' : 'extreme-clicking')">
      <img v-if="interaction === 'extreme-clicking'"
           alt="extreme clicking" src="@/assets/icons/check.svg">
      <img v-else
           alt="extreme clicking" src="@/assets/icons/flame.svg">
    </div>

    <div class="spacer"/>

    <div ref="move_box"
         class="image"
         title="move and resize bounding box (R)"
         :class="{active: interaction === 'move-box'}"
         @click="$emit('interaction', 'move-box')">
      <img alt="move and resize bounding box" src="@/assets/icons/four-directions.svg">
    </div>

    <div v-if="labelsEnabled"
         ref="labels"
         class="image"
         title="label bounding box (T)"
         :class="{active: interaction === 'label-box'}"
         @click="labelSelector=true">
      <img alt="extreme clicking" src="@/assets/icons/tag.svg">
    </div>

    <label-selector v-if="labelSelector"
                    :labels="labels"
                    @close="labelSelector=false"
                    @label="$emit('interaction', 'label-box'); $emit('label', $event)"/>

    <div ref="confirm_box"
         class="image"
         title="confirm bounding box (G)"
         :class="{active: interaction === 'confirm-box'}"
         @click="$emit('interaction', 'confirm-box')">
      <img alt="confirm bounding box" src="@/assets/icons/check-circle.svg">
    </div>

    <div ref="remove_box"
         class="image"
         title="remove bounding box (F)"
         :class="{active: interaction === 'remove-box'}"
         @click="$emit('interaction', 'remove-box')">
      <img alt="remove bounding box" src="@/assets/icons/trash.svg">
    </div>

    <div class="spacer"/>

    <div ref="crop_info"
         class="image"
         title="Show info of a bounding box (I)"
         :class="{active: interaction === 'info-box'}"
         @click="$emit('interaction', 'info-box')">
      <img alt="zoom bounding box" src="@/assets/icons/info.svg">
    </div>

    <!--
    <div ref="zoom_annotation"
         class="image"
         title="zoom bounding box (X)"
         :class="{active: interaction === 'zoom-box' || zoomBox}"
         @click="$emit(zoomBox ? 'unzoom' : 'interaction', 'zoom-box')">
      <img alt="zoom bounding box" src="@/assets/icons/codescan.svg">
    </div>

    <div ref="zoom_prev_annotation"
         class="image"
         title="zoom previous bounding box (C)"
         @click="$emit('prevzoom', true)">
      <img alt="zoom previous bounding box" src="@/assets/icons/chevron-left.svg">
    </div>

    <div ref="zoom_next_annotation"
         class="image"
         title="zoom next bounding box (V)"
         @click="$emit('nextzoom', true)">
      <img alt="zoom next bounding box" src="@/assets/icons/chevron-right.svg">
    </div>
    -->

    <div class="spacer"/>

    <div ref="show_user_annotations"
         class="image"
         title="show user annotations"
         :class="{active: filter && filter.includes('user')}"
         @click="invertFilter('user')">
      <img alt="show user annotations" src="@/assets/icons/smiley.svg">
    </div>

    <div ref="show_pipeline_annotations"
         class="image"
         title="show pipeline annotations"
         :class="{active: filter && filter.includes('pipeline')}"
         @click="invertFilter('pipeline')">
      <img alt="show pipeline annotations" src="@/assets/icons/cpu.svg">
    </div>

    <div class="spacer"/>

    <div ref="create_predictions"
         class="image"
         title="create predictions (B)"
         :class="{active: isPredictionRunning}"
         @click="predict">
      <img alt="create predictions" src="@/assets/icons/rocket.svg">
    </div>
  </div>
</template>

<script>
import LabelSelector from "@/components/media/label-selector";

export default {
  name: "options-bar",
  components: {LabelSelector},
  props: ['file', 'interaction', 'filter', 'label', 'labels', 'infoBox', 'zoomBox'],
  created: function () {
    // get data
    this.getJobs();

    this.$root.socket.get(`/projects/${this.$root.project.identifier}/model`)
      .then(response => response.json())
      .then(model => this.model = model);

    // subscribe to changes
    this.$root.socket.on('connect', this.getJobs);
    this.$root.socket.on('create-job', this.addJob);
    this.$root.socket.on('remove-job', this.removeJob);
    this.$root.socket.on('edit-job', this.editJob);

    // subscribe to keypress events
    window.addEventListener('keypress', this.keypressEvent);
  },
  destroyed: function () {
    this.$root.socket.off('connect', this.getJobs);
    this.$root.socket.off('create-job', this.addJob);
    this.$root.socket.off('remove-job', this.removeJob);
    this.$root.socket.off('edit-job', this.editJob);

    window.removeEventListener('keypress', this.keypressEvent)
  },
  data: function () {
    return {
      jobs: [],
      labelSelector: false,
      model: null
    }
  },
  computed: {
    isPredictionRunning: function () {
      return this.jobs.filter(j => !j.finished && j.type === 'Model Interaction').length > 0;
    },
    labelsEnabled: function () {
      return this.model
          && (
              this.model.supports.includes('labeled-images')
              || this.model.supports.includes('labeled-bounding-boxes')
          );
    }
  },
  methods: {
    invertFilter: function (name) {
      if (!this.filter)
        return;

      if (this.filter.includes(name))
        this.$emit('filter', this.filter.filter(f => f !== name));
      else
        this.$emit('filter', [...this.filter, name]);
    },
    predict: function () {
      if (!this.isPredictionRunning) {
        // TODO then / error
        this.$root.socket.post(`/data/${this.file.identifier}/predict`, {
          predict: true
        });
      }
    },
    keypressEvent: function (event) {
      switch (event.key) {
        case 'r':
          this.$refs.move_box.click();
          break;
        case 'q':
          this.$refs.draw_box.click();
          break;
        case 'e':
          this.$refs.extreme_clicking.click();
          break;
        case 't':
          this.$refs.labels.click();
          event.preventDefault();
          break;
        case 'f':
          this.$refs.remove_box.click();
          break;
        case 'g':
          this.$refs.confirm_box.click();
          break;
        case 'b':
          this.$refs.create_predictions.click();
          break;
        case 'x':
          this.$refs.zoom_annotation.click();
          break;
        case 'c':
          this.$refs.zoom_prev_annotation.click();
          break;
        case 'v':
          this.$refs.zoom_next_annotation.click();
          break;
        case 'i':
          this.$refs.crop_info.click();
          break;
      }
    },
    getJobs: function () {
      this.$root.socket.get('/jobs')
          .then(response => response.json())
          .then(jobs => {
            this.jobs = [];
            jobs.forEach(this.addJob)
          });
    },
    addJob: function (job) {
      for (let j of this.jobs)
        if (j.identifier === job.identifier)
          return;

      this.jobs.push(job);
    },
    removeJob: function (job) {
      for (let i = 0; i < this.jobs.length; i++) {
        if (this.jobs[i].identifier === job.identifier) {
          this.jobs.splice(i, 1);
          return;
        }
      }
    },
    editJob: function (job) {
      for (let i = 0; i < this.jobs.length; i++) {
        if (this.jobs[i].identifier === job.identifier) {
          this.$set(this.jobs, i, job);
          return;
        }
      }
    }
  }
}
</script>

<style scoped>
.options-bar {
  /* background-color: rgba(0, 0, 0, 0.25); */
  background-color: #858585;
  z-index: 1;
}

.spacer {
  border-top: 1px solid rgba(255, 255, 255, 0.25);
}

.image {
  display: flex;
  justify-content: center;
  align-items: center;

  cursor: pointer;

  margin: 0.4rem;
  border: 1px solid whitesmoke;
  border-radius: 0.5rem;

  width: 1.6rem;
  height: 1.6rem;
}

.image.active {
  background-color: rgba(0, 0, 0, 0.2);
  box-shadow: inset 0 0 5px 0 rgba(0, 0, 0, 0.2);
}

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

.label-selector {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 101;

  width: 30rem;
  max-width: 90vw;
  max-height: 100%;
  padding-bottom: 0;

  animation: label-selector-animation 0.5s ease-out forwards;
}

@keyframes label-selector-animation {
  from {
    transform: translateX(-50%) translateY(-100%);
  }
  to {
    transform: translateX(-50%) translateY(0%);
  }
}
</style>
