/**
 * @file volume-control.js
 */
import Component from '../../component.js' ;
import checkVolumeSupport de './check-volume-support' ;
import {isPlain} from '../../utils/obj' ;
import {throttle, bind, UPDATE_REFRESH_INTERVAL} from '../../utils/fn.js' ;

// Enfants requis
import './volume-bar.js' ;

/**
 * Le composant permettant de contrôler le niveau de volume
 *
 * @extends Component
 */
class VolumeControl extends Component {

  /**
   * Crée une instance de cette classe.
   *
   * @param {Player} player
   *        Le `Player` auquel cette classe doit être attachée.
   *
   * @param {Objet} [options={}]
   *        La mémoire clé/valeur des options du lecteur.
   */
  constructor(player, options = {}) {
    options.vertical = options.vertical || false ;

    // Transmettre l'option verticale à la barre de volume si
    // la barre de volume est activée.
    if (typeof options.volumeBar === 'undefined' || isPlain(options.volumeBar)) {
      options.volumeBar = options.volumeBar || {} ;
      options.volumeBar.vertical = options.vertical ;
    }

    super(player, options) ;

    // cacher ce contrôle si le volume n'est pas pris en charge
    checkVolumeSupport(this, player) ;

    this.throttledHandleMouseMove = throttle(bind(this, this.handleMouseMove), UPDATE_REFRESH_INTERVAL) ;
    this.handleMouseUpHandler_ = (e) => this.handleMouseUp(e) ;

    this.on('mousedown', (e) => this.handleMouseDown(e)) ;
    this.on('touchstart', (e) => this.handleMouseDown(e)) ;
    this.on('mousemove', (e) => this.handleMouseMove(e)) ;

    // lorsque le curseur est actif (la souris a été enfoncée et le curseur a été déplacé)
    // est en train de glisser) ou dans le focus, nous ne voulons pas cacher la barre de volume
    this.on(this.volumeBar, ['focus', 'slideractive'], () => {
      this.volumeBar.addClass('vjs-slider-active') ;
      this.addClass('vjs-slider-active') ;
      this.trigger('slideractive') ;
    }) ;

    this.on(this.volumeBar, ['blur', 'sliderinactive'], () => {
      this.volumeBar.removeClass('vjs-slider-active') ;
      this.removeClass('vjs-slider-active') ;
      this.trigger('sliderinactive') ;
    }) ;
  }

  /**
   * Créer l'élément DOM du `Composant`
   *
   * @return {Element}
   *         L'élément qui a été créé.
   */
  createEl() {
    let orientationClass = 'vjs-volume-horizontal' ;

    if (this.options_.vertical) {
      orientationClass = 'vjs-volume-vertical' ;
    }

    return super.createEl('div', {
      className : `vjs-volume-contrôle vjs-contrôle ${orientationClass}`
    }) ;
  }

  /**
   * Gère les événements `mousedown` ou `touchstart` sur le `VolumeControl`.
   *
   * @param {EventTarget~Event} event
   *        événement `mousedown` ou `touchstart` qui a déclenché cette fonction
   *
   * @listens mousedown
   * @listens touchstart
   */
  handleMouseDown(event) {
    const doc = this.el_.ownerDocument ;

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

  /**
   * Gère les événements `mouseup` ou `touchend` sur le `VolumeControl`.
   *
   * @param {EventTarget~Event} event
   *        l'événement `mouseup` ou `touchend` qui a déclenché cette fonction.
   *
   * @listens touchend
   * @listens mouseup
   */
  handleMouseUp(event) {
    const doc = this.el_.ownerDocument ;

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

  /**
   * Gère les événements `mousedown` ou `touchstart` sur le `VolumeControl`.
   *
   * @param {EventTarget~Event} event
   *        événement `mousedown` ou `touchstart` qui a déclenché cette fonction
   *
   * @listens mousedown
   * @listens touchstart
   */
  handleMouseMove(event) {
    this.volumeBar.handleMouseMove(event) ;
  }
}

/**
 * Options par défaut pour la commande `VolumeControl`
 *
 * @type {Objet}
 * @private
 */
VolumeControl.prototype.options_ = {
  enfants : [
    volumeBar
  ]
};

Component.registerComponent('VolumeControl', VolumeControl) ;
exporter le contrôle de volume par défaut ;