<!DOCTYPE html>
<!--
  This page was created to help debug and study webrtc issues such as
  bandwidth estimation problems. It allows one to easily launch a test
  case that establishs a connection between 2 peer connections
-->
<html>
<head>
<title>Loopback test</title>

<!-- In order to plot graphs, this tools uses google visualization API which is
     loaded via goog.load provided by google api. -->
<script src="//www.google.com/jsapi"></script>

<!-- This file is included to allow loopback_test.js instantiate a
     RTCPeerConnection on a browser and version agnostic way. -->
<script src="adapter.js"></script>

<!-- Provides class StatTracker used by loopback_test.js to keep track of
     RTCPeerConnection stats -->
<script src="stat_tracker.js"></script>

<!-- Provides LoopbackTest class which has the core logic for the test itself.
     Such as: create 2 peer connections, establish a call, filter turn
     candidates, constraint video bitrate etc.
  -->
<script src="loopback_test.js"></script>

<style>
#chart {
  height: 400px;
}

#control-range {
  height: 100px;
}
</style>
</head>
<body>
<div id="test-launcher">
  <p>Duration (s): <input id="duration" type="text"></p>
  <p>Max video bitrate (kbps): <input id="max-video-bitrate" type="text"></p>
  <p>Force TURN: <input id="force-turn" type="checkbox" checked></p>
  <p><input id="launcher-button" type="button" value="Run test">
  <div id="test-status" style="display:none"></div>
  <div id="dashboard">
    <div id="control-category"></div>
    <div id="chart"></div>
    <div id="control-range"></div>
  </div>
</div>
<script>
google.load('visualization', '1.0', {'packages':['controls']});

var durationInput = document.getElementById('duration');
var maxVideoBitrateInput = document.getElementById('max-video-bitrate');
var forceTurnInput = document.getElementById('force-turn');
var launcherButton = document.getElementById('launcher-button');
var autoModeInput = document.createElement('input');
var testStatus = document.getElementById('test-status');

launcherButton.onclick = start;

// Load parameters from the url if present. This allows one to link to
// a specific test configuration and is used to automatically pass parameters
// for scripts such as record-test.sh
function getURLParameter(name, default_value) {
  var search =
      RegExp('(^\\?|&)' + name + '=' + '(.+?)(&|$)').exec(location.search);
  if (search)
    return decodeURI(search[2]);
  else
    return default_value;
}

durationInput.value = getURLParameter('duration', 10);
maxVideoBitrateInput.value = getURLParameter('max-video-bitrate', 2000);
forceTurnInput.checked = (getURLParameter('force-turn', 'true') === 'true');
autoModeInput.checked = (getURLParameter('auto-mode', 'false') === 'true');

if (autoModeInput.checked) start();

function start() {
  var durationMs = parseInt(durationInput.value) * 1000;
  var maxVideoBitrateKbps = parseInt(maxVideoBitrateInput.value);
  var forceTurn = forceTurnInput.checked;
  var autoClose = autoModeInput.checked;

  var updateStatusInterval;
  var testFinished = false;
  function updateStatus() {
    if (testFinished) {
      testStatus.innerHTML = 'Test finished';
      if (updateStatusInterval) {
	clearInterval(updateStatusInterval);
        updateStatusInterval = null;
      }
    } else {
      if (!updateStatusInterval) {
        updateStatusInterval = setInterval(updateStatus, 1000);
        testStatus.innerHTML = 'Running';
      }
      testStatus.innerHTML += '.';
    }
  }

  if (!(isFinite(maxVideoBitrateKbps) && maxVideoBitrateKbps > 0)) {
    // TODO(andresp): Get a better way to show errors than alert.
    alert("Invalid max video bitrate");
    return;
  }

  if (!(isFinite(durationMs) && durationMs > 0)) {
    alert("Invalid duration");
    return;
  }

  durationInput.disabled = true;
  forceTurnInput.disabled = true;
  maxVideoBitrateInput.disabled = true;
  launcherButton.style.display = 'none';
  testStatus.style.display = 'block';

  getUserMedia({audio:true, video:true},
                gotStream, function() {});

  function gotStream(stream) {
    updateStatus();
    var test = new LoopbackTest(stream, durationMs, forceTurn,
                                maxVideoBitrateKbps);
    test.run(onTestFinished.bind(test));
  }

  function onTestFinished() {
    testFinished = true;
    updateStatus();
    if (autoClose) {
      window.close();
    } else {
      plotStats(this.getResults());
    }
  }
}

function plotStats(data) {
  var dashboard = new google.visualization.Dashboard(
      document.getElementById('dashboard'));

  var chart = new google.visualization.ChartWrapper({
      'containerId': 'chart',
      'chartType': 'LineChart',
      'options': { 'pointSize': 0, 'lineWidth': 1, 'interpolateNulls': true },
    });

  var rangeFilter = new google.visualization.ControlWrapper({
     'controlType': 'ChartRangeFilter',
     'containerId': 'control-range',
     'options': {
       'filterColumnIndex': 0,
       'ui': {
         'chartType': 'ScatterChart',
         'chartOptions': {
           'hAxis': {'baselineColor': 'none'}
         },
         'chartView': {
           'columns': [0, 1]
         },
         'minRangeSize': 1000 // 1 second
       }
     },
   });

  // Create a table with the columns of the dataset.
  var columnsTable = new google.visualization.DataTable();
  columnsTable.addColumn('number', 'columnIndex');
  columnsTable.addColumn('string', 'columnLabel');
  var initState = {selectedValues: []};
  for (var i = 1; i < data.getNumberOfColumns(); i++) {
    columnsTable.addRow([i, data.getColumnLabel(i)]);
    initState.selectedValues.push(data.getColumnLabel(i));
  }

  var columnFilter = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'control-category',
    dataTable: columnsTable,
    options: {
      filterColumnLabel: 'columnLabel',
      ui: {
        label: '',
        allowNone: false,
        selectedValuesLayout: 'aside'
      }
    },
    state: initState
  });
  google.visualization.events.addListener(columnFilter, 'statechange',
    function () {
      var state = columnFilter.getState();
      var row;
      var columnIndices = [0];
      for (var i = 0; i < state.selectedValues.length; i++) {
        row = columnsTable.getFilteredRows([{
            column: 1,
            value: state.selectedValues[i]}])[0];
        columnIndices.push(columnsTable.getValue(row, 0));
      }
      // Sort the indices into their original order
      columnIndices.sort(function (a, b) { return (a - b); });
      chart.setView({columns: columnIndices});
      chart.draw();
    });

  columnFilter.draw();
  dashboard.bind([rangeFilter], [chart]);
  dashboard.draw(data);
}
</script>
</body>
</html>
