// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// The page simply plays an audio or a video stream in a loop, it can be used
// by appending following queryable object to url path, e.g.
//   http://0.0.0.0:8000/cobalt/demos/content/background-mode-demo?type=video
//   http://0.0.0.0:8000/cobalt/demos/content/background-mode-demo?type=audio
// If the stream is adaptive, it has to be fit in memory as this demo will
// download the whole stream at once.

var video = null;
var type = null;

let playlist = getPlaylist();
let index = 0;
let defaultSkipTime = 10;

var kAdaptiveAudioChunkSize = 720 * 1024;

function downloadAndAppend(url, begin, end, source_buffer, callback) {
  var xhr = new XMLHttpRequest;
  xhr.open('GET', url, true);
  xhr.responseType = 'arraybuffer';
  xhr.addEventListener('load', function(e) {
    var onupdateend = function() {
      source_buffer.removeEventListener('updateend', onupdateend);
      callback();
    };
    source_buffer.addEventListener('updateend', onupdateend);
    source_buffer.appendBuffer(new Uint8Array(e.target.response));
  });

  xhr.setRequestHeader('Range', ('bytes=' + begin +'-' + end));
  xhr.send();
}

function createVideoElement() {
  var video = document.createElement('video');
  video.autoplay = true;
  video.style.width = '1280px';
  video.style.height = '720px';
  document.body.appendChild(video);

  return video;
}

function onVideoEnded() {
  startNextVideo();
}

function startAdaptiveVideo() {
  video.src = '';
  video.load();
  var mediasource = new MediaSource;
  mediasource.addEventListener('sourceopen', function () {
    if (type == 'audio') {
      var audio_source_buffer = mediasource.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');
      downloadAndAppend('../media-element-demo/public/assets/dash-audio.mp4', 0, kAdaptiveAudioChunkSize * 10, audio_source_buffer, function () {
        mediasource.endOfStream();
      });
    }

    if (type == 'video') {
      var video_source_buffer = mediasource.addSourceBuffer('video/mp4; codecs="avc1.640028"');
      var audio_source_buffer = mediasource.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');
      downloadAndAppend('../media-element-demo/public/assets/dash-video-1080p.mp4', 0, 15 * 1024 * 1024, video_source_buffer, function () {
        video_source_buffer.abort();
           // Append the first two segments of the 240p video so we can see the transition.
        downloadAndAppend('../media-element-demo/public/assets/dash-audio.mp4', 0, kAdaptiveAudioChunkSize * 10, audio_source_buffer, function () {
          mediasource.endOfStream();
        });
      });
    }
  })

  video.src = window.URL.createObjectURL(mediasource);
  video.addEventListener('ended', onVideoEnded);
}


function startNextVideo() {
  startAdaptiveVideo();
}

function checkMediaType() {
  var get_parameters = window.location.search.substr(1).split('&');
  for (var param of get_parameters) {
    split = param.split('=');
    if (split[0] == 'type') {
      type = split[1];
    }
  }

  if (type != 'audio' && type != 'video') {
    throw "invalid type " + type;
  }
}

function main() {
  checkMediaType();
  video = createVideoElement();
  startNextVideo();
  setUpMediaSessionHandlers();
  updateMetadata();
}

// MediaSession
function updateMetadata() {
  let track = playlist[index];

  navigator.mediaSession.metadata = new MediaMetadata({
    title: track.title,
    artist: track.artist,
  });
  navigator.mediaSession.playbackState = "playing";
}

function setUpMediaSessionHandlers() {
  navigator.mediaSession.setActionHandler('seekbackward', function(event) {
    const skipTime = event.seekOffset || defaultSkipTime;
    video.currentTime = Math.max(video.currentTime - skipTime, 0);
    updatePositionState();
  });

  navigator.mediaSession.setActionHandler('seekforward', function(event) {
    const skipTime = event.seekOffset || defaultSkipTime;
    video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
    updatePositionState();
  });

  navigator.mediaSession.setActionHandler('play', function() {
    log_info('TimeStamp: ' + getTime() + ' seconds' + ' play');
    video.play();
    navigator.mediaSession.playbackState = "playing";
  });

  navigator.mediaSession.setActionHandler('pause', function() {
    log_info('TimeStamp: ' + getTime() + ' seconds' + ' pause');
    video.pause();
    navigator.mediaSession.playbackState = "paused";
  });

  try {
    navigator.mediaSession.setActionHandler('stop', function() {
      log_info('TimeStamp: ' + getTime() + ' seconds' + ' stop');
    });
  } catch(error) {
  }

  try {
    navigator.mediaSession.setActionHandler('seekto', function(event) {
      if (event.fastSeek && ('fastSeek' in video)) {
        video.fastSeek(event.seekTime);
        return;
      }
      video.currentTime = event.seekTime;
      updatePositionState();
    });
  } catch(error) {
  }
}

function getPlaylist() {
  return [{title: 'Background mode demo', artist: 'Cobalt',}];
}

function log_info(message) {
  console.warn(message);
  document.getElementById('info').innerHTML += message + '.\n';
}

function getTime() {
  return Math.floor(Date.now() / 1000 | 0);
}

main();
