/**
 * @file progress-control.js
 */
從 '../../component.js' 導入組件;
import * as Dom from '../../utils/dom.js';
從 '../../utils/clamp.js' 導入箝位;
從 '../../utils/fn.js' 導入 {bind, throttle, UPDATE_REFRESH_INTERVAL};
從'../../utils/promise'導入{silencePromise};

導入'./seek-bar.js';

/**
 * Progress Control組件包含搜索欄,加載進度,
 * 和播放進度。
 *
 * @extends 組件
 */
類 ProgressControl 擴展組件 {

  /**
   * 創建此類的一個實例。
   *
   * @param {Player} 播放器
   * 此類應附加到的 `Player`。
   *
   * @param {對象} [選項]
   * 播放器選項的鍵/值存儲。
   */
  構造函數(播放器,選項){
    超級(播放器,選項);
    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);

    這個。啟用();
  }

  /**
   * 創建 `Component` 的 DOM 元素
   *
   * @return {元素}
   * 創建的元素。
   */
  創建El() {
    返回 super.createEl('div', {
      className: 'vjs-progress-control vjs-control'
    });
  }

  /**
   * 當鼠標移到`ProgressControl`上時,指針位置
   * 向下傳遞到“MouseTimeDisplay”組件。
   *
   * @param {EventTarget~Event} 事件
   * 導致此函數運行的 `mousemove` 事件。
   *
   * @listen 鼠標移動
   */
  handleMouseMove(事件){
    const seekBar = this.getChild('seekBar');

    如果(!seekBar){
      返回;
    }

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

    如果 (!playProgressBar && !mouseTimeDisplay) {
      返回;
    }

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

    // 默認皮膚在 `SeekBar` 的兩側都有一個間隙。這意味著
    // 可以在邊界之外觸發此行為
    // `SeekBar`。這確保我們始終留在其中。
    seekBarPoint = clamp(seekBarPoint, 0, 1);

    如果(鼠標時間顯示){
      mouseTimeDisplay.update(seekBarRect, seekBarPoint);
    }

    如果(播放進度條){
      playProgressBar.update(seekBarRect, seekBar.getProgress());
    }

  }

  /**
   * {@link ProgressControl#handleMouseSeek} 偵聽器的節流版本。
   *
   * @method ProgressControl#throttledHandleMouseSeek
   * @param {EventTarget~Event} 事件
   * 導致此函數運行的 `mousemove` 事件。
   *
   * @listen 鼠標移動
   * @listen touchmove
   */

  /**
   * 處理 `ProgressControl` 上的 `mousemove` 或 `touchmove` 事件。
   *
   * @param {EventTarget~Event} 事件
   * 觸發此功能的 `mousedown` 或 `touchstart` 事件
   *
   * @listens 鼠標移動
   * @listens touchmove
   */
  handleMouseSeek(事件){
    const seekBar = this.getChild('seekBar');

    如果(搜索欄){
      seekBar.handleMouseMove(事件);
    }
  }

  /**
   * 當前是否為此進度控件啟用了控件。
   *
   * @return {布爾值}
   * 如果啟用控件則為 true,否則為 false
   */
  啟用(){
    返回 this.enabled_;
  }

  /**
   * 禁用進度控件及其子控件的所有控件
   */
  禁用(){
    this.children().forEach((child) => child.disable && child.disable());

    如果(!this.enabled()){
      返回;
    }

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

    this.removeListenersAddedOnMousedownAndTouchstart();

    this.addClass('禁用');

    this.enabled_ = false;

    // 如果在擦洗時控件被禁用,則恢復正常播放狀態
    如果 (this.player_.scrubbing()) {
      const seekBar = this.getChild('seekBar');

      this.player_.scrubbing(false);

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

  /**
   * 啟用進度控件及其子控件的所有控件
   */
  使能夠() {
    this.children().forEach((child) => child.enable && child.enable());

    如果(this.enabled()){
      返回;
    }

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

    this.enabled_ = true;
  }

  /**
   * 在用戶完成與進度控件的交互後清理監聽器
   */
  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_);
  }

  /**
   * 處理 `ProgressControl` 上的 `mousedown` 或 `touchstart` 事件。
   *
   * @param {EventTarget~Event} 事件
   * 觸發此功能的 `mousedown` 或 `touchstart` 事件
   *
   * @listens mousedown
   * @listens touchstart
   */
  handleMouseDown(事件){
    const doc = this.el_.ownerDocument;
    const seekBar = this.getChild('seekBar');

    如果(搜索欄){
      seekBar.handleMouseDown(事件);
    }

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

  /**
   * 處理 `ProgressControl` 上的 `mouseup` 或 `touchend` 事件。
   *
   * @param {EventTarget~Event} 事件
   * 觸發此功能的 `mouseup` 或 `touchend` 事件。
   *
   * @listens touchend
   * @listens mouseup
   */
  handleMouseUp(事件){
    const seekBar = this.getChild('seekBar');

    如果(搜索欄){
      seekBar.handleMouseUp(事件);
    }

    this.removeListenersAddedOnMousedownAndTouchstart();
  }
}

/**
 * `ProgressControl` 的默認選項
 *
 * @type {對象}
 * @私人的
 */
ProgressControl.prototype.options_ = {
  孩子們: [
    '搜索欄'
  ]
};

Component.registerComponent('ProgressControl', ProgressControl);
導出默認 ProgressControl;