<template>
  <div class="fm-additions-cropper">
    <div class="row" v-bind:style="{ 'max-height': maxHeight + 'px' }">
      <div class="col-sm-9 cropper-block">
        <img
          v-bind:src="imgSrc"
          ref="fmCropper"
          v-bind:alt="selectedItem.basename"
        />
      </div>
      <div class="col-sm-3 pl-0">
        <div class="cropper-preview"></div>
        <div class="cropper-data">
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataX">X</label>
            </span>
            <input
              v-model.number="x"
              type="text"
              class="form-control"
              id="dataX"
            />
            <span class="input-group-append">
              <span class="input-group-text">px</span>
            </span>
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataY">Y</label>
            </span>
            <input
              v-model.number="y"
              type="text"
              class="form-control"
              id="dataY"
            />
            <span class="input-group-append">
              <span class="input-group-text">px</span>
            </span>
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataWidth">Width</label>
            </span>
            <input
              v-model.number="width"
              type="text"
              class="form-control"
              id="dataWidth"
            />
            <span class="input-group-append">
              <span class="input-group-text">px</span>
            </span>
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataHeight">Height</label>
            </span>
            <input
              v-model.number="height"
              type="text"
              class="form-control"
              id="dataHeight"
            />
            <span class="input-group-append">
              <span class="input-group-text">px</span>
            </span>
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataRotate">Rotate</label>
            </span>
            <input
              v-model.number="rotate"
              type="text"
              class="form-control"
              id="dataRotate"
            />
            <span class="input-group-append">
              <span class="input-group-text">deg</span>
            </span>
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataScaleX">ScaleX</label>
            </span>
            <input
              v-model.number="scaleX"
              type="text"
              class="form-control"
              id="dataScaleX"
            />
          </div>
          <div class="input-group input-group-sm">
            <span class="input-group-prepend">
              <label class="input-group-text" for="dataScaleY">ScaleY</label>
            </span>
            <input
              v-model.number="scaleY"
              type="text"
              class="form-control"
              id="dataScaleY"
            />
          </div>
          <button
            v-on:click="setData()"
            v-bind:title="lang.modal.cropper.apply"
            type="button"
            class="btn btn-block btn-sm btn-info mb-2"
          >
            <i class="fas fa-check" />
          </button>
        </div>
      </div>
    </div>
    <div class="d-flex justify-content-between">
      <div>
        <div class="btn-group mr-2" role="group" aria-label="Scale">
          <button v-on:click="cropMove(-10, 0)" class="btn btn-info">
            <i class="fas fa-arrow-left" />
          </button>
          <button v-on:click="cropMove(10, 0)" class="btn btn-info">
            <i class="fas fa-arrow-right" />
          </button>
          <button v-on:click="cropMove(0, -10)" class="btn btn-info">
            <i class="fas fa-arrow-up" />
          </button>
          <button v-on:click="cropMove(0, 10)" class="btn btn-info">
            <i class="fas fa-arrow-down" />
          </button>
        </div>
        <div class="btn-group mr-2" role="group" aria-label="Scale">
          <button v-on:click="cropScaleX()" class="btn btn-info">
            <i class="fas fa-arrows-alt-h" />
          </button>
          <button v-on:click="cropScaleY()" class="btn btn-info">
            <i class="fas fa-arrows-alt-v" />
          </button>
        </div>
        <div class="btn-group mr-2" role="group" aria-label="Rotate">
          <button v-on:click="cropRotate(-45)" class="btn btn-info">
            <i class="fas fa-undo" />
          </button>
          <button v-on:click="cropRotate(45)" class="btn btn-info">
            <i class="fas fa-redo" />
          </button>
        </div>
        <div class="btn-group mr-2" role="group" aria-label="Rotate">
          <button v-on:click="cropZoom(0.1)" class="btn btn-info">
            <i class="fas fa-search-plus" />
          </button>
          <button v-on:click="cropZoom(-0.1)" class="btn btn-info">
            <i class="fas fa-search-minus" />
          </button>
        </div>
        <button
          v-on:click="cropReset()"
          v-bind:title="lang.modal.cropper.reset"
          class="btn btn-info mr-2"
        >
          <i class="fas fa-sync-alt" />
        </button>
        <button
          v-on:click="cropSave()"
          v-bind:title="lang.modal.cropper.save"
          class="btn btn-danger mr-2"
        >
          <i class="far fa-save" />
        </button>
      </div>
      <span class="d-block">
        <button v-on:click="$emit('closeCropper')" class="btn btn-light">
          {{ lang.btn.back }}
        </button>
      </span>
    </div>
  </div>
</template>

<script>
import Cropper from "cropperjs";
import translate from "@/utils/translate";

export default {
  name: "Cropper",
  mixins: [translate],
  props: {
    imgSrc: { required: true },
    maxHeight: { type: Number, required: true },
  },
  data() {
    return {
      cropper: {},
      height: 0,
      width: 0,
      x: 0,
      y: 0,
      rotate: 0,
      scaleX: 1,
      scaleY: 1,
    };
  },
  mounted() {
    // set cropper instance
    this.cropper = new Cropper(this.$refs.fmCropper, {
      preview: ".cropper-preview",
      crop: (e) => {
        this.x = Math.round(e.detail.x);
        this.y = Math.round(e.detail.y);
        this.height = Math.round(e.detail.height);
        this.width = Math.round(e.detail.width);
        this.rotate =
          typeof e.detail.rotate !== "undefined" ? e.detail.rotate : "";
        this.scaleX =
          typeof e.detail.scaleX !== "undefined" ? e.detail.scaleX : "";
        this.scaleY =
          typeof e.detail.scaleY !== "undefined" ? e.detail.scaleY : "";
      },
    });
  },
  beforeDestroy() {
    this.cropper.destroy();
  },
  computed: {
    /**
     * Selected file
     * @returns {*}
     */
    selectedItem() {
      return this.$store.getters["fm/selectedItems"][0];
    },
  },
  methods: {
    /**
     * Move
     * @param x
     * @param y
     */
    cropMove(x, y) {
      this.cropper.move(x, y);
    },

    /**
     * Scale - mirroring Y
     */
    cropScaleY() {
      this.cropper.scale(1, this.cropper.getData().scaleY === 1 ? -1 : 1);
    },

    /**
     * Scale - mirroring X
     */
    cropScaleX() {
      this.cropper.scale(this.cropper.getData().scaleX === 1 ? -1 : 1, 1);
    },

    /**
     * Rotate
     * @param grade
     */
    cropRotate(grade) {
      this.cropper.rotate(grade);
    },

    /**
     * Zoom
     * @param ratio
     */
    cropZoom(ratio) {
      this.cropper.zoom(ratio);
    },

    /**
     * Reset
     */
    cropReset() {
      this.cropper.reset();
    },

    /**
     * Set data from form
     */
    setData() {
      this.cropper.setData({
        x: this.x,
        y: this.y,
        width: this.width,
        height: this.height,
        rotate: this.rotate,
        scaleX: this.scaleX,
        scaleY: this.scaleY,
      });
    },

    /**
     * Save cropped image
     */
    cropSave() {
      this.cropper.getCroppedCanvas().toBlob(
        (blob) => {
          const formData = new FormData();
          // add disk name
          formData.append("disk", this.$store.getters["fm/selectedDisk"]);
          // add path
          formData.append("path", this.selectedItem.dirname);
          // new image
          formData.append("file", blob, this.selectedItem.basename);

          this.$store.dispatch("fm/updateFile", formData).then((response) => {
            // if file updated successfully
            if (response.data.result.status === "success") {
              // close cropper
              this.$emit("closeCropper");
            }
          });
        },
        this.selectedItem.extension !== "jpg"
          ? `image/${this.selectedItem.extension}`
          : "image/jpeg"
      );
    },
  },
};
</script>

<style lang="scss">
@import "~cropperjs/dist/cropper.css";

.fm-additions-cropper {
  overflow: hidden;

  & > .row {
    flex-wrap: nowrap;
  }

  .cropper-block {
    overflow: hidden;

    img {
      max-width: 100%;
    }
  }

  .col-sm-3 {
    overflow: auto;

    &::-webkit-scrollbar {
      display: none;
    }
  }

  .cropper-preview {
    margin-bottom: 1rem;
    overflow: hidden;
    height: 200px;

    img {
      max-width: 100%;
    }
  }

  .cropper-data {
    padding-left: 1rem;
    padding-right: 1rem;

    & > .input-group {
      margin-bottom: 0.5rem;
    }

    .input-group-prepend .input-group-text {
      min-width: 4rem;
    }

    .input-group-append .input-group-text {
      min-width: 3rem;
    }
  }

  & > .d-flex {
    padding: 1rem;
    border-top: 1px solid #e9ecef;
  }
}
</style>
