/**
 * @Datei progress-control.js
 * /
importiere Komponente aus '../../component.js';
import * as Dom from '../../utils/dom.js';
import clamp from '../../utils/clamp.js';
importiere {bind, throttle, UPDATE_REFRESH_INTERVAL} aus '../../utils/fn.js';
importiere {silencePromise} von '../../utils/promise';

importieren './seek-bar.js';

/**
 * Die Komponente Progress Control enthält die Suchleiste und den Ladefortschritt,
 * und Spielfortschritt.
 *
 * @erweitert Komponente
 * /
class ProgressControl extends Component {

  /**
   * Erzeugt eine Instanz dieser Klasse.
   *
   * @param {Player} Spieler
   *        Der `Player`, dem diese Klasse zugeordnet werden soll.
   *
   * @param {Object} [Optionen]
   *        Der Schlüssel/Wertspeicher der Playeroptionen.
   * /
  constructor(spieler, optionen) {
    super(Spieler, Optionen);
    this.handleMouseMove = throttle(bind(this, this.handleMouseMove), UPDATE_REFRESH_INTERVAL);
    this.throttledHandleMouseSeek = throttle(bind(this, this.handleMouseSeek), UPDATE_REFRESH_INTERVAL);
    this.handleMouseUpHandler_ = (e) => this.handleMouseUp(e);
    this.handleMouseDownHandler_ = (e) => this.handleMouseDown(e);

    this.enable();
  }

  /**
   * Das DOM-Element der Komponente erstellen
   *
   * @return {Element}
   *         Das Element, das erstellt wurde.
   * /
  createEl() {
    return super.createEl('div', {
      className: 'vjs-progress-control vjs-control'
    });
  }

  /**
   * Bewegt sich die Maus über das `ProgressControl`, wird die Zeigerposition
   * wird an die Komponente `MouseTimeDisplay` weitergegeben.
   *
   * @param {EventTarget~Event} event
   *        Das Ereignis "Mausbewegung", das diese Funktion ausgelöst hat.
   *
   * @listen mousemove
   * /
  handleMouseMove(event) {
    const seekBar = this.getChild('seekBar');

    if (!seekBar) {
      rückkehr;
    }

    const playProgressBar = seekBar.getChild('playProgressBar');
    const mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay');

    if (!playProgressBar && !mouseTimeDisplay) {
      rückkehr;
    }

    const seekBarEl = seekBar.el();
    const seekBarRect = Dom.findPosition(seekBarEl);
    let seekBarPoint = Dom.getPointerPosition(seekBarEl, event).x;

    // Der Standard-Skin hat eine Lücke auf beiden Seiten der `SeekBar`. Dies bedeutet
    // dass es möglich ist, dieses Verhalten außerhalb der Grenzen von
    // die `SeekBar`. Damit ist sichergestellt, dass wir uns jederzeit daran halten.
    seekBarPoint = clamp(seekBarPoint, 0, 1);

    if (mouseTimeDisplay) {
      mouseTimeDisplay.update(seekBarRect, seekBarPoint);
    }

    wenn (playProgressBar) {
      playProgressBar.update(seekBarRect, seekBar.getProgress());
    }

  }

  /**
   * Eine gedrosselte Version des {@link ProgressControl#handleMouseSeek} Listeners.
   *
   * @Methode ProgressControl#throttledHandleMouseSeek
   * @param {EventTarget~Event} event
   *        Das Ereignis "Mausbewegung", das diese Funktion ausgelöst hat.
   *
   * @listen mousemove
   * @listen touchmove
   * /

  /**
   * Behandelt "mousemove"- oder "touchmove"-Ereignisse auf dem "ProgressControl".
   *
   * @param {EventTarget~Event} event
   *        mousedown"- oder "Touchstart"-Ereignis, das diese Funktion ausgelöst hat
   *
   * @listens mousemove
   * @listens touchmove
   * /
  handleMouseSeek(event) {
    const seekBar = this.getChild('seekBar');

    wenn (seekBar) {
      seekBar.handleMouseMove(event);
    }
  }

  /**
   * Für diese Fortschrittskontrolle sind derzeit Kontrollen aktiviert.
   *
   * @return {boolean}
   *         true, wenn die Kontrollen aktiviert sind, sonst false
   * /
  aktiviert() {
    return this.enabled_;
  }

  /**
   * Alle Steuerelemente für das Fortschrittssteuerelement und seine untergeordneten Elemente deaktivieren
   * /
  deaktivieren() {
    this.children().forEach((child) => child.disable && child.disable());

    if (!this.enabled()) {
      rückkehr;
    }

    this.off(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
    this.off(this.el_, 'mousemove', this.handleMouseMove);

    this.removeListenersAddedOnMousedownAndTouchstart();

    this.addClass('disabled');

    this.enabled_ = false;

    // Wiederherstellung des normalen Wiedergabestatus, wenn die Steuerelemente während des Scrubbing deaktiviert sind
    if (this.player_.scrubbing()) {
      const seekBar = this.getChild('seekBar');

      this.player_.scrubbing(false);

      if (seekBar.videoWasPlaying) {
        silencePromise(this.player_.play());
      }
    }
  }

  /**
   * Aktivieren Sie alle Steuerelemente für das Fortschrittssteuerelement und seine untergeordneten Elemente
   * /
  enable() {
    this.children().forEach((child) => child.enable && child.enable());

    if (this.enabled()) {
      rückkehr;
    }

    this.on(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
    this.on(this.el_, 'mousemove', this.handleMouseMove);
    this.removeClass('disabled');

    this.enabled_ = true;
  }

  /**
   * Cleanup-Listener, nachdem der Benutzer die Interaktion mit den Fortschrittskontrollen beendet hat
   * /
  removeListenersAddedOnMousedownAndTouchstart() {
    const doc = this.el_.ownerDocument;

    this.off(doc, 'mousemove', this.throttledHandleMouseSeek);
    this.off(doc, 'touchmove', this.throttledHandleMouseSeek);
    this.off(doc, 'mouseup', this.handleMouseUpHandler_);
    this.off(doc, 'touchend', this.handleMouseUpHandler_);
  }

  /**
   * Behandelt "Mousedown"- oder "Touchstart"-Ereignisse auf dem "ProgressControl".
   *
   * @param {EventTarget~Event} event
   *        mousedown"- oder "Touchstart"-Ereignis, das diese Funktion ausgelöst hat
   *
   * @listens mousedown
   * @listens touchstart
   * /
  handleMouseDown(event) {
    const doc = this.el_.ownerDocument;
    const seekBar = this.getChild('seekBar');

    wenn (seekBar) {
      seekBar.handleMouseDown(event);
    }

    this.on(doc, 'mousemove', this.throttledHandleMouseSeek);
    this.on(doc, 'touchmove', this.throttledHandleMouseSeek);
    this.on(doc, 'mouseup', this.handleMouseUpHandler_);
    this.on(doc, 'touchend', this.handleMouseUpHandler_);
  }

  /**
   * Behandelt `Mouseup` oder `Touchend` Ereignisse auf dem `ProgressControl`.
   *
   * @param {EventTarget~Event} event
   *        mouseup"- oder "Touchend"-Ereignis, das diese Funktion ausgelöst hat.
   *
   * @listens berührend
   * @listens mouseup
   * /
  handleMouseUp(event) {
    const seekBar = this.getChild('seekBar');

    wenn (seekBar) {
      seekBar.handleMouseUp(event);
    }

    this.removeListenersAddedOnMousedownAndTouchstart();
  }
}

/**
 * Standardoptionen für `ProgressControl`
 *
 * @Typ {Objekt}
 * @privat
 * /
ProgressControl.prototype.options_ = {
  kinder: [
    'seekBar'
  ]
};

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