/* Show information if video fails to load */

(function() {
  'use strict';
  
  var timer = null;

  function show_fail_info() {
    var video_container = document.getElementById('video_container0'),
        video = document.getElementById('video0'),
        fail_info = document.getElementById('failed_to_load_info'),
        footer = document.getElementById('footer'),
        footer_expander = document.getElementById('footer_expander');

    if (footer) {
      // the footer might have been shown already, so we should hide it back
      footer.classList.add('hidden');
      if (footer_expander) {
        footer_expander.innerHTML = '&gt;';
      }
    }
    if (video_container) {
      video_container.classList.add('hidden');
    }
    if (video) {
      video.parentNode.classList.remove('loading');
      video.parentNode.removeChild(video);
    }
    if (fail_info) {
      fail_info.classList.remove('hidden');
    }

    move_entry_info();
  }

  function move_entry_info() {
    // move entry info, if it exists, into the failed to load div
    var fail_entry_info = document.getElementById('failed_to_load_entry_info'),
        entry_info = document.getElementById('video_info_wrapper0');

    if (fail_entry_info) {
      // move all the entry info into the failed_to_load div
      while (entry_info.hasChildNodes()) {
        fail_entry_info.appendChild(entry_info.firstChild);
      }
      entry_info.classList.remove('hidden');
      fail_entry_info.classList.remove('hidden');
    }
  }

  function video_loaded() {
    var video = document.getElementById('video0');
    window.clearInterval(timer);
    timer = null;
    if (!video) { return; }
    video.removeEventListener('loadedmetadata', video_loaded);
  }

  function get_last_source(video) {
    /* return last source in video element */
    var i, source = null;

    for (i=0; i<video.childNodes.length; i++) {
      if (video.childNodes[i].tagName === 'SOURCE') {
        source = video.childNodes[i];
      }
    }
    if (source) {
      return source.src;
    }
    return null;
  }

  function check_network_state() {
    /* TODO: debug and see how we can be sure that the current network state
     * applies to the current source */
    var last_source,
        video = document.getElementById('video0');

    if (!video) { return; }

    if (video.readyState > 0) {
      // video has begun loading, stop checking
      window.clearInterval(timer);
      timer = null;
    }
    // note we're assuming the video always has sources, because otherwise the
    // page will have already redirected the user
    else if (video.networkState === 3) {
      last_source = get_last_source(video);
      if (last_source && video.currentSrc === last_source) {
        // video has failed to load
        window.clearInterval(timer);
        timer = null;
        show_fail_info();
      }
    }
  }

  function check_video_dimensions() {
    /* If a data-less video gets delivered, the browser will trick us into
     * believing everything is fine, even though there's nothing playing. On
     * the other hand, if a video is already cache, if might fire
     * canplaythrough and even play before it's dimensions have been set. To
     * deal with this, we introduce a small delay and test both the video
     * duration and its dimensions. */
    var video = document.getElementById('video0');
    if (!video) { return; }

    video.removeEventListener('play', check_video_dimensions);

    window.setTimeout(function() {
      /* On mobile, it's possible that videoWidth and videoHeight get
       * reported as zero. Checking scrollWidth and scrollHeight will
       * prevent those false positives. */
      if (!(video.duration > 0 || video.videoWidth > 0 || video.videoHeight > 0 ||
            video.scrollWidth > 0 || video.scrollHeight > 0)) {
        console.log('empty video detected');
        show_fail_info();
      }
    }, 100);
  }

  function setup_error_handling() {
    var video = document.getElementById('video0');

    if (!video) {
      /* user probably specified no_video, so just move the entry info and
       * we're done */
      move_entry_info();
      return;
    }

    video.addEventListener('error', show_fail_info);
    video.addEventListener('abort', show_fail_info);

    video.addEventListener('loadedmetadata', video_loaded);
    video.addEventListener('play', check_video_dimensions);

    if (timer) {
      window.clearInterval(timer);
    }
    timer = window.setInterval(check_network_state, 500);
  }

  document.addEventListener('DOMContentLoaded', setup_error_handling);
  window.addEventListener('newVideoCreated', setup_error_handling);
}());
