<!--
 Assetmanager todo:
  - Tonen van maten in overzicht en detail
  - Bestandsnaam (titel in overzicht) kunnen aanpassen
  - tags bij afbeeldingen (en filteren)
  - Opschonen van assets (alleen assets die nergens gebruikt worden)
  - Lijst van pagina's waar de asset gebruikt wordt
  - Updaten van afbeeldingen in een asset
  - In overzicht, sorteren op created/updated date
  - Delete-button enkel enabled zetten als asset nergens gebruikt wordt
  - Zoeken op naam (nice to have)
  - Aantal KB's in detail scherm
-->
<template>
  <form @submit.prevent="saveAsset">
    <div class="form-group row">
      <div class="col-sm-8">
        <fieldset>
          <legend>Eigenschappen</legend>
          <field label="Titel">
            <input type="text" class="form-control" v-model="asset.title">
          </field>

          <field label="Alt tekst">
            <input type="text" class="form-control" v-model="asset.alt">
          </field>

          <field label="Bestand" v-if="isNew">
            <input type="file" @change="selectFile($event.target.files[0])" class="form-control-file"/>
          </field>

          <field label="Bestandstype" v-if="asset.blobstoreUrl">
            <input type="text" class="form-control" v-model="asset.contentType" readonly>
          </field>

          <field label="Afmetingen" v-if="asset.width">
            <input type="text" class="form-control" v-model="imageDimensions" readonly>
          </field>

          <field label="Download URL" v-if="!imageUrl && asset.blobstoreUrl">
            <input type="text" class="form-control" v-model="asset.blobstoreUrl" readonly>
          </field>

          <field label="Genereer URL">
            <div class="form-group form-row-url">
              <input type="number" class="form-control form-row-url-input" v-model="generateDimension" placeholder="Aantal pixels">
              <div class="form-row-url-button">
                <input id="width" type="radio" value="width" v-model="generateWidthOrHeight"> <label for="width">breed</label>
              </div>
              <div class="form-row-url-button">
                <input id="height" type="radio" value="height" v-model="generateWidthOrHeight"> <label for="height">hoog</label>
              </div>
            </div>
            <button type="button" class="btn btn-primary" @click="generate">Genereer</button>
          </field>
          <field v-if="!!generatedUrl">
            <input type="text" class="form-control" v-model="generatedUrl" readonly>
          </field>

        </fieldset>
      </div>
      <div class="col-sm-4">
        <loader>
          <div class="card" v-if="imageUrl">
            <img ref="img" :src="imageUrl" @load="updatePreviewUrl" crossorigin="anonymous" v-if="imageUrl != asset.blobstoreUrl"/> <img :src="imageUrl"
                                                                                                                                         v-if="imageUrl == asset.blobstoreUrl"/>
          </div>
        </loader>
      </div>
    </div>

    <div class="form-group form-controls">
      <button @click.prevent="remove" class="btn btn-danger mr-2" :disabled="!permissions.canDelete" v-if="!isNew">Verwijderen</button>
      <button type="submit" class="btn btn-primary mr-2" :disabled="!permissions.canUpdate || !canSubmit">Opslaan</button>
      <button @click.prevent="cancel" class="btn btn-secondary-outline">Annuleren</button>
    </div>

    <confirm-dialog ref="dialog"></confirm-dialog>

  </form>

</template>

<style lang="scss" scoped>
  .card {
    background: rgba(204, 204, 204, .3) repeating-linear-gradient(45deg, transparent, transparent 5px, rgba(255, 255, 255, .2) 5px, rgba(255, 255, 255, .2) 10px);
    display: block; // override flex from bootstrap
    text-align: center;
  }

  img {
    max-width: 100%;
    max-height: 250px;
  }

  .form-controls {
    display: flex;

    button:first-child {
      margin-left: auto;
    }
  }

  .form-row-url {
    display: flex;
    justify-content: space-between;

    &-input {
      flex: 1 1 auto;
      margin-right: 10px;
    }

    &-button {
      width: 100px;
      display: flex;
      justify-content: flex-end;
      align-items: center;

      input {
        margin-right: 5px;
      }

      label {
        margin-bottom: 0;
      }
    }
  }
</style>

<script>
  var StackBlur = require("stackblur-canvas/src/stackblur.js");

  import {ServerStore} from '../tools/server-store.js';
  import {compress} from '../tools/image-preview.js';
  import {assetStore} from '../tools/asset-store.js';
  import {permissionStore} from '../tools/permission-store';

  import confirmDialog from '../shared/form/confirm-dialog.vue';
  import field from '../shared/form/field.vue';
  import assetTagPicker from './asset-tag-picker.vue';
  import loader from '../shared/loader.vue';

  export default {
    name: 'asset-detail',
    props: {
      value: {
        type: Object,
        required: false
      },
      assetProp: {}
    },
    data() {
      return {
        serverStore: new ServerStore(),
        selectedFile: null,
        selectedFileDataUrl: null,
        isLoading: false,
        generatedUrl: null,
        generateDimension: null,
        generateWidthOrHeight: "width",
        asset: this.assetProp || {
          title: '',
          alt: '',
          tags: [],
          blobstoreUrl: '',
          previewData: ''
        }
      };
    },
    methods: {
      saveAsset() {
        const promise = this.isNew ? assetStore.createAsset(this.asset, this.selectedFile) : assetStore.updateAsset(this.asset);

        promise.then(asset => {
          this.$emit('input', asset); // vue syntax: update prop 'value' in the parent
          this.$store.dispatch('alerts/addSuccess', 'De asset is opgeslagen')
        })
          .catch(e => this.$store.dispatch('alerts/addError', `Opslaan is niet gelukt! <br> ${e.message}`));
      },
      selectFile(file) {
        this.selectedFile = file;
        if (this.selectedFile) {
          var reader = new FileReader();
          reader.onloadstart = () => {
            this.isLoading = true;
          };
          reader.onloadend = () => {
            this.isLoading = false;
          };
          reader.onload = (e) => {
            this.selectedFileDataUrl = e.target.result;
          };
          reader.readAsDataURL(this.selectedFile);
        }
      },
      remove() {
        this.$refs.dialog.confirm("Asset verwijderen", "Weet je zeker dat je deze asset wilt verwijderen?")
          .then(() => {
            assetStore.deleteAsset(this.asset)
              .then(() => {
                this.$emit('input', null);
                this.$store.dispatch('alerts/addSuccess', 'De asset is verwijderd');
              })
              .catch(error => {
                if (error.isReferenceError) {
                  this.$emit('deleteError', error);
                }

                this.$store.dispatch('alerts/addError', `Verwijderen is niet gelukt! <br> ${error.message}`)

                throw error;
              });
          }, () => {
            // intentionally empty for removing console error when dismissing dialog
          });
      },
      cancel() {
        this.$emit('input', null); // vue syntax: update prop 'value' in the parent
      },
      updatePreviewUrl() {
        const cnv = document.createElement('canvas');
        const ctx = cnv.getContext('2d');

        // add width/height for new images only
        if (this.isNew) {
          this.asset.width = this.$refs.img.naturalWidth;
          this.asset.height = this.$refs.img.naturalHeight;
        }

        const maxSize = 32;
        const ratio = this.$refs.img.naturalWidth / this.$refs.img.naturalHeight;
        const width = cnv.width = Math.min(maxSize, Math.round(maxSize * ratio));
        const height = cnv.height = Math.min(maxSize, Math.round(maxSize / ratio));

        ctx.drawImage(this.$refs.img, 0, 0, width, height);
        StackBlur.canvasRGBA(cnv, 0, 0, width, height, 5);

        this.asset.previewData = compress(cnv);
      },
      generate() {
        this.generatedUrl = null;
        const path = `/assets/generate-url/${this.asset.id}?${this.generateWidthOrHeight}=${this.generateDimension}`;
        this.serverStore.fetch(path, '', {method: 'get'}).then(res => {
          this.generatedUrl = res;
        });
      }
    },
    computed: {
      permissions() {
        return permissionStore.getPermissions('CmsAsset');
      },
      isNew() {
        return !this.asset.id;
      },
      imageUrl() {
        if (this.selectedFileDataUrl && this.selectedFile.type.startsWith('image/')) {
          return this.selectedFileDataUrl;
        }
        return assetStore.previewUrl(this.asset);
      },
      canSubmit() {
        return (this.asset.blobstoreUrl || this.selectedFile) && this.asset.title;
      },
      imageDimensions() {
        return this.asset.width + ' x ' + this.asset.height;
      }
    },
    components: {
      confirmDialog,
      field,
      assetTagPicker,
      loader
    }
  };
</script>
