// Store path to audio file in a variable
var xFile = 'https://storage04.dropshots.com/photos7000/photos/1381926/20180318/175955.mp4'
// Store cues of each start time of each clip in an array
var xMap = [0, 1.266, 2.664, 3.409, 4.259,4.682,  5.311, 7.169, 7.777, 9.575, 10.88,11.883,13.64, 15.883, 16.75, 17, 17.58];
/* Register doc to act when the DOM is ready but before the images
|| are fully loaded. When that occurs, call loadAudio()
*/
document.addEventListener('DOMContentLoaded', function(e) {
  loadAudio(e, xFile, xMap);
});
/* Pass the Event Object, file, and array through
|| Make a Template Literal of the HTML layout and the hidden
|| <audio> tag. Interpolate the ${file} into the <audio> tag.
|| Insert the TL into the <body> and parse it into HTML.
== Call generateBtn() function...
*/
function loadAudio(e, file, map) {
  var template = `
<fieldset class='set'>
  <legend>Sound FX Test Panel</legend>
</fieldset>
<audio id='sndFX' hidden>
  <source src='${file}' type='audio/wav'>
</audio>`;
  document.body.insertAdjacentHTML('beforeend', template);
  generateBtn(e, map);
}
/* Pass the Event Object and the array through
|| Reference fieldset.set
|| create a documentFragment in order to speedup appending
|| map() the array...
|| create a <button>
|| Set btn class to .btn
|| Set button.btn data-idx to the corresponding index value of
|| map array.
|| Set button.btn text to its index number.
|| Add button.btn to the documentFragment...
|| return an array of .btn (not used in this demo)
== Call the eventBinder() function...
*/
function generateBtn(e, map) {
  var set = document.querySelector('.set');
  var frag = document.createDocumentFragment();
  map.map(function(mark, index, map) {
    var btn = document.createElement('button');
    btn.className = 'btn';
    btn.dataset.idx = map[index];
    btn.textContent = index;
    frag.appendChild(btn);
    return btn;
  });
  set.appendChild(frag);
  eventBinder(e, set, map);
}
/* Pass EventObject, fieldset.set, and map array through
|| Reference the <audio> tag.
|| Register fieldset.set to the click event
|| if the clicked node (e.target) class is .btn...
|| Determine the start and end time of the audio clip.
== Call playClip() function
*/
function eventBinder(e, set, map) {
  var sFX = document.getElementById('sndFX');
  set.addEventListener('click', function(e) {
    if (e.target.className === 'btn') {
      var cue = parseFloat(e.target.textContent);
      var start = parseFloat(e.target.dataset.idx);
      if (cue !== (map.length - 1)) {
        var end = parseFloat(e.target.nextElementSibling.dataset.idx);
      } else {
        var end = parseFloat(sFX.duration);
      }
      playClip.call(this, sFX, start, end);
    } else {
      return false;
    }
  });
}
/* Pass the reference to the <audio> tag, start and end of clip
|| pause audio
|| Set the currentTime to the start parameter
|| Listen for timeupdate event...
|| should currentTime meet or exceed the end parameter...
|| pause <audio> tag.
*/
function playClip(sFX, start, end) {
  sFX.pause();
  sFX.currentTime = start;
  sFX.play();
  sFX.ontimeupdate = function() {
    if (sFX.currentTime >= end) {
      sFX.pause();
    }
  }
  return false;
}