"use strict";

// refactor ok

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Measuring time (e.g. of the code execution, or for passing time into shaders) and elapsed frames.
 *
 * @author smrceant (Antonin Smrcek)
 *
 * @param         {boolean} [start] if TRUE, measuring starts immediately (default is FALSE)
 * @constructor
 */
var TimeMeasure = function (start)
{
  if (!Util.isInitialized(start))
  {
    var start = false;
  }

  /**
   * Time when the timer has started.
   *
   * @type {number}
   */
  this.startTime = null;

  /**
   * Is the timer running?
   *
   * @type {boolean}
   */
  this.running = false;

  if (start || arguments.length === 0)
  {
    this.start();
  }

  /**
   * How many frames have elapsed since application start.
   *
   * @type {number}
   */
  this.elapsedFrames = 0;

  /**
   * Start time of the current frame.
   *
   * @type {number}
   */
  this.currentFrameStart = 0;

  /**
   * All collected frame times.
   *
   * @type {number[]}
   */
  this.frameTimes = [];

  this.runningBenchmark = false;

  this.benchmarkTimelimit = 60 * 1000;
  this.benchmarkStart = 0;

  if (Preferences.Application.MEASURE_FRAME_TIME)
  {
    this.$msPerFrame = $('<div style="position: absolute; top: 10px; left: 50%; color: yellow; background-color: black; font-size: 2.5vh"></div>');
    $("body").append (this.$msPerFrame);
  }
};

/**
 * Starts measuring of the time.
 */
TimeMeasure.prototype.start = function()
{
  this.running = true;
  this.startTime = Date.now();
};

/**
 *
 * @returns {number}    elapsed time in ms since the time measurement has started
 */
TimeMeasure.prototype.getElapsedTime = function()
{
  if (!this.running)
  {
    console.error ("Time measure has not yet started.");
    return 0;
  }

  return ( Date.now() - this.startTime );
};

TimeMeasure.prototype.startBenchmark = function()
{
  this.benchmarkStart = Date.now();
};

/**
 * Records starting time of current frame.
 */
TimeMeasure.prototype.startFrame = function()
{
  if (this.benchmarkStart === 0)
  {
    this.benchmarkStart = Date.now();
  }
  this.currentFrameStart = Date.now();
};

/**
 * Computes how long the frame took and saves into the array of records.
 */
TimeMeasure.prototype.endFrame = function()
{
  if (!this.runningBenchmark) return;

  var now = Date.now();
  var ms = now - this.currentFrameStart;

  if (now - this.benchmarkStart >= this.benchmarkTimelimit)
  {
    this.frameTimes.push (ms);
  }


  if (ms < 10)
  {
    ms = "0" + ms.toFixed(0);
  }
  else
  {
    ms = ms.toFixed();
  }

  if (Util.isInitialized(this.$msPerFrame))
  {
    this.$msPerFrame.html(ms);

    if (now - this.benchmarkStart >= this.benchmarkTimelimit)
    {
      this.$msPerFrame.html("Benchmark ended.");

      var avgMs = 0;
      for (var i = 0; i < this.frameTimes.length; i++)
      {
        avgMs += this.frameTimes[i];
      }

      avgMs /= this.frameTimes.length;

      var avgFps =  (1 / avgMs)*1000;

      this.$msPerFrame.html("ms: " + avgMs.toFixed(2) + "\n" + "fps: " + avgFps.toFixed(2));

      this.runningBenchmark = false;
    }
  }

};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
