<html>
  <head>
    <title>Test media source config changes.</title>
  </head>
  <body onload="runTest();">
    <video controls></video>
    <script src='eme_player_js/app_loader.js' type='text/javascript'></script>
    <script type="text/javascript">
      var testConfig;

      var video = document.querySelector('video');
      var mediaType = 'video/webm; codecs="vorbis, vp8"';

      var CLEAR_MEDIA_1 = 'bear-320x240.webm';
      var CLEAR_MEDIA_2 = 'bear-640x360.webm';
      var ENCRYPTED_MEDIA_1 = 'bear-320x240-av_enc-av.webm';
      var ENCRYPTED_MEDIA_2 = 'bear-640x360-av_enc-av.webm';

      var MEDIA_1_WIDTH = 320;
      var MEDIA_1_HEIGHT = 240;

      var MEDIA_2_WIDTH = 640;
      var MEDIA_2_HEIGHT = 360;
      var MEDIA_2_LENGTH = 2.75;

      // The time in secs to append the second media source.
      var APPEND_TIME = 1;
      // DELTA is the time after APPEND_TIME where the second video dimensions
      // are guaranteed to take effect.
      var DELTA = 0.1;
      // Append MEDIA_2 source at APPEND_TIME, so expected total duration is:
      var TOTAL_DURATION = APPEND_TIME + MEDIA_2_LENGTH;

      function initTestConfig() {
        testConfig = new TestConfig();
        testConfig.loadQueryParams();
      }

      function appendNextSource(mediaSource) {
        console.log('Appending next media source at ' + APPEND_TIME + 'sec.');
        var xhr = new XMLHttpRequest();
        var mediaFile =
            (testConfig.runEncrypted == 1) ? ENCRYPTED_MEDIA_2 : CLEAR_MEDIA_2;
        xhr.open("GET", mediaFile);
        xhr.responseType = 'arraybuffer';
        xhr.addEventListener('load', function(e) {
          var onUpdateEnd = function(e) {
            console.log('Second buffer append ended.');
            srcBuffer.removeEventListener('updateend', onUpdateEnd);
            mediaSource.endOfStream();
            if (!mediaSource.duration ||
                Math.abs(mediaSource.duration - TOTAL_DURATION) > DELTA) {
              Utils.failTest('Unexpected mediaSource.duration = ' +
                       mediaSource.duration + ', expected duration = ' +
                       TOTAL_DURATION);
              return;
            }
            video.play();
          };
          console.log('Appending next media source at ' + APPEND_TIME + 'sec.');
          var srcBuffer = mediaSource.sourceBuffers[0];
          srcBuffer.addEventListener('updateend', onUpdateEnd);
          srcBuffer.timestampOffset = APPEND_TIME;
          srcBuffer.appendBuffer(new Uint8Array(e.target.response));
        });
        xhr.send();
      }

      function onTimeUpdate() {
        // crbug.com/246308
        //checkVideoProperties();

        // Seek to APPEND_TIME because after a seek a timeUpdate event is fired
        // before video width and height properties get updated.
        if (video.currentTime < APPEND_TIME - DELTA) {
          // Seek to save test execution time (about 1 secs) and to test seek
          // on the first buffer.
          video.currentTime = APPEND_TIME - DELTA;
        } else if (video.currentTime > APPEND_TIME + DELTA) {
          // Check video duration here to guarantee that second segment has been
          // appended and video total duration is updated.
          // Video duration is a float value so we check it within a range.
          if (!video.duration ||
              Math.abs(video.duration - TOTAL_DURATION) > DELTA) {
            Utils.failTest('Unexpected video.duration = ' + video.duration +
                     ', expected duration = ' + TOTAL_DURATION);
            return;
          }

          video.removeEventListener('timeupdate', onTimeUpdate);
          video.removeEventListener('ended', Utils.failTest);
          Utils.installTitleEventHandler(video, 'ended');
          // Seek to save test execution time and to test seek on second buffer.
          video.currentTime = APPEND_TIME + MEDIA_2_LENGTH * 0.9;
        }
      }

      function checkVideoProperties() {
        if (video.currentTime <= APPEND_TIME) {
          if (video.videoWidth != MEDIA_1_WIDTH ||
              video.videoHeight != MEDIA_1_HEIGHT) {
            logVideoDimensions();
            Utils.failTest('Unexpected dimensions for first video segment.');
            return;
          }
        } else if (video.currentTime >= APPEND_TIME + DELTA) {
          if (video.videoWidth != MEDIA_2_WIDTH ||
              video.videoHeight != MEDIA_2_HEIGHT) {
            logVideoDimensions();
            Utils.failTest('Unexpected dimensions for second video segment.');
            return;
          }
        }
      }

      function logVideoDimensions() {
        console.log('video.currentTime = ' + video.currentTime +
                    ', video dimensions = ' + video.videoWidth + 'x' +
                    video.videoHeight + '.');
      }

      function runTest() {
        initTestConfig();
        testConfig.mediaFile =
            (testConfig.runEncrypted == 1) ? ENCRYPTED_MEDIA_1 : CLEAR_MEDIA_1;
        testConfig.mediaType = mediaType;
        video.addEventListener('timeupdate', onTimeUpdate);
        video.addEventListener('ended', Utils.failTest);
        var mediaSource = MediaSourceUtils.loadMediaSourceFromTestConfig(
            testConfig, appendNextSource);
        if (testConfig.runEncrypted == 1) {
          var emePlayer = PlayerUtils.createPlayer(video, testConfig);
          emePlayer.registerEventListeners()
              .then(function(player) {
                video.src = window.URL.createObjectURL(mediaSource);
              })
              .catch(function(error) {
                Utils.failTest('Unable to register event listeners.');
              });
        } else {
          video.src = window.URL.createObjectURL(mediaSource);
        }
      }
      </script>
  </body>
</html>
