<!DOCTYPE HTML>

<html id="t">
  <head>
    <title>About Stats</title>

<style>
body {
  border-top: 10px solid #3B85E3;
  color: #333;
  font-family: Verdana, Helvetica, Arial, sans-serif;
}
body, td {
  font-size: 11px;
}
a:link, a:visited {
  color: #2C3EBA;
  text-decoration: none;
}
a:hover {
  color: red;
  text-decoration: underline;
}
h1 {
  border-left: 10px solid #FFF;
  font-size: 16px;
  font-weight: bold;
  margin: 0;
  padding: 0.2em;
  color: #3B85E3;
}
h2 {
  border-left: 10px solid #FFF;
  font-size: 11px;
  font-weight: normal;
  margin: 0;
  padding: 0 6em 0.2em 0.2em;
}
.details {
  margin: 0.4em 1.9em 0 1.2em;
  padding: 0 0.4em 0.3em 0;
  white-space: nowrap;
}
.details .outer {
  padding-right: 0;
  vertical-align: top;
}
.details .top {
  border-top: 2px solid #333;
  font-weight: bold;
  margin-top: 0.4em;
}
.details .header2 {
  font-weight: bold;
  padding-left: 0.9em;
}
.details .key {
  padding-left: 1.1em;
  vertical-align: top;
}
.details .value {
  text-align: right;
  color: #333;
  font-weight: bold;
}
.details .zebra {
  background: #EEE;
}
.lower {
  text-transform: lowercase;
}
</style>
<script>

/* Counter accessor for Name Node. */
function getCounterNameFromCounterNode(node) {
  return node.childNodes[1];
}

/* Counter accessor for Value Node. */
function getCounterValueFromCounterNode(node) {
  return node.childNodes[3];
}

/* Counter accessor for Delta Node. */
function getCounterDeltaFromCounterNode(node) {
  return node.childNodes[5];
}

/* Timer accessor for Name Node. */
function getTimerNameFromTimerNode(node) {
  return node.childNodes[1];
}

/* Timer accessor for Value Node. */
function getTimerValueFromTimerNode(node) {
  return node.childNodes[3];
}

/* Timer accessor for Time Node. */
function getTimerTimeFromTimerNode(node) {
  return node.childNodes[5];
}

/* Timer accessor for Average Time Node. */
function getTimerAvgTimeFromTimerNode(node) {
  return node.childNodes[7];
}

/* Do the filter work.  Hide all nodes matching node.*/
function filterMatching(text, nodelist, functionToGetNameNode) {
  var showAll = text.length == 0;
  for (var i = 0, node; node = nodelist[i]; i++) {
    var name = functionToGetNameNode(node).innerHTML.toLowerCase();
    if (showAll || name.indexOf(text) >= 0) {
      node.style.display = "table-row";
    } else {
      node.style.display = "none";
    }
  }
}

/* Hides or shows counters based on the user's current filter selection. */
function doFilter() {
  var filter = document.getElementById("filter");
  var text = filter.value.toLowerCase();
  var nodes = document.getElementsByName("counter");
  filterMatching(text, nodes, getCounterNameFromCounterNode);
  var nodes = document.getElementsByName("timer");
  filterMatching(text, nodes, getTimerNameFromTimerNode);
}

/* Colors the counters based on increasing or decreasing value. */
function doColor() {
  var nodes = document.getElementsByName("counter");
  for (var i = 0, node; node = nodes[i]; i++) {
    var child = getCounterDeltaFromCounterNode(node);
    var delta = child.innerHTML;
    if (delta > 0) {
      child.style.color = "Green";
    } else if (delta == 0) {
      child.style.color = "Black";
    } else {
      child.style.color = "Red";
    }
  }
}

/* Counters with no values are null. Remove them. */
function removeNullValues() {
  var nodes = document.getElementsByName("counter");
  for (var i = nodes.length - 1; i >= 0; i--) {
    var node = nodes[i];
    var value = getCounterValueFromCounterNode(node).innerHTML;
    if (value == "null") {
      node.parentNode.removeChild(node);
    }
  }
  var nodes = document.getElementsByName("timer");
  for (var i = 0, node; node = nodes[i]; i++) {
    var value_node = getTimerValueFromTimerNode(node);
    if (value_node.innerHTML == "null") {
      value_node.innerHTML = "";
    }
  }
}

/* Compute the average time for timers */
function computeTimes() {
  var nodes = document.getElementsByName("timer");
  for (var i = 0, node; node = nodes[i]; i++) {
    var count = getTimerValueFromTimerNode(node).innerHTML;
    if (count.length > 0) {
      var time = getTimerTimeFromTimerNode(node).innerHTML;
      var avg = getTimerAvgTimeFromTimerNode(node);
      avg.innerHTML = Math.round(time / count * 100) / 100;
    }
  }
}

/* All the work we do onload. */
function onLoadWork() {
  doColor();
  removeNullValues();
  computeTimes();
  document.getElementById("filter").focus();
}

// The function should only be used as the event handler
// on a table cell element. To use it, put it in a <td> element:
//  <td onclick="sort('string')" ...>
//
// The function sorts rows after the row with onclick event handler.
//
// type: the data type, 'string', 'number'
function sort_table(type){
  var cell = event.target;
  var cnum = cell.cellIndex;

  var row = cell.parentNode;
  var start_index = row.rowIndex + 1;

  var tbody = row.parentNode;
  var table = tbody.parentNode;

  var rows = new Array();

  var indexes = new Array();
  // skip the first row
  for (var i = start_index; i < table.rows.length; i++)
    rows.push(table.rows[i]);

  // a, b are strings
  function compare_strings(a,b) {
    if (a == b) return 0;
    if (a < b) return -1;
    return 1;
  }

  // a, b are numbers
  function compare_numbers(a,b) {
    var x = isNaN(a) ? 0 : a;
    var y = isNaN(b) ? 0 : b;
    return x - y;
  }

  var sort_func = undefined;
  if (type === 'string') {
    sort_func = function(a, b) {
      var x = a.cells[cnum].innerText;
      var y = b.cells[cnum].innerText;
      return compare_strings(x, y);
    } ;

  } else if (type === 'number') {
    sort_func = function(a, b) {
      var x = parseFloat(a.cells[cnum].innerText);
      var y = parseFloat(b.cells[cnum].innerText);
      return compare_numbers(x, y);
    }
  }

  rows.sort(sort_func);

  // change tables
  if (cell._reverse) {
    for (var i = rows.length - 1; i >= 0; i--)
      tbody.appendChild(rows[i]);
    cell._reverse = false;
  } else {
    for (var i = 0; i < rows.length; i++)
      tbody.appendChild(rows[i]);
    cell._reverse = true;
  }
}

</script>
</head>
<body onload="onLoadWork()">
  <div style="float: right">
    <br>Filter: <input id="filter" type="text" value="" onkeyup="doFilter()">
  </div>
  <h1 class="lower">About Stats</h1>
  <h2>Shhh!  This page is secret!</h2><br/>
  <table class="details" cellspacing="0" cellpadding="0" border="0">
    <tbody>
      <tr>
        <td class="outer">
          <table cellspacing="0" cellpadding="0" border="0">
            <tbody>
              <tr>
                <td class="top" width="100">Counters</td>
                <td class="top value" colspan=2></td>
              </tr>
              <tr>
                <td class="header2 lower" width="200" onclick="sort_table('string')">name</td>
                <td class="header2 lower" onclick="sort_table('number')">value</td>
                <td class="header2 lower" onclick="sort_table('number')">delta</td>
              </tr>
              <tr jsselect="counters" name="counter">
                <td class="key" width="200" jscontent="name"></td>
                <td class="value" jscontent="value"></td>
                <td class="value" jscontent="delta"></td>
              </tr>
            </tbody>
          </table>
        </td>
        <td width="15"/>
        <td class="outer">
          <table cellspacing="0" cellpadding="0" border="0">
            <tbody>
              <tr>
                <td class="top" width="100">Timers</td>
                <td class="top value"></td>
                <td class="top value" colspan=3></td>
              </tr>
              <tr>
                <td class="header2 lower" width="200" onclick="sort_table('string')">name</td>
                <td class="header2 lower" onclick="sort_table('number')">count</td>
                <td class="header2 lower" onclick="sort_table('number')">time (ms)</td>
                <td class="header2 lower" onclick="sort_table('number')">avg time (ms)</td>
              </tr>
              <tr jsselect="timers" name="timer">
                <td class="key" width="200" jscontent="name"></td>
                <td class="value" jscontent="value"></td>
                <td class="value" jscontent="time"></td>
                <td class="value"></td>
              </tr>
            </tbody>
          </table>
        </td>
      </tr>
    </tbody>
  </table><br/>
</body>
</html>