/*

var audio = $('<audio><source src="/audio/tasks/3463/1.wav" type="audio/mpeg"></audio>');
$('.audio_wr').append(audio);

new zAudioPlayer(audio[0]); 

*/

class zAudioPlayer {

  constructor(player,  options){

      var defaultOptions = {
          wrapper_class: 'audio-player',
          after_init: function(){}            
      };

      this.options = Object.assign(defaultOptions, options);
      this.player = player;    
      this.player_wrapper = null;
      this.isPlaying = false;
      this.is_dragged = false;
      this.duration = 0;

      if('actual_duration' in this.options && this.options.actual_duration > 0){
        console.log('передали actual_duration', this.options.actual_duration);
        this.duration = this.options.actual_duration;
      }

      // elems
      this.currentTimeDisplay = null;
      this.totalTimeDisplay = null;
      this.loading = null;
      this.playPauseButton = null;
      this.playPauseButtonIcon = null;
      this.loading = null;
      this.progressBar = null;
      this.volumeControl = null;
      this.speaker = null;

      this.init();
      this.events();

  }

  // =================
  // INIT
  // =================
  init(){

      var controls_tpl = `
          <div class="controls">
              
              <div class="loading"><div class="loading__spinner"></div></div>

              <div class="play-pause-button">
                  <svg xmlns="http://www.w3.org/2000/svg" width="18" height="24" viewBox="0 0 18 24"><path fill="#566574" fill-rule="evenodd" d="M18 12L0 24V0" class="play-pause-btn__icon"></path></svg>
              </div>

              <div class="progress_wr">
                  <div class="time current-time">0:00</div>
                  
                  <div class="progress">
                      <div class="progress-bar">
                          <div class="progress-bar-pin"></div>
                      </div>
                  </div>
                  
                  <div class="time total-time">0:00</div>
              </div>

              <div class="speed" title="Скорость">
                  <svg fill="#000000" height="800px" width="800px" viewBox="0 0 612 612" xml:space="preserve">
                      <path d="M175.205,239.62c0.127-1.965-0.533-3.902-1.833-5.381l-58.84-66.941c-1.3-1.479-3.135-2.381-5.102-2.508 c-1.975-0.126-3.902,0.533-5.381,1.833c-27.037,23.766-49.479,51.794-66.706,83.305c-0.944,1.729-1.165,3.762-0.611,5.651 c0.554,1.89,1.836,3.483,3.565,4.427l78.205,42.748c1.131,0.619,2.352,0.912,3.557,0.912c2.627,0,5.174-1.398,6.523-3.866 c11.386-20.828,26.229-39.359,44.114-55.08C174.178,243.422,175.08,241.587,175.205,239.62z"/>
                      <path d="M201.462,214.829c1.334,2.515,3.907,3.948,6.568,3.948c1.174,0,2.365-0.279,3.473-0.867 c20.962-11.117,43.512-18.371,67.025-21.561c4.064-0.551,6.913-4.293,6.362-8.358l-11.979-88.316 c-0.551-4.064-4.304-6.909-8.358-6.362c-35.708,4.843-69.949,15.857-101.772,32.736c-3.623,1.922-5.002,6.416-3.082,10.041 L201.462,214.829z"/>
                      <path d="M105.785,334.345l-86.017-23.338c-1.901-0.514-3.929-0.255-5.638,0.725s-2.958,2.598-3.475,4.499 C3.586,342.295,0,369.309,0,396.523c0,4.657,0.111,9.329,0.342,14.284c0.185,3.981,3.468,7.083,7.414,7.083 c0.116,0,0.234-0.002,0.35-0.008l89.031-4.113c1.967-0.09,3.82-0.96,5.145-2.415c1.327-1.455,2.022-3.38,1.93-5.347 c-0.155-3.341-0.23-6.444-0.23-9.484c0-18.02,2.365-35.873,7.029-53.066C112.082,339.499,109.743,335.42,105.785,334.345z"/>
                      <path d="M438.731,120.745c-32.411-15.625-67.04-25.308-102.925-28.786c-1.972-0.198-3.918,0.408-5.439,1.659 c-1.521,1.252-2.481,3.056-2.671,5.018l-8.593,88.712c-0.396,4.082,2.594,7.713,6.677,8.108 c23.652,2.291,46.463,8.669,67.8,18.954c1.015,0.49,2.118,0.738,3.225,0.738c0.826,0,1.654-0.139,2.45-0.416 c1.859-0.649,3.385-2.012,4.24-3.786l38.7-80.287C443.978,126.965,442.427,122.525,438.731,120.745z"/>
                      <path d="M569.642,245.337c0.48-1.911,0.184-3.932-0.828-5.624c-18.432-30.835-41.933-57.983-69.848-80.686 c-1.529-1.242-3.48-1.824-5.447-1.627c-1.959,0.203-3.758,1.174-5,2.702l-56.237,69.144c-1.242,1.529-1.828,3.488-1.625,5.447 c0.201,1.959,1.173,3.758,2.702,5.002c18.47,15.019,34.015,32.975,46.205,53.369c1.392,2.326,3.855,3.618,6.383,3.618 c1.297,0,2.61-0.34,3.803-1.054l76.501-45.728C567.94,248.889,569.16,247.248,569.642,245.337z"/>
                      <path d="M598.044,304.939c-1.228-3.915-5.397-6.096-9.308-4.867l-85.048,26.648c-3.915,1.226-6.093,5.393-4.867,9.306 c6.104,19.486,9.199,39.839,9.199,60.494c0,3.041-0.076,6.144-0.23,9.484c-0.092,1.967,0.602,3.892,1.93,5.347 c1.327,1.456,3.178,2.325,5.145,2.415l89.031,4.113c0.118,0.005,0.234,0.008,0.35,0.008c3.944,0,7.228-3.103,7.414-7.083 c0.229-4.955,0.342-9.627,0.342-14.284C612,365.306,607.306,334.494,598.044,304.939z"/>
                      <path d="M305.737,380.755c-1.281,0-2.555,0.042-3.824,0.11l-120.65-71.185c-2.953-1.745-6.702-1.308-9.176,1.065 c-2.476,2.371-3.07,6.099-1.456,9.121l65.815,123.355c-0.242,2.376-0.371,4.775-0.371,7.195c0,18.608,7.246,36.101,20.403,49.258 c13.158,13.158,30.652,20.404,49.26,20.404c18.608,0,36.101-7.248,49.258-20.404c13.158-13.157,20.403-30.65,20.403-49.258 c0-18.608-7.246-36.101-20.403-49.258C341.839,388.001,324.344,380.755,305.737,380.755z"/>
                  </svg>        

                  <div class="speed_menu">
                      Скорость:
                      <div class="speed_menu_item is_active" data-speed="1">Обычная</div>
                      <div class="speed_menu_item" data-speed="0.7">Медленно</div>
                      <div class="speed_menu_item" data-speed="0.5">Очень медленно</div>
                  </div>
              </div>

              <div class="volume">
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="volume_speaker" fill="#566574" fill-rule="evenodd" d="M14.667 0v2.747c3.853 1.146 6.666 4.72 6.666 8.946 0 4.227-2.813 7.787-6.666 8.934v2.76C20 22.173 24 17.4 24 11.693 24 5.987 20 1.213 14.667 0zM18 11.693c0-2.36-1.333-4.386-3.333-5.373v10.707c2-.947 3.333-2.987 3.333-5.334zm-18-4v8h5.333L12 22.36V1.027L5.333 7.693H0z"></path></svg>
                  <div class="volume_menu">
                      <input type="range" class="volume-control" min="0" max="1" step="0.01" value="1">
                  </div>
              </div>

          </div>    
      `;


      // собирем верстку
      // если в размертке нет обертки - добавляем        
      $(this.player).wrap('<div class="'+this.options.wrapper_class+'"></div>');        

      // сохраняем врапер
      this.player_wrapper = this.player.closest('.'+this.options.wrapper_class);

      $(this.player_wrapper).append(controls_tpl);

      // elems
      this.currentTimeDisplay = $('.current-time', this.player_wrapper);
      this.totalTimeDisplay = $('.total-time', this.player_wrapper);
      this.playPauseButton = $('.play-pause-button', this.player_wrapper);
      this.playPauseButtonIcon = $('path', this.playPauseButton);
      this.loading = $('.loading', this.player_wrapper);
      this.progressBar = $('.progress-bar', this.player_wrapper);
      this.volumeControl = $('.volume-control', this.player_wrapper);
      this.speaker = $('.volume_speaker', this.player_wrapper);
      
      // iOS не позволяет программно устанавливать свойство «громкость»
      // поэтому скрываем иконку
      if (window.navigator.userAgent.match(/iPad/i) || window.navigator.userAgent.match(/iPhone/i)) {
          $('.volume', this.player_wrapper).hide();
      }

      // callback
      this.options.after_init(this);

  }

  // =================
  // EVENTS
  // =================
  events(){

      var _this = this;

      // loadedmetadata
      this.player.addEventListener('loadedmetadata', function(e){
          
          _this.hideLoadingIndicator();
         
          //_this.duration = duration;

          if(_this.duration == 0){
            var duration = _this.player.duration;
            _this.duration = duration;
          }

          /*
          // fix 
          // если у файла нет метаданных, то player.duration приходит равный "Infinity"
          // в таком случае мы снаружи можем сами передать реальную продолжительность ролика в параметре 'actual_duration'.
          // начинаем использовать ее
          if(_this.duration=='Infinity' && _this.options.actual_duration && _this.options.actual_duration > 0){ 
              _this.duration = _this.options.actual_duration / 1000;      
          }
          */

          var totalMinutes = Math.floor(_this.duration / 60);
          var totalSeconds = Math.floor(_this.duration % 60);

          _this.totalTimeDisplay.text(`${totalMinutes}:${totalSeconds < 10 ? '0' : ''}${totalSeconds}`);

      });

      // timeupdate
      this.player.addEventListener("timeupdate", function(e){

          var currentTime = _this.player.currentTime;

          var currentMinutes = Math.floor(currentTime / 60);
          var currentSeconds = Math.floor(currentTime % 60);

          var totalMinutes = Math.floor(_this.duration / 60);
          var totalSeconds = Math.floor(_this.duration % 60);

          _this.currentTimeDisplay.text(`${currentMinutes}:${currentSeconds < 10 ? '0' : ''}${currentSeconds}`);
          _this.totalTimeDisplay.text(`${totalMinutes}:${totalSeconds < 10 ? '0' : ''}${totalSeconds}`);

          var progress = (currentTime / _this.duration) * 100;
          _this.progressBar.css('width', progress+'%');

      });


      this.player.addEventListener('seeking', function(){
          _this.showLoadingIndicator();
      });

      this.player.addEventListener('seeked', function(){
          _this.hideLoadingIndicator();            
      });

      this.player.addEventListener('canplay', function(){
          _this.hideLoadingIndicator()
      });
     

      // плей / пауза
      this.playPauseButton[0].addEventListener("click", function(){
          
          if (!_this.player.paused){

              _this.pausePlayer(_this.player);
              _this.isPlaying = false;

          } else {
        
              // останавливаем остальные плееры
              var players = document.querySelectorAll('.audio-player audio');
              for (var i = 0; i < players.length; i++){
                  _this.pausePlayer(players[i]);
              }

              _this.playPlayer(_this.player);
              _this.isPlaying = true;
          }
      });

      // изменение громкости
      this.volumeControl[0].addEventListener("input", function(){
          _this.player.volume = _this.volumeControl[0].value;
      });

      // после изменения громкости
      this.player.addEventListener('volumechange', function(){            
          if (_this.player.volume >= 0.5) {
              _this.speaker.attr('d', 'M14.667 0v2.747c3.853 1.146 6.666 4.72 6.666 8.946 0 4.227-2.813 7.787-6.666 8.934v2.76C20 22.173 24 17.4 24 11.693 24 5.987 20 1.213 14.667 0zM18 11.693c0-2.36-1.333-4.386-3.333-5.373v10.707c2-.947 3.333-2.987 3.333-5.334zm-18-4v8h5.333L12 22.36V1.027L5.333 7.693H0z');            
          } else if (_this.player.volume < 0.5 && _this.player.volume > 0.05) {
              _this.speaker.attr('d', 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667M17.333 11.373C17.333 9.013 16 6.987 14 6v10.707c2-.947 3.333-2.987 3.333-5.334z');
          } else if (_this.player.volume <= 0.05) {
              _this.speaker.attr('d', 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667');
          }
      });

      // конец
      this.player.addEventListener('ended', function(){
          _this.pausePlayer(_this.player);
          _this.player.currentTime = 0;
      });

      // volume
      $(this.player_wrapper).on('click', '.volume', function(e){

          $('.speed.is_expand', this.player_wrapper).removeClass('is_expand');

          var t = $(this);

          if(t.hasClass('is_expand')){
              setTimeout(function(){
                  t.removeClass('is_expand');
              }, 150);
          }else{
              t.addClass('is_expand');
          }

      });

      // speed
      $(this.player_wrapper).on('click', '.speed', function(e){

          $('.volume.is_expand', this.player_wrapper).removeClass('is_expand');

          var t = $(this);           
          t.toggleClass('is_expand');
          
      });

      $(this.player_wrapper).on('click', '.speed_menu_item', function(e){   

          var speed = +$(e.target).data('speed');
          var speed_wr = $(e.target).closest('.speed');

          if(speed!=1){
              speed_wr.append('<div class="speed_tip">'+(speed*100)+'%</div>');
          }else{
              $('.speed_tip', speed_wr).remove();
          }

          _this.player.playbackRate = speed;

          $('.speed_menu_item').removeClass('is_active');
          $(e.target).addClass('is_active');

          setTimeout(function(){
              speed_wr.removeClass('is_expand');
          }, 150);

      }.bind(this));

      // клик по прогрессбару
      $('.progress', this.player_wrapper).on('click', function(e){   

          var progress = $(this);
          var mouseX = Math.floor(e.pageX - progress.offset().left);

          var progress1 = mouseX / (progress.width() / 100);
          _this.player.currentTime = _this.duration * (progress1 / 100);

      });

      $('.progress-bar-pin', this.player_wrapper).on('mousedown touchstart', function(e){   

          _this.is_dragged = true;

          var progress = $(this).closest('.progress');
          var bar = $(this).closest('.progress-bar');
          
          $(document).on('mousemove touchmove', function(ev){ 
              if(_this.is_dragged){

                  if(ev.originalEvent.touches){
                      var pageX = ev.originalEvent.touches[0].pageX;
                  }else{
                      var pageX = ev.pageX;
                  }

                  var left = Math.floor(pageX - progress.offset().left);
                  var width = left / (progress.width() / 100);

                  if(width <= 100){
                      bar.css('width', width+'%');

                      var seconds = _this.duration * width / 100;
                      _this.player.currentTime = seconds;
                  
                  }
              }
          });

          $(document).on('mouseup touchend', function(e){ 
              _this.is_dragged = false;
          });

      });


      // закрываем менюшки по клику вне меню
      $(document).on('click', function(e){ 

          if (!$(e.target).closest(".speed").length && !$(e.target).closest(".volume").length){
              $('.speed.is_expand', _this.player_wrapper).removeClass('is_expand');
              $('.volume.is_expand', _this.player_wrapper).removeClass('is_expand');
          }            
          e.stopPropagation();
      });

      // обработчик нажития эскейпа
      $(document).on('keyup', function(event){
          if(event.keyCode === 27){
              $('.speed.is_expand', _this.player_wrapper).removeClass('is_expand');
              $('.volume.is_expand', _this.player_wrapper).removeClass('is_expand');
          }
      });

  }

  // =================
  // FUNC
  // =================

  hideLoadingIndicator(){        
      $(this.playPauseButton).css('display', 'flex');
      $(this.loading).hide();
  }

  showLoadingIndicator() {
      $(this.playPauseButton).hide();
      $(this.loading).css('display', 'flex');
  }

  playPlayer(player) {        
      
      player.play();

      var playPauseButton = player.parentElement.querySelector('.play-pause-btn__icon');
      playPauseButton.attributes.d.value = 'M0 0h6v24H0zM12 0h6v24h-6z';
      //this.playPauseButtonIcon.attr('d', 'M0 0h6v24H0zM12 0h6v24h-6z');
  }

  pausePlayer(player){
     
      player.pause();

      var playPauseButton = player.parentElement.querySelector('.play-pause-btn__icon');
      playPauseButton.attributes.d.value = 'M18 12L0 24V0';
      //this.playPauseButtonIcon.attr('d', 'M18 12L0 24V0');
  }


}