<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/base/utils.html">
<script>
'use strict';

tr.exportTo('tr.b', function() {
  // Setting this to true will cause stack traces to get dumped into the
  // tasks. When an exception happens the original stack will be printed.
  //
  // NOTE: This should never be set committed as true.
  var recordRAFStacks = false;

  var pendingPreAFs = [];
  var pendingRAFs = [];
  var pendingIdleCallbacks = [];
  var currentRAFDispatchList = undefined;

  var rafScheduled = false;

  function scheduleRAF() {
    if (rafScheduled)
      return;
    rafScheduled = true;
    if (tr.isHeadless) {
      Promise.resolve().then(function() {
        processRequests(0);
      }, function(e) {
        console.log(e.stack);
        throw e;
      });
    } else {
      if (window.requestAnimationFrame) {
        window.requestAnimationFrame(processRequests);
      } else {
        var delta = Date.now() - window.performance.now();
        window.webkitRequestAnimationFrame(function(domTimeStamp) {
          processRequests(domTimeStamp - delta);
        });
      }
    }
  }

  function onAnimationFrameError(e, opt_stack) {
    console.log(e.stack);
    if (tr.isHeadless)
      throw e;

    if (opt_stack)
      console.log(opt_stack);

    if (e.message)
      console.error(e.message, e.stack);
    else
      console.error(e);
  }

  function runTask(task, frameBeginTime) {
    try {
      task.callback.call(task.context, frameBeginTime);
    } catch (e) {
      tr.b.onAnimationFrameError(e, task.stack);
    }
  }

  function processRequests(frameBeginTime) {
    // We assume that we want to do a maximum of 10ms optional work per frame.
    // Hopefully rAF will eventually pass this in for us.
    var rafCompletionDeadline = frameBeginTime + 10;

    rafScheduled = false;


    var currentPreAFs = pendingPreAFs;
    currentRAFDispatchList = pendingRAFs;
    pendingPreAFs = [];
    pendingRAFs = [];
    var hasRAFTasks = currentPreAFs.length || currentRAFDispatchList.length;

    for (var i = 0; i < currentPreAFs.length; i++)
      runTask(currentPreAFs[i], frameBeginTime);

    while (currentRAFDispatchList.length > 0)
      runTask(currentRAFDispatchList.shift(), frameBeginTime);
    currentRAFDispatchList = undefined;

    if (!hasRAFTasks) {
      while (pendingIdleCallbacks.length > 0) {
        runTask(pendingIdleCallbacks.shift());
        // Check timer after running at least one idle task to avoid buggy
        // window.performance.now() on some platforms from blocking the idle
        // task queue.
        if (tr.isHeadless || window.performance.now() >= rafCompletionDeadline)
          break;
      }
    }

    if (pendingIdleCallbacks.length > 0)
      scheduleRAF();
  }

  function getStack_() {
    if (!recordRAFStacks)
      return '';

    var stackLines = tr.b.stackTrace();
    // Strip off getStack_.
    stackLines.shift();
    return stackLines.join('\n');
  }

  function requestPreAnimationFrame(callback, opt_this) {
    pendingPreAFs.push({
      callback: callback,
      context: opt_this || window,
      stack: getStack_()});
    scheduleRAF();
  }

  function requestAnimationFrameInThisFrameIfPossible(callback, opt_this) {
    if (!currentRAFDispatchList) {
      requestAnimationFrame(callback, opt_this);
      return;
    }
    currentRAFDispatchList.push({
      callback: callback,
      context: opt_this || window,
      stack: getStack_()});
    return;
  }

  function requestAnimationFrame(callback, opt_this) {
    pendingRAFs.push({
      callback: callback,
      context: opt_this || window,
      stack: getStack_()});
    scheduleRAF();
  }

  function requestIdleCallback(callback, opt_this) {
    pendingIdleCallbacks.push({
      callback: callback,
      context: opt_this || window,
      stack: getStack_()});
    scheduleRAF();
  }

  function forcePendingRAFTasksToRun(frameBeginTime) {
    if (!rafScheduled)
      return;
    processRequests(frameBeginTime);
  }

  return {
    onAnimationFrameError: onAnimationFrameError,
    requestPreAnimationFrame: requestPreAnimationFrame,
    requestAnimationFrame: requestAnimationFrame,
    requestAnimationFrameInThisFrameIfPossible:
        requestAnimationFrameInThisFrameIfPossible,
    requestIdleCallback: requestIdleCallback,
    forcePendingRAFTasksToRun: forcePendingRAFTasksToRun
  };
});
</script>
