<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;

      var firstFile;
      var secondFile;

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

      function setMediaFiles() {
        switch (testConfig.configChangeType) {
          case CONFIG_CHANGE_TYPE.CLEAR_TO_CLEAR:
            console.log('Config change type: clear to clear.');
            firstFile = CLEAR_MEDIA_1;
            secondFile = CLEAR_MEDIA_2;
            break;
          case CONFIG_CHANGE_TYPE.CLEAR_TO_ENCRYPTED:
            console.log('Config change type: clear to encrypted.');
            firstFile = CLEAR_MEDIA_1;
            secondFile = ENCRYPTED_MEDIA_2;
            break;
          case CONFIG_CHANGE_TYPE.ENCRYPTED_TO_CLEAR:
            console.log('Config change type: encrypted to clear.');
            firstFile = ENCRYPTED_MEDIA_1;
            secondFile = CLEAR_MEDIA_2;
            break;
          case CONFIG_CHANGE_TYPE.ENCRYPTED_TO_ENCRYPTED:
            console.log('Config change type: encrypted to encrypted.');
            firstFile = ENCRYPTED_MEDIA_1;
            secondFile = ENCRYPTED_MEDIA_2;
            break;
        }
      }

      function appendNextSource(mediaSource) {
        console.log('Appending next media source at ' + APPEND_TIME + 'sec.');
        var xhr = new XMLHttpRequest();
        xhr.open("GET", secondFile);
        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();
        setMediaFiles();
        testConfig.mediaFile = firstFile;
        testConfig.mediaType = mediaType;
        video.addEventListener('timeupdate', onTimeUpdate);
        video.addEventListener('ended', Utils.failTest);
        var mediaSource = MediaSourceUtils.loadMediaSourceFromTestConfig(
            testConfig, appendNextSource);
        if (testConfig.configChangeType != CONFIG_CHANGE_TYPE.CLEAR_TO_CLEAR) {
          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>
