<!--
Copyright (c) 2012 Cameron Adams. All rights reserved.
Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Copyright (C) 2013 Google Inc. 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 Code Aurora Forum Inc., 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 test is based on code written by Cameron Adams and imported from
  http://themaninblue.com/experiment/AnimationBenchmark/html
-->

<!doctype html>
<head>
<title>Benchmark - Balls Animation using requestAnimationFrame</title>
<style>
html {
    height: 100%;
}

body {
    width: 100%;
    height: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
}

span {
    position: absolute;
    width: 12px;
    height: 12px;
    border-radius: 6px;
}
</style>
<script>
var framesPerTimerReading = 10;
var maxFrameTimes = 30;
var stageWidth = 600;
var stageHeight = 600;
var maxParticles = 2500;
var minVelocity = 50;
var maxVelocity = 500;
var particleRadius = 6;
var colors = ["#cc0000", "#ffcc00", "#aaff00", "#0099cc", "#194c99", "#661999"];

var testRunning = true;
var frameCount = 0;
var frameTimes = [];
var particles = [];
var prevTime;

window.onload = function () {
    PerfTestRunner.prepareToMeasureValuesAsync({done: onCompletedRun, unit: 'fps'});

    // Create the particles
    for (var i = 0; i < maxParticles; i++)
        particles.push(new Particle());

    // Start the animation
    prevTime = PerfTestRunner.now();
    animate();
}

function animate()
{
    var currTime = PerfTestRunner.now();
    var timeDelta = currTime - prevTime;

    // Draw each particle
    for (var particle in particles)
        particles[particle].draw(timeDelta);

    if ((frameCount++ % framesPerTimerReading) == 0) {
        // Limit the frame time array to the last 30 frames
        while (frameTimes.length > maxFrameTimes)
            frameTimes.splice(0, 1);

        // Calculate the framerate based upon the difference between the absolute times of the oldest and newest frames
        // subdivided by how many frames were drawn inbetween
        var frameRate = framesPerTimerReading * 1000 / ((currTime - frameTimes[0]) / frameTimes.length);
        if (!isNaN(frameRate))
            PerfTestRunner.measureValueAsync(frameRate);

        frameTimes.push(currTime);
    }

    prevTime = currTime;

    if (testRunning)
        requestAnimationFrame(animate);
}

function Particle()
{
    var angle = Math.PI * 2 * PerfTestRunner.random();
    var velocity = minVelocity + ((maxVelocity - minVelocity) * PerfTestRunner.random());
    var x = stageWidth / 2 - particleRadius;
    var y = stageHeight / 2 - particleRadius;
    var dx = Math.cos(angle) * velocity;
    var dy = Math.sin(angle) * velocity;

    // Create visual element for the particle
    var domNode = document.createElement('span');
    document.body.appendChild(domNode);

    // Set initial position to middle of screen
    domNode.style.left = x + "px";
    domNode.style.top = y + "px";

    // Set colour of element
    domNode.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];

    function destroy()
    {
        document.body.removeChild(domNode);
    }

    function draw(timeDelta)
    {
        var timeDeltaSeconds = timeDelta / 1000;
        var testX = x + (dx * timeDeltaSeconds);
        var testY = y + (dy * timeDeltaSeconds);

        if (testX < 0 || testX > stageWidth) {
            dx = -dx;
            x += dx;
        } else {
            x = testX;
        }
        if (testY < 0 || testY > stageHeight) {
            dy = -dy;
            y += dy;
        } else {
            y = testY;
        }

        domNode.style.left = x + "px";
        domNode.style.top = y + "px";
    }

    this.draw = draw;
    this.destroy = destroy;
}

function onCompletedRun() {
    testRunning = false;

    for (var i = 0; i < particles.length; i++)
        particles[i].destroy();
    particles = [];
}
</script>
<script src="../resources/runner.js"></script>
</head>
</html>
