<template>
  <div
    v-if="loaded"
    :key="name"
    :class="`rendition-collection ${name}`"
    :style="name === previewTypes.PROMOTIONAL ? `flex: 1 ${widestPromotional}px` : ''"
  >
    <h2 class="rendition-collection-title">
      {{ name }} Renditions
    </h2>
    <div class="crop-container">
      <div
        v-for="([previewKey, preview], idx) of previewList"
        :key="`${name}-${id}-${idx}`"
        :class="`crop-rendition ${name}`"
      >
        <preview-item
          v-if="loaded"
          :key="`${name}-${id}-${idx}`"
          :asset="asset"
          :aspect-ratio="preview.aspectRatio"
          :crop-guide="asset.cropGuide"
          :master-crop="asset.masterCrop"
          :cutout="cutouts[previewKey]"
          :edit-rendition="editRendition"
          :ignore-master-crop="preview['ignore-master-crop']"
          :height="getPreviewHeight(preview['ignore-master-crop'])"
          :reference-name="referenceName"
          :rendition-name="preview.name"
          :rendition-key="previewKey"
          :replaced="replacedRendition(previewKey)"
          :src="previewSource"
          :target-width="preview.width"
          :target-height="preview.height"
          :trim="preview.instruction | isTrim"
          :width="getPreviewWidth(preview['ignore-master-crop'])"
          :zoom="preview.instruction | isZoom"
          :original-dimensions="asset.dimension"
        />
      </div>
    </div>
  </div>
</template>
<script>

import { PREVIEWS_TYPES } from 'Config/constants';
import { getOriginalImageName } from 'Helpers/asset';
import { INSTRUCTIONS } from 'Helpers/images';
import PreviewItem from './PreviewItem.vue';

export default {
  components: {
    PreviewItem
  },
  filters: {
    isTrim(instruction = '') {
      // if no instruction, default to trim
      return !instruction || instruction === INSTRUCTIONS.TRIM;
    },
    isZoom(instruction = '') {
      return instruction === INSTRUCTIONS.ZOOM;
    }
  },
  props: {
    alternates: {
      type: Array,
      default: () => []
    },
    asset: {
      type: Object,
      default: () => ({})
    },
    currentlyReplacedRendition: {
      type: String,
      default: ''
    },
    cutouts: {
      type: Object,
      default: () => ({})
    },
    editRendition: {
      type: Function,
      default: () => ({})
    },
    id: {
      type: String,
      default: ''
    },
    filename: {
      type: String,
      default: ''
    },
    loaded: {
      type: Boolean,
      default: false
    },
    name: {
      type: String,
      default: ''
    },
    referenceName: {
      type: String,
      required: true
    },
    previews: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    alternatesKeys() {
      return Object.keys(this.alternates);
    },
    previewList() {
      return Object.entries(this.previews).filter(([, { type }]) => type === this.name);
    },
    previewTypes() {
      return PREVIEWS_TYPES;
    },
    // find the widest promotional
    widestPromotional() {
      const promotional = Object.values(this.previews)
          .filter(({ type }) => type === this.previewTypes.PROMOTIONAL),
        out = promotional.reduce((acc, { width }) => (acc > width ? acc : width), 0);

      return out;
    },
    previewSource() {
      return getOriginalImageName(this.asset.path, this.filename);
    }
  },
  methods: {
    /**
     * Get preview width
     * @param {Boolean} ignoreMasterCrop Whether it should ignore master crop
     * @returns {String}
     */
    getPreviewWidth(ignoreMasterCrop) {
      return this.getPreviewDimension('width', ignoreMasterCrop);
    },
    /**
     * Get preview height
     * @param {Boolean} ignoreMasterCrop Whether it should ignore master crop
     * @returns {String}
     */
    getPreviewHeight(ignoreMasterCrop) {
      return this.getPreviewDimension('height', ignoreMasterCrop);
    },
    /**
     * Get preview dimension depending on name
     * @param {string} property Property to be calculated
     * @param {Boolean} ignoreMasterCrop Whether it should ignore master crop
     * @returns {Number}
     */
    getPreviewDimension(property, ignoreMasterCrop) {
      if (!this.asset) return 0;

      if (!ignoreMasterCrop && this.asset.masterCrop) {
        const { right = 0, left = 0, bottom = 0, top = 0 } = this.asset.masterCrop,
          value = property === 'width' ? right - left : bottom - top;

        return value * this.asset.dimension[property];
      }

      return this.asset.dimension[property];
    },
    /**
     * Checks if rendition is replaced with alternate
     * @param {string} renditionKey Name of rendition to check
     * @returns {Boolean}
     */
    replacedRendition(renditionKey = '') {
      const replacedNames = [...this.alternates];

      if (this.currentlyReplacedRendition) replacedNames.push(this.currentlyReplacedRendition);

      return replacedNames.includes(renditionKey);
    }
  }
};
</script>
<style lang="scss" scoped>
  @import 'Styles/colors.scss';
  @import 'Styles/fonts.scss';

  .rendition-collection {
    flex: 100%;
    grid-column: 1;

    &.display {
      grid-row: 4;
    }

    &.promotional {
      grid-row: 3;
    }

    .rendition-collection-title {
      color: $border-color-darker;
      margin: 10px 0;
    }
  }

  .crop-rendition {
    align-items: flex-start;
    display: flex;
    justify-content: center;
    text-align: right;

    figure {
      margin: 0 20px 10px 0;

      /deep/ canvas {
        height: 150px;
      }
    }

    &.display {
      figure {
        /deep/ canvas {
          height: 300px;
        }
      }
    }
  }

  .crop-container {
    display: flex;
    flex-wrap: wrap;
  }

  @media screen and (min-width: 1600px) {

    .rendition-collection {

      &.display {
        grid-column-end: 4;
        grid-column-start: 1;
      }

      &.promotional {
        grid-column: 2;
        grid-row: 1;
        margin-left: 40px;

        .crop-container {
          display: block;

          .crop-rendition {
            justify-content: left;
          }
        }
      }
    }
  }

  @media screen and (min-width: 2200px) {

    .rendition-collection {

      &.display {
        grid-column: 2;
        grid-row: 2;
        margin-left: 40px;
      }

      &.promotional > .crop-container {
        display: flex;
      }
    }
  }
</style>
