<template>
  <div class="cropped-image">
    <div class="close-button"
         @mousedown.prevent="$emit('close', true)"
         @touchstart.prevent="$emit('close', true)">
      <img alt="close button" src="@/assets/icons/cross.svg">
    </div>


    <h3 v-html="label"></h3>
    <div v-if="src">
      <div class="image-container">
        <img alt="crop" :src="src" />
      </div>

      <div class="label-container">
        <div ref="create_prediction"
             class="icon"
             title="predict label for this image patch"
             :class="{active: isPredictionRunning}"
             @click="predictCroppedImage">
          <img alt="predict label" src="@/assets/icons/rocket.svg">
        </div>
        <div v-if="hasLabel"
             ref="remove_prediction"
             class="icon"
             title="remove this label"
             @click="removeLabel">
          <img alt="remove label" src="@/assets/icons/untag.svg">
        </div>
        <div v-if="!hasLabel"
             ref="add_label"
             class="icon"
             title="set label"
             @click="setLabel">
          <img alt="set label" src="@/assets/icons/tag.svg">
        </div>
      </div>

      <div v-if="hasAnnotator" class="annotation-info">
        <table border="0">
          <tr>
            <td>Annotated by:</td>
            <td align="left"><b v-html="getAnnotator"></b></td>
          </tr>
          <tr v-if="box.confirmations.length !== 0">
            <td colspan="2" align="left">Confirmed by:</td>
          </tr>
          <tr v-if="box.confirmations.length !== 0">
            <td colspan="2" align="right">
              <ol class="confirming-users">
                <li v-for="confirmation in box.confirmations" :key="confirmation.id" margin="0" padding="0">
                  <b>{{confirmation.confirming_user}}</b>
                </li>
              </ol>
            </td>
          </tr>
        </table>
      </div>

      <div v-else class="annotation-info">
        <table border="0">
          <tr>
            <td>Annotated by:</td>
            <td align="left"><b><em>unknown</em></b></td>
          </tr>
        </table>
      </div>
    </div>

    <div v-else>
      Click a bounding box
    </div>
  </div>
</template>

<script>
export default {
  name: "cropped-image",
  props: ['labels', 'file', 'box'],
  created: function () {
    // get data
    this.getJobs();

    // 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);
  },
  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);
  },
  data: function () {
    return {
      jobs: [],
      labelSelector: false,
      model: null
    }
  },
  computed: {
    src: function () {
      if (!this.box)
        return false;

      const file = this.file.identifier;
      const uuid = this.file.uuid;
      const x = this.box.data.x;
      const y = this.box.data.y;
      const w = this.box.data.w;
      const h = this.box.data.h;

      return this.$root.socket.url(`/data/${file}/1024/${x}x${y}x${w}x${h}?uuid=${uuid}`)
    },

    hasLabel: function() {
      return this.box && this.box.label_id !== null;
    },

    label: function () {
      if (!this.hasLabel)
        return '<em>Unknown</em>'

      for (let label of this.labels)
        if (label.identifier === this.box.label_id)
          return label.name;

      return '<em>Not found</em>';
    },
    isPredictionRunning: function () {
      return this.jobs.filter(j => !j.finished && j.type === 'Model Interaction').length > 0;
    },

    hasAnnotator: function() {
      return this.box && this.box.origin_user !== null;
    },
    getAnnotator: function () {
      let current_user = this.$root.socket.username;
      if (this.box.origin === 'user' && this.box.origin_user !== null) {
        if (this.box.origin_user === current_user)
          return "<em>You</em>"
        else
          return this.box.origin_user;
      }
      if (this.box.origin === 'pipeline') {
        return 'Pipeline';
      }
      return '<em>Unknown</em>';

    },
  },
  methods: {
    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;
        }
      }
    },

    removeLabel: function () {
      if (!this.box)
        return;
      this.$emit("removeLabel", this.box.identifier);
    },

    setLabel: function () {
      if (!this.box)
        return;
      console.log(this.box);
      this.$emit("setLabel", this.box);
    },

    predictCroppedImage: function () {
      // This shouldn't happen, since the icon is only shown if a bounding box
      // was selected.
      if (!this.box)
        return;

      if (this.isPredictionRunning)
        return
      this.$emit("predictBox", this.file.identifier, this.box.identifier)
    }
  }
}
</script>

<style scoped>
.cropped-image {
  width: 40%;
  height: 100%;
  background-color: #858585;
  position: relative;
  padding: 2rem 1rem;
  text-align: center;
  border-left: 2px solid;
  margin-left: 0.5rem;
}

h3 {
  max-width: 100%;
  max-height: 5%;
  margin: 0.5em;
}

.close-button {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0.5rem 0.67rem;
  cursor: pointer;
  filter: invert(1);
}

.close-button img {
  width: 24px;
  height: 24px;
}

.image-container img {
  border: 2px solid;
  max-width: 100%;
  max-height: 50vh;
}

.label-container {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: center;
}

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

  cursor: pointer;

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

  width: 32px;
  height: 32px;
}

.icon:hover, .icon.active {
  background-color: rgba(0, 0, 0, 0.2);
}

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

.annotation-info {
  display: flex;
  justify-content: center;
  align-items: center;
  overflow-x: auto;
  max-height: 13vh;
}

.confirming-users {
  list-style-position: inside;
  padding: 0;
  margin:0;
}

</style>
