/**
 * @file volume-bar.js
 */
import Slider from '../../slider/slider.js' ;
import Component from '../../component.js' ;
import * as Dom from '../../utils/dom.js' ;
import clamp from '../../utils/clamp.js' ;
import {IS_IOS, IS_ANDROID} from '../../utils/browser.js' ;

// Enfants requis
import './volume-level.js' ;
import './mouse-volume-level-display.js' ;

/**
 * La barre qui contient le niveau de volume et sur laquelle on peut cliquer pour ajuster le niveau
 *
 * slider @extends
 */
class VolumeBar extends Slider {

  /**
   * 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) {
    super(player, options) ;
    this.on('slideractive', (e) => this.updateLastVolume_(e)) ;
    this.on(player, 'volumechange', (e) => this.updateARIAAttributes(e)) ;
    player.ready(() => this.updateARIAAttributes()) ;
  }

  /**
   * Créer l'élément DOM du `Composant`
   *
   * @return {Element}
   *         L'élément qui a été créé.
   */
  createEl() {
    return super.createEl('div', {
      className : 'vjs-volume-bar vjs-slider-bar'
    }, {
      'aria-label' : this.localize('Volume Level'),
      aria-live" : "poli
    }) ;
  }

  /**
   * Manipuler la souris vers le bas sur la barre de volume
   *
   * @param {EventTarget~Event} event
   *        L'événement `mousedown` qui a provoqué l'exécution de ce programme.
   *
   * @listens mousedown
   */
  handleMouseDown(event) {
    if (!Dom.isSingleLeftClick(event)) {
      retour ;
    }

    super.handleMouseDown(event) ;
  }

  /**
   * Gère les événements de mouvement sur le {@link VolumeMenuButton}.
   *
   * @param {EventTarget~Event} event
   *        L'événement qui a provoqué l'exécution de cette fonction.
   *
   * @listens mousemove
   */
  handleMouseMove(event) {
    const mouseVolumeLevelDisplay = this.getChild('mouseVolumeLevelDisplay') ;

    if (mouseVolumeLevelDisplay) {
      const volumeBarEl = this.el() ;
      const volumeBarRect = Dom.getBoundingClientRect(volumeBarEl) ;
      const vertical = this.vertical() ;
      let volumeBarPoint = Dom.getPointerPosition(volumeBarEl, event) ;

      volumeBarPoint = vertical ? volumeBarPoint.y : volumeBarPoint.x ;
      // Le skin par défaut a un espace de chaque côté de la `VolumeBar`. Cela signifie que
      // qu'il est possible de déclencher ce comportement en dehors des limites de la catégorie
      // la `VolumeBar`. Cela nous permet de nous y tenir à tout moment.
      volumeBarPoint = clamp(volumeBarPoint, 0, 1) ;

      mouseVolumeLevelDisplay.update(volumeBarRect, volumeBarPoint, vertical) ;
    }

    if (!Dom.isSingleLeftClick(event)) {
      retour ;
    }

    this.checkMuted() ;
    this.player_.volume(this.calculateDistance(event)) ;
  }

  /**
   * Si le lecteur est en sourdine, rétablissez-le.
   */
  checkMuted() {
    if (this.player_.muted()) {
      ce.joueur_.muted(false) ;
    }
  }

  /**
   * Obtenir le pourcentage du niveau de volume
   *
   * @return {number}
   *         Pourcentage du niveau de volume sous forme de nombre décimal.
   */
  getPercent() {
    if (this.player_.muted()) {
      retour 0 ;
    }
    return this.player_.volume() ;
  }

  /**
   * Augmenter le volume pour les utilisateurs de clavier
   */
  stepForward() {
    this.checkMuted() ;
    this.player_.volume(this.player_.volume() + 0.1) ;
  }

  /**
   * Diminuer le niveau de volume pour les utilisateurs de clavier
   */
  stepBack() {
    this.checkMuted() ;
    this.player_.volume(this.player_.volume() - 0.1) ;
  }

  /**
   * Mise à jour des attributs d'accessibilité ARIA
   *
   * @param {EventTarget~Event} [event]
   *        L'événement `volumechange` qui a provoqué l'exécution de cette fonction.
   *
   * @listens Player#volumechange
   */
  updateARIAAttributes(event) {
    const ariaValue = this.player_.muted() ? 0 : this.volumeAsPercentage_() ;

    this.el_.setAttribute('aria-valuenow', ariaValue) ;
    this.el_.setAttribute('aria-valuetext', ariaValue + '%') ;
  }

  /**
   * Renvoie la valeur actuelle du volume du lecteur en pourcentage
   *
   * @private
   */
  volumeAsPercentage_() {
    return Math.round(this.player_.volume() * 100) ;
  }

  /**
   * Lorsque l'utilisateur commence à faire glisser la barre de volume, mémoriser le volume et écouter pour
   * la fin de la traînée. À la fin de la traînée, si le volume a été mis à zéro,
   * fixe le dernierVolume au volume stocké.
   *
   * @listens slideractive
   * @private
   */
  updateLastVolume_() {
    const volumeBeforeDrag = this.player_.volume() ;

    this.one('sliderinactive', () => {
      if (this.player_.volume() === 0) {
        this.player_.lastVolume_(volumeBeforeDrag) ;
      }
    }) ;
  }

}

/**
 * Options par défaut pour la `VolumeBar`
 *
 * @type {Objet}
 * @private
 */
VolumeBar.prototype.options_ = {
  enfants : [
    niveau de volume
  ],
  barName : 'volumeLevel'
};

// La bulle d'aide MouseVolumeLevelDisplay ne doit pas être ajoutée à un lecteur sur les appareils mobiles
if (!IS_IOS && !IS_ANDROID) {
  VolumeBar.prototype.options_.children.splice(0, 0, 'mouseVolumeLevelDisplay') ;
}

/**
 * Appelle l'événement de mise à jour de ce curseur lorsque cet événement se produit sur le lecteur.
 *
 * @type {string}
 */
VolumeBar.prototype.playerEvent = 'volumechange' ;

Component.registerComponent('VolumeBar', VolumeBar) ;
exporter la barre de volume par défaut ;