// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


/**
 * This function provides requestAnimationFrame in a cross browser way.
 * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 */
if ( !window.requestAnimationFrame ) {
  window.requestAnimationFrame = ( function() {
    return window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback, element) {
          window.setTimeout( callback, 1000 / 60 );
        };
  } )();
}

var kNPoints = 8000;
var kNModifications = 20;
var kNVisiblePoints = 200;
var kDecaySpeed = 20;

var kPointRadius = 4;
var kInitialLifeForce = 100;

var livePoints = void 0;
var dyingPoints = void 0;
var scene = void 0;
var renderingStartTime = void 0;
var scene = void 0;
var pausePlot = void 0;
var splayTree = void 0;
var numberOfFrames = 0;
var sumOfSquaredPauses = 0;
var benchmarkStartTime = void 0;
var benchmarkTimeLimit = void 0;
var autoScale = void 0;
var pauseDistribution = [];


function Point(x, y, z, payload) {
  this.x = x;
  this.y = y;
  this.z = z;

  this.next = null;
  this.prev = null;
  this.payload = payload;
  this.lifeForce = kInitialLifeForce;
}


Point.prototype.color = function () {
  return "rgba(0, 0, 0, " + (this.lifeForce / kInitialLifeForce) + ")";
};


Point.prototype.decay = function () {
  this.lifeForce -= kDecaySpeed;
  return this.lifeForce <= 0;
};


function PointsList() {
  this.head = null;
  this.count = 0;
}


PointsList.prototype.add = function (point) {
  if (this.head !== null) this.head.prev = point;
  point.next = this.head;
  this.head = point;
  this.count++;
}


PointsList.prototype.remove = function (point) {
  if (point.next !== null) {
    point.next.prev = point.prev;
  }
  if (point.prev !== null) {
    point.prev.next = point.next;
  } else {
    this.head = point.next;
  }
  this.count--;
}


function GeneratePayloadTree(depth, tag) {
  if (depth == 0) {
    return {
      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
      string : 'String for key ' + tag + ' in leaf node'
    };
  } else {
    return {
      left:  GeneratePayloadTree(depth - 1, tag),
      right: GeneratePayloadTree(depth - 1, tag)
    };
  }
}


// To make the benchmark results predictable, we replace Math.random
// with a 100% deterministic alternative.
Math.random = (function() {
  var seed = 49734321;
  return function() {
    // Robert Jenkins' 32 bit integer hash function.
    seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
    seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
    seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
    seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
    seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
    seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
    return (seed & 0xfffffff) / 0x10000000;
  };
})();


function GenerateKey() {
  // The benchmark framework guarantees that Math.random is
  // deterministic; see base.js.
  return Math.random();
}

function CreateNewPoint() {
  // Insert new node with a unique key.
  var key;
  do { key = GenerateKey(); } while (splayTree.find(key) != null);

  var point = new Point(Math.random() * 40 - 20,
                        Math.random() * 40 - 20,
                        Math.random() * 40 - 20,
                        GeneratePayloadTree(5, "" + key));

  livePoints.add(point);

  splayTree.insert(key, point);
  return key;
}

function ModifyPointsSet() {
  if (livePoints.count < kNPoints) {
    for (var i = 0; i < kNModifications; i++) {
      CreateNewPoint();
    }
  } else if (kNModifications === 20) {
    kNModifications = 80;
    kDecay = 30;
  }

  for (var i = 0; i < kNModifications; i++) {
    var key = CreateNewPoint();
    var greatest = splayTree.findGreatestLessThan(key);
    if (greatest == null) {
      var point = splayTree.remove(key).value;
    } else {
      var point = splayTree.remove(greatest.key).value;
    }
    livePoints.remove(point);
    point.payload = null;
    dyingPoints.add(point);
  }
}


function PausePlot(width, height, size, scale) {
  var canvas = document.createElement("canvas");
  canvas.width = this.width = width;
  canvas.height = this.height = height;
  document.body.appendChild(canvas);

  this.ctx = canvas.getContext('2d');

  if (typeof scale !== "number") {
    this.autoScale = true;
    this.maxPause = 0;
  } else {
    this.autoScale = false;
    this.maxPause = scale;
  }

  this.size = size;

  // Initialize cyclic buffer for pauses.
  this.pauses = new Array(this.size);
  this.start = this.size;
  this.idx = 0;
}


PausePlot.prototype.addPause = function (p) {
  if (this.idx === this.size) {
    this.idx = 0;
  }

  if (this.idx === this.start) {
    this.start++;
  }

  if (this.start === this.size) {
    this.start = 0;
  }

  this.pauses[this.idx++] = p;
};


PausePlot.prototype.iteratePauses = function (f) {
  if (this.start < this.idx) {
    for (var i = this.start; i < this.idx; i++) {
      f.call(this, i - this.start, this.pauses[i]);
    }
  } else {
    for (var i = this.start; i < this.size; i++) {
      f.call(this, i - this.start, this.pauses[i]);
    }

    var offs = this.size - this.start;
    for (var i = 0; i < this.idx; i++) {
      f.call(this, i + offs, this.pauses[i]);
    }
  }
};


PausePlot.prototype.draw = function () {
  var first = null;

  if (this.autoScale) {
    this.iteratePauses(function (i, v) {
      if (first === null) {
        first = v;
      }
      this.maxPause = Math.max(v, this.maxPause);
    });
  }

  var dx = this.width / this.size;
  var dy = this.height / this.maxPause;

  this.ctx.save();
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.ctx.beginPath();
  this.ctx.moveTo(1, dy * this.pauses[this.start]);
  var p = first;
  this.iteratePauses(function (i, v) {
    var delta = v - p;
    var x = 1 + dx * i;
    var y = dy * v;
    this.ctx.lineTo(x, y);
    if (delta > 2 * (p / 3)) {
      this.ctx.font = "bold 12px sans-serif";
      this.ctx.textBaseline = "bottom";
      this.ctx.fillText(v + "ms", x + 2, y);
    }
    p = v;
  });
  this.ctx.strokeStyle = "black";
  this.ctx.stroke();
  this.ctx.restore();
}


function Scene(width, height) {
  var canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  document.body.appendChild(canvas);

  this.ctx = canvas.getContext('2d');
  this.width = canvas.width;
  this.height = canvas.height;

  // Projection configuration.
  this.x0 = canvas.width / 2;
  this.y0 = canvas.height / 2;
  this.z0 = 100;
  this.f  = 1000;  // Focal length.

  // Camera is rotating around y-axis.
  this.angle = 0;
}


Scene.prototype.drawPoint = function (x, y, z, color) {
  // Rotate the camera around y-axis.
  var rx = x * Math.cos(this.angle) - z * Math.sin(this.angle);
  var ry = y;
  var rz = x * Math.sin(this.angle) + z * Math.cos(this.angle);

  // Perform perspective projection.
  var px = (this.f * rx) / (rz - this.z0) + this.x0;
  var py = (this.f * ry) / (rz - this.z0) + this.y0;

  this.ctx.save();
  this.ctx.fillStyle = color
  this.ctx.beginPath();
  this.ctx.arc(px, py, kPointRadius, 0, 2 * Math.PI, true);
  this.ctx.fill();
  this.ctx.restore();
};


Scene.prototype.drawDyingPoints = function () {
  var point_next = null;
  for (var point = dyingPoints.head; point !== null; point = point_next) {
    // Rotate the scene around y-axis.
    scene.drawPoint(point.x, point.y, point.z, point.color());

    point_next = point.next;

    // Decay the current point and remove it from the list
    // if it's life-force ran out.
    if (point.decay()) {
      dyingPoints.remove(point);
    }
  }
};


Scene.prototype.draw = function () {
  this.ctx.save();
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.drawDyingPoints();
  this.ctx.restore();

  this.angle += Math.PI / 90.0;
};


function updateStats(pause) {
  numberOfFrames++;
  if (pause > 20) {
    sumOfSquaredPauses += (pause - 20) * (pause - 20);
  }
  pauseDistribution[Math.floor(pause / 10)] |= 0;
  pauseDistribution[Math.floor(pause / 10)]++;
}


function renderStats() {
  var msg = document.createElement("p");
  msg.innerHTML = "Score " +
    Math.round(numberOfFrames * 1000 / sumOfSquaredPauses);
  var table = document.createElement("table");
  table.align = "center";
  for (var i = 0; i < pauseDistribution.length; i++) {
    if (pauseDistribution[i] > 0) {
      var row = document.createElement("tr");
      var time = document.createElement("td");
      var count = document.createElement("td");
      time.innerHTML = i*10 + "-" + (i+1)*10 + "ms";
      count.innerHTML = " => " + pauseDistribution[i];
      row.appendChild(time);
      row.appendChild(count);
      table.appendChild(row);
    }
  }
  div.appendChild(msg);
  div.appendChild(table);
}


function render() {
  if (typeof renderingStartTime === 'undefined') {
    renderingStartTime = Date.now();
    benchmarkStartTime = renderingStartTime;
  }

  ModifyPointsSet();

  scene.draw();

  var renderingEndTime = Date.now();
  var pause = renderingEndTime - renderingStartTime;
  pausePlot.addPause(pause);
  renderingStartTime = renderingEndTime;

  pausePlot.draw();

  updateStats(pause);

  div.innerHTML =
      livePoints.count + "/" + dyingPoints.count + " " +
      pause + "(max = " + pausePlot.maxPause + ") ms " +
      numberOfFrames + " frames";

  if (renderingEndTime < benchmarkStartTime + benchmarkTimeLimit) {
    // Schedule next frame.
    requestAnimationFrame(render);
  } else {
    renderStats();
  }
}


function Form() {
  function create(tag) { return document.createElement(tag); }
  function text(value) { return document.createTextNode(value); }

  this.form = create("form");
  this.form.setAttribute("action", "javascript:start()");

  var table = create("table");
  table.setAttribute("style", "margin-left: auto; margin-right: auto;");

  function col(a) {
    var td = create("td");
    td.appendChild(a);
    return td;
  }

  function row(a, b) {
    var tr = create("tr");
    tr.appendChild(col(a));
    tr.appendChild(col(b));
    return tr;
  }

  this.timelimit = create("input");
  this.timelimit.setAttribute("value", "60");

  table.appendChild(row(text("Time limit in seconds"), this.timelimit));

  this.autoscale = create("input");
  this.autoscale.setAttribute("type", "checkbox");
  this.autoscale.setAttribute("checked", "true");
  table.appendChild(row(text("Autoscale pauses plot"), this.autoscale));

  var button = create("input");
  button.setAttribute("type", "submit");
  button.setAttribute("value", "Start");
  this.form.appendChild(table);
  this.form.appendChild(button);

  document.body.appendChild(this.form);
}


Form.prototype.remove = function () {
  document.body.removeChild(this.form);
};


function init() {
  livePoints = new PointsList;
  dyingPoints = new PointsList;

  splayTree = new SplayTree();

  scene = new Scene(640, 480);

  div = document.createElement("div");
  document.body.appendChild(div);

  pausePlot = new PausePlot(480, autoScale ? 240 : 500, 160, autoScale ? void 0 : 500);
}

function start() {
  benchmarkTimeLimit = form.timelimit.value * 1000;
  autoScale = form.autoscale.checked;
  form.remove();
  init();
  render();
}

var form = new Form();
