/**
 * @file picture-in-picture-toggle.js
 */
import Button from '../button.js';
import Component from '../component.js';
import document from 'global/document';
import window from 'global/window';

/**
 * Toggle Picture-in-Picture mode
 *
 * @extends Button
 */
class PictureInPictureToggle extends Button {

  /**
   * Creates an instance of this class.
   *
   * @param { import('./player').default } player
   *        The `Player` that this class should be attached to.
   *
   * @param {Object} [options]
   *        The key/value store of player options.
   *
   * @listens Player#enterpictureinpicture
   * @listens Player#leavepictureinpicture
   */
  constructor(player, options) {
    super(player, options);
    this.on(player, ['enterpictureinpicture', 'leavepictureinpicture'], (e) => this.handlePictureInPictureChange(e));
    this.on(player, ['disablepictureinpicturechanged', 'loadedmetadata'], (e) => this.handlePictureInPictureEnabledChange(e));

    this.on(player, ['loadedmetadata', 'audioonlymodechange', 'audiopostermodechange'], () => {
      // This audio detection will not detect HLS or DASH audio-only streams because there was no reliable way to detect them at the time
      const isSourceAudio = player.currentType().substring(0, 5) === 'audio';

      if (isSourceAudio || player.audioPosterMode() || player.audioOnlyMode()) {
        if (player.isInPictureInPicture()) {
          player.exitPictureInPicture();
        }
        this.hide();
      } else {
        this.show();
      }

    });

    // TODO: Deactivate button on player emptied event.
    this.disable();
  }

  /**
   * Builds the default DOM `className`.
   *
   * @return {string}
   *         The DOM `className` for this object.
   */
  buildCSSClass() {
    return `vjs-picture-in-picture-control ${super.buildCSSClass()}`;
  }

  /**
   * Enables or disables button based on availability of a Picture-In-Picture mode.
   *
   * Enabled if
   * - `player.options().enableDocumentPictureInPicture` is true and
   *   window.documentPictureInPicture is available; or
   * - `player.disablePictureInPicture()` is false and
   *   element.requestPictureInPicture is available
   */
  handlePictureInPictureEnabledChange() {
    if (
      (document.pictureInPictureEnabled && this.player_.disablePictureInPicture() === false) ||
      (this.player_.options_.enableDocumentPictureInPicture && 'documentPictureInPicture' in window)
    ) {
      this.enable();
    } else {
      this.disable();
    }
  }

  /**
   * Handles enterpictureinpicture and leavepictureinpicture on the player and change control text accordingly.
   *
   * @param {Event} [event]
   *        The {@link Player#enterpictureinpicture} or {@link Player#leavepictureinpicture} event that caused this function to be
   *        called.
   *
   * @listens Player#enterpictureinpicture
   * @listens Player#leavepictureinpicture
   */
  handlePictureInPictureChange(event) {
    if (this.player_.isInPictureInPicture()) {
      this.controlText('Exit Picture-in-Picture');
    } else {
      this.controlText('Picture-in-Picture');
    }
    this.handlePictureInPictureEnabledChange();
  }

  /**
   * This gets called when an `PictureInPictureToggle` is "clicked". See
   * {@link ClickableComponent} for more detailed information on what a click can be.
   *
   * @param {Event} [event]
   *        The `keydown`, `tap`, or `click` event that caused this function to be
   *        called.
   *
   * @listens tap
   * @listens click
   */
  handleClick(event) {
    if (!this.player_.isInPictureInPicture()) {
      this.player_.requestPictureInPicture();
    } else {
      this.player_.exitPictureInPicture();
    }
  }

}

/**
 * The text that should display over the `PictureInPictureToggle`s controls. Added for localization.
 *
 * @type {string}
 * @protected
 */
PictureInPictureToggle.prototype.controlText_ = 'Picture-in-Picture';

Component.registerComponent('PictureInPictureToggle', PictureInPictureToggle);
export default PictureInPictureToggle;