<template>
  <div class="annotation-box"
       :style="style"
       :class="{
          draggable,
          deletable,
          taggable,
          confirmable,
          croppable,
        }"
       @contextmenu.prevent
       @mousedown.prevent="click" @touchstart.prevent="click">
    <template v-if="draggable">
      <div class="nw" @mousedown.prevent.stop="resize('nw')" @touchstart.prevent.stop="resize('nw')"/>
      <div class="nn" @mousedown.prevent.stop="resize('nn')" @touchstart.prevent.stop="resize('nn')"/>
      <div class="ne" @mousedown.prevent.stop="resize('ne')" @touchstart.prevent.stop="resize('ne')"/>
      <div class="ww" @mousedown.prevent.stop="resize('ww')" @touchstart.prevent.stop="resize('ww')"/>
      <div class="ee" @mousedown.prevent.stop="resize('ee')" @touchstart.prevent.stop="resize('ee')"/>
      <div class="sw" @mousedown.prevent.stop="resize('sw')" @touchstart.prevent.stop="resize('sw')"/>
      <div class="ss" @mousedown.prevent.stop="resize('ss')" @touchstart.prevent.stop="resize('ss')"/>
      <div class="se" @mousedown.prevent.stop="resize('se')" @touchstart.prevent.stop="resize('se')"/>
    </template>

    <div v-if="labelName" class="label">
      {{ labelName }}
    </div>
  </div>
</template>

<script>
export default {
  name: "annotation-box",
  data: function(){
    return {
      clickCounter: 0,
      dblClickInterval: 200, // in ms

      colors: {
        default: '255, 255, 255',
        pipeline: '0, 0, 255',
        user: '255, 0, 0',
        other_user: '136, 0, 136',
        confirmed: '0, 180, 0',
        other_confirmed: '180, 180, 136',
      }
    };
  },
  props: [
    'box',
    'position',
    'draggable',
    'deletable',
    'taggable',
    'confirmable',
    'zoomable',
    'croppable',
    'labels',
    'shine'
  ],
  computed: {
    labelName: function () {
      if (!this.box || !this.box.label_id)
        return false;
      for (let label of this.labels) {
        if (label.identifier === this.box.label_id) {
          return label.name;
        }
      }

      return 'unknown';
    },

    color: function() {
      let box = this.box;
      let current_user = this.$root.socket.username

      if(!box)
        return this.colors.default;

      switch(box.origin) {
        case 'user':
          for (let confirmer of box.confirmations)
            if (confirmer.confirming_user ==  current_user)
              return this.colors.confirmed;

          if (box.confirmations.length !== 0)
            return this.colors.other_confirmed;

          if (box.origin_user === current_user)
            return this.colors.user;

          return this.colors.other_user;

        case 'pipeline':
          return this.colors.pipeline;

        default:
          return this.colors.default;
      }

    },

    alpha: function () {
      return this.shine ? 0.6 : 0.3;
    },

    style: function () {
      let color = this.color;
      let alpha = this.alpha;

      return {
        backgroundColor: `rgba(${color}, ${alpha})`,
        borderColor: `rgba(${color}, ${Math.min(1, alpha * 1.5)})`,
        top: this.position.y * 100 + '%',
        left: this.position.x * 100 + '%',
        width: this.position.w * 100 + '%',
        height: this.position.h * 100 + '%'
      }
    },
  },
  methods: {


    doubleLeftClick(event) {
      console.debug("double left click", event);
      this.$emit('interaction', "move-box");
      this.$emit('crop', this.box);
    },

    doubleRightClick(event) {
      console.debug("double right click", event);

    },

    singleLeftClick(event) {
      console.debug("single left click", event);

      if (this.deletable) {
        // TODO then / error
        this.$emit("remove", this.box.identifier)
      }
      else if (this.draggable) {
        // TODO then / error
        this.$emit('move', event, this.position, this.update);
      }
      else if (this.taggable) {
        // TODO then / error
        this.$emit("labelBox", this.box.identifier, this.taggable.identifier)
        this.selectMe();
      }
      else if (this.confirmable) {
        // TODO then / error
        this.$emit("confirm", this.box.identifier)
      }
      else if (this.zoomable) {
        this.$emit('zoom', this.position);
      }
      else if (this.croppable) {
        this.selectMe();
      }

      event.stopPropagation();
    },

    singleRightClick() {
      this.selectMe();
      this.$emit('labelSelector', this.box);
    },

    singleClick(event) {
      if (event.which == 1){
        this.singleLeftClick(event);
      }
      else if (event.which == 2){
        console.debug("single middle click");
      }
      else if (event.which == 3){
        this.singleRightClick(event);
      }
    },

    doubleClick(event) {
      if (event.which == 1){
        this.doubleLeftClick(event);
      }
      else if (event.which == 2){
        console.debug("double middle click");
      }
      else if (event.which == 3){
        this.doubleRightClick(event);
      }
    },

    selectMe(){
      this.$emit('crop', this.box);
    },

    click: function (event) {
      this.clickCounter++;

      event.stopPropagation();

      if (this.clickCounter == 1) {
        this.timer = setTimeout( () => {
          this.clickCounter = 0;
          this.singleClick(event);
        }, this.dblClickInterval);
        return;
      }

      clearTimeout(this.timer);
      this.clickCounter = 0;
      this.doubleClick(event);
    },
    resize: function (mode) {
      this.$emit('resize', mode, this.position, this.update);
    },
    update: function (value) {
      this.$emit("updateBox", this.box.identifier, value)
    }
  }
}
</script>

<style scoped>
.annotation-box {
  position: absolute;
  border: 1px solid transparent;
}

.label {
  position: absolute;
  bottom: 0.25rem;
  left: 50%;
  transform: translateX(-50%);

  font-size: 80%;
  color: whitesmoke;
  text-shadow: 0 0 1px #000000;
}

.nw {
  position: absolute;
  top: -0.3rem;
  left: -0.3rem;
  width: 0.6rem;
  height: 0.6rem;
  cursor: nwse-resize;
  /* background-color: blue; */
}

.nn {
  position: absolute;
  top: -0.3rem;
  left: 0.3rem;
  right: 0;
  height: 0.6rem;
  cursor: ns-resize;
  /* background-color: orangered; */
}

.ne {
  position: absolute;
  top: -0.3rem;
  right: -0.3rem;
  width: 0.6rem;
  height: 0.6rem;
  cursor: nesw-resize;
  /* background-color: cadetblue; */
}

.ww {
  position: absolute;
  top: 0.3rem;
  left: -0.3rem;
  width: 0.6rem;
  bottom: 0.3rem;
  cursor: ew-resize;
  /* background-color: fuchsia; */
}

.ee {
  position: absolute;
  top: 0.3rem;
  right: -0.3rem;
  width: 0.6rem;
  bottom: 0.3rem;
  cursor: ew-resize;
  /* background-color: midnightblue; */
}

.sw {
  position: absolute;
  bottom: -0.3rem;
  left: -0.3rem;
  width: 0.6rem;
  height: 0.6rem;
  cursor: nesw-resize;
  /* background-color: aqua; */
}

.ss {
  position: absolute;
  bottom: -0.3rem;
  left: 0.3rem;
  right: 0.3rem;
  height: 0.6rem;
  cursor: ns-resize;
  /* background-color: gold; */
}

.se {
  position: absolute;
  bottom: -0.3rem;
  right: -0.3rem;
  width: 0.6rem;
  height: 0.6rem;
  cursor: nwse-resize;
  /* background-color: brown; */
}

.draggable {
  cursor: url('~@/assets/icons/four-directions.svg') 8 8, move;
}

.deletable {
  cursor: url('~@/assets/icons/trash.svg') 8 8, not-allowed;
}

.taggable {
  cursor: url('~@/assets/icons/tag.svg') 8 8, alias;
}

.confirmable {
  cursor: url('~@/assets/icons/check.svg') 8 8, pointer;
}

.croppable {
  cursor: url('~@/assets/icons/info.svg') 8 8, move;
}
</style>
