/**
 * @file
 * Audiofield build Wavesurfer audio player.
 */

(($, Drupal) => {
  'use strict';

  Drupal.AudiofieldWavesurfer = {};

  /**
   * Generate a wavesurfer player.
   *
   * @param {jQuery} context
   *   The Drupal context for which we are finding and generating this player.
   * @param {array} file
   *   The audio file for which we are generating a player.
   * @param {jQuery} settings
   *   The Drupal settings for this player..
   */
  Drupal.AudiofieldWavesurfer.generate = (context, file, settings) => {
    $.each($(context).find(`#${file.id}`).once('generate-waveform'), (index, wavecontainer) => {
      // Create waveform.
      const wavesurfer = WaveSurfer.create({
        container: `#${$(wavecontainer).attr('id')} .waveform`,
      });

      // Load the file.
      wavesurfer.load(file.path);

      // Set the default volume.
      wavesurfer.setVolume(settings.volume);

      // Handle play/pause.
      $(wavecontainer).find('.player-button.playpause').on('click', () => {
        Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
      });

      // Handle volume change.
      $(wavecontainer).find('.volume').on('change', () => {
        wavesurfer.setVolume(($(event.currentTarget).val() / 10));
      });

      // Handle autoplay.
      if (!!settings.autoplay) {
        wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
      }
    });
  };

  /**
   * Generate a wavesurfer playlist player.
   *
   * @param {jQuery} context
   *   The Drupal context for which we are finding and generating this player.
   * @param {jQuery} settings
   *   The Drupal settings for this player.
   */
  Drupal.AudiofieldWavesurfer.generatePlaylist = (context, settings) => {
    $.each($(context).find('#wavesurfer_playlist').once('generate-waveform'), (index, wavecontainer) => {
      // Create waveform.
      const wavesurfer = WaveSurfer.create({
        container: `#${$(wavecontainer).attr('id')} .waveform`,
      });

      // Set the default volume.
      wavesurfer.setVolume(settings.volume);

      // Load the first file.
      const first = $(wavecontainer).find('.playlist .track').first();
      // Get the label and update it with the first filename.
      const label = $(wavecontainer).find('label').first();
      label.html(`Playing: ${first.html()}`);
      // Set the playing class on the first element.
      first.addClass('playing');
      // Load the file.
      wavesurfer.load(first.attr('data-src'));

      // Handle play/pause.
      $(wavecontainer).find('.player-button.playpause').on('click', () => {
        Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
      });

      // Handle next/previous.
      $(wavecontainer).find('.player-button.next').on('click', () => {
        Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
      });
      $(wavecontainer).find('.player-button.previous').on('click', () => {
        Drupal.AudiofieldWavesurfer.Previous(wavecontainer, wavesurfer);
      });

      // Handle clicking track.
      $(wavecontainer).find('.playlist .track').on('click', () => {
        // Load the track.
        Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
        // Play the track.
        Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
      });

      // Handle volume change.
      $(wavecontainer).find('.volume').on('change', () => {
        wavesurfer.setVolume(($(event.currentTarget).val() / 10));
      });

      // Handle autoplay.
      if (!!settings.autoplay) {
        wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
      }

      // Handle track finishing.
      wavesurfer.on('finish', () => {
        Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
      });
    });
  };

  /**
   * Play or pause the wavesurfer and set appropriate classes.
   *
   * @param {jQuery} wavecontainer
   *   The container of the wavesurfer element we are accessing.
   * @param {jQuery} wavesurfer
   *   The wavesurfer player we are accessing.
   */
  Drupal.AudiofieldWavesurfer.PlayPause = (wavecontainer, wavesurfer) => {
    wavesurfer.playPause();
    const button = $(wavecontainer).find('.player-button.playpause');
    if (wavesurfer.isPlaying()) {
      $(wavecontainer).addClass('playing');
      button.html('Pause');
    }
    else {
      $(wavecontainer).removeClass('playing');
      button.html('Play');
    }
  };

  /**
   * Load track on wavesurfer and set appropriate classes.
   *
   * @param {jQuery} wavecontainer
   *   The container of the wavesurfer element we are accessing.
   * @param {jQuery} wavesurfer
   *   The wavesurfer player we are accessing.
   * @param {jQuery} track
   *   The track being loaded into the player.
   */
  Drupal.AudiofieldWavesurfer.Load = (wavecontainer, wavesurfer, track) => {
    // Load the track.
    wavesurfer.on('ready', () => {
      wavesurfer.play();
      $(wavecontainer).removeClass('playing');
      $(wavecontainer).addClass('playing');
      $(wavecontainer).find('.player-button.playpause').html('Pause');
    });
    wavesurfer.load(track.attr('data-src'));
    // Remove playing from all other tracks.
    $(wavecontainer).find('.track').removeClass('playing');
    // Set the class on this track.
    track.addClass('playing');
    // Show what's playing.
    $(wavecontainer).find('label').first().html(`Playing: ${track.html()}`);
  };

  /**
   * Skip track forward on wavesurfer and set appropriate classes.
   *
   * @param {jQuery} wavecontainer
   *   The container of the wavesurfer element we are accessing.
   * @param {jQuery} wavesurfer
   *   The wavesurfer player we are accessing.
   */
  Drupal.AudiofieldWavesurfer.Next = (wavecontainer, wavesurfer) => {
    if (wavesurfer.isPlaying()) {
      Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
    }
    // Find the next track.
    let track = $(wavecontainer).find('.track.playing').next();
    if (typeof track.attr('data-src') === 'undefined') {
      track = $(wavecontainer).find('.track').first();
    }
    // Load the track.
    Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, track);
  };

  /**
   * Skip track back on wavesurfer and set appropriate classes.
   *
   * @param {jQuery} wavecontainer
   *   The container of the wavesurfer element we are accessing.
   * @param {jQuery} wavesurfer
   *   The wavesurfer player we are accessing.
   */
  Drupal.AudiofieldWavesurfer.Previous = (wavecontainer, wavesurfer) => {
    if (wavesurfer.isPlaying()) {
      Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
    }
    // Find the next track.
    let track = $(wavecontainer).find('.track.playing').prev();
    if (typeof track.attr('data-src') === 'undefined') {
      track = $(wavecontainer).find('.track').last();
    }
    // Load the track.
    Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, track);
  };

  /**
   * Attach the behaviors to generate the audio player.
   *
   * @type {Drupal~behavior}
   *
   * @prop {Drupal~behaviorAttach} attach
   *   Attaches generation of Wavesurfer audio players.
   */
  Drupal.behaviors.audiofieldwavesurfer = {
    attach: (context, settings) => {
      $.each(settings.audiofieldwavesurfer, (key, settingEntry) => {
        // Default audio player.
        if (settingEntry.playertype === 'default') {
          // Loop over the files.
          $.each(settingEntry.files, (key2, file) => {
            Drupal.AudiofieldWavesurfer.generate(context, file, settingEntry);
          });
        }
        else if (settingEntry.playertype === 'playlist') {
          Drupal.AudiofieldWavesurfer.generatePlaylist(context, settingEntry);
        }
      });
    },
  };
})(jQuery, Drupal);
