/**
 * jpictures.js
 * JavaScript functions for the pictures galleries.
 */
"use strict";

// Import PhotoSwipe Lightbox
import PhotoSwipe from './photoswipe/photoswipe.esm.min.js';
import PhotoSwipeLightbox from './photoswipe/photoswipe-lightbox.esm.min.js';
import PhotoSwipeDynamicCaption from './photoswipe/photoswipe-dynamic-caption-plugin.esm.js'

// Import internationalization support
import i18n from './../i18n.js';

class PhotoSwipePictureGallery {
  constructor(items) {
    // Create PhotoSwipe Lightbox
    const lightboxOptions = {
      dataSource: items,
      pswpModule: PhotoSwipe,
      bgOpacity: 0.95,
      closeOnVerticalDrag: false,
      closeTitle: i18n.viewer_close + ' (Esc)',
      zoomTitle: i18n.viewer_zoom + ' (z)',
      arrowPrevTitle: i18n.viewer_previous,
      arrowNextTitle: i18n.viewer_next,
    };
    this.lightbox = new PhotoSwipeLightbox(lightboxOptions);

    // Initialize caption plugin
    const captionPluginOptions = {
      type: 'below',
      mobileLayoutBreakpoint: 800,
      captionContent: (slide) => {
        return this._captionContent(slide)
      },
    };
    this.captionPlugin = new PhotoSwipeDynamicCaption(this.lightbox, captionPluginOptions);

    // Add custom 'Info' button, see https://photoswipe.com/v5/docs/adding-custom-buttons/
    // Info menu button
    const infoButton = {
      name: 'info',
      title: i18n.viewer_toggle_caption,
      order: 15, // Insert button between zoom & close buttons
      isButton: true,
      html: {
        isCustomSVG: true,
        inner: '<path d="M7 16a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" id="pswp__icn-info"/>'
              + '<path fill="currentColor" d="M17 15h-2v6h2z"/>'
              + '<path fill="currentColor" d="M17 11h-2v2h2z"/>',
        outlineID: 'pswp__icn-info',
      },
      onClick: (ev, el, pswp) => {
        this._toggleInfoPannel(ev, el, pswp);
      },
    };
    this.lightbox.on('uiRegister', () => {
      this.lightbox.pswp.ui.registerElement(infoButton);
    });

    this.lightbox.on('calcSlideSize', (e) => {
      /* When using mobile layout for caption, hide the Info button since the caption is fixed
       * at the bottom. */
      if (this.captionPlugin.useMobileLayout()) {
        document.querySelector('.pswp__button--info').style.display = 'none';
      } else {
        document.querySelector('.pswp__button--info').style.display = '';
      }
    });
  }

  // Open gallery at the given slide index (starting at 0)
  open(index) {
    this.lightbox.init();
    this.lightbox.loadAndOpen(index);
  }

  // Switch between regular caption (below image) and info pannel (aside)
  _toggleInfoPannel(ev, el, pswp) {
    if (this.captionPlugin.options.type === 'below') {
      this.captionPlugin.options.type = 'aside';
    } else if (this.captionPlugin.options.type === 'aside') {
      this.captionPlugin.options.type = 'below';
    }
    /* Force updating size of all PhotoSwipe elements. This will trigger the 'calcSlideSize' event
     * on each loaded slide, causing update of the caption text (see handler above). */
    this.lightbox.pswp.updateSize(true);
  }

  _convertDate(iso8601_date) {
    const d = new Date(iso8601_date);
    const str = d.toLocaleDateString() + ' ' + d.toLocaleTimeString().replace(/(\d{2}):(\d{2}):(\d{2})/, '$1h$2');
    return str;
  }

  // Get caption content, according to current image & caption layout
  _captionContent(slide) {
    const slideTitle    = slide.data.title;
    const slideDateTime = this._convertDate(slide.data.datetime, true);

    if (this.captionPlugin.options.type === 'aside' && !this.captionPlugin.useMobileLayout()) {
      var caption = '<strong>' + slideTitle + '</strong><hr />' +
                    '<p class="pswp__caption__exif pswp__caption__exif_datetime">' + slideDateTime + '</p>';
      if (slide.data.artist) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_author">' + slide.data.artist + '</p>';
      }
      if (slide.data.event) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_event">' + slide.data.event + '</p>';
      }
      if (slide.data.city || slide.data.region) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_location">';
        if (slide.data.city) { caption += slide.data.city; }
        if (slide.data.city && slide.data.region) { caption += ', '; }
        if (slide.data.region) { caption += slide.data.region; }
        caption += '</p>';
      }
      if (slide.data.model) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_camera">' + slide.data.model + '</p>';
      }
      if (slide.data.focallength) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_focal">' + slide.data.focallength + '</p>';
      }
      if (slide.data.fnumber) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_fstop">' + slide.data.fnumber + '</p>';
      }
      if (slide.data.exposure) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_shutter">' + slide.data.exposure + '</p>';
      }
      if (slide.data.isospeed) {
        caption += '<p class="pswp__caption__exif pswp__caption__exif_iso">' + 'ISO ' + slide.data.isospeed + '</p>';
      }
      return caption;
    } else {
      return '<strong>' + slideDateTime + '</strong> &mdash; ' + slideTitle;
    }
  }
}

function createImageGallery(json) {
  var items = [];
  for (let i = 0; i < json.length; i++) {
    var imageData = json[i];
    imageData.src = 'api/picture?id=' + json[i].id; // Add 'src' field required by PhotoSwipe
    items.push(imageData);
  }

  const gallery = new PhotoSwipePictureGallery(items);
  gallery.open(0); // start at first slide
}

// Export this function so that it may be called from HTML
function openImagesGallery(selectors) {
  fetch('api/pictures?' + selectors) // selectors is not empty
    .then(response => response.json())
    .then(data => createImageGallery(data));
}
window.openImagesGallery = openImagesGallery;