'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var MIN_INERVAL = 1000 / 60;

/**
 * Trigger a callback at a given interval
 * @param interval defaults to 1000/60 ms
 * @return {function()} reference to start, stop, immediate and started
 */

var intervalFunction = function intervalFunction() {
  var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MIN_INERVAL;


  var lapse = interval < MIN_INERVAL ? MIN_INERVAL : interval;
  var cb = undefined;
  var next = null;
  var timeElapsed = 0;

  var execute = function execute() {
    var f = cb(timeElapsed);
    if (!f) {
      cancel();
    }
  };

  var cancel = function cancel() {
    if (next) {
      window.cancelAnimationFrame(next);
    }
    next = null;
    timeElapsed = 0;
  };

  var _start = function _start() {
    var timeStart = Date.now();

    var loop = function loop(now) {
      if (next) {
        next = window.requestAnimationFrame(function () {
          return loop(Date.now());
        });

        timeElapsed += now - timeStart;

        if (timeElapsed >= lapse) {
          execute();
          if ((timeElapsed -= lapse) > lapse) {
            // time elapsed - interval_ > interval_ , indicates inactivity
            // Could be due to browser minimized, tab changed, screen saver started, computer sleep, and so on
            timeElapsed = 0;
          }
        }
        timeStart = now;
      }
    };

    next = 1; // a truthy value for first loop
    loop(timeStart);
  };

  return {
    get started() {
      return next != null;
    },
    get interval() {
      return lapse;
    },
    set interval(value) {
      lapse = value < MIN_INERVAL ? MIN_INERVAL : value;
    },
    start: function start(callback) {
      if (typeof callback !== 'function') {
        throw new TypeError('callback parameter must be a function');
      }
      cb = callback;
      _start();
    },
    immediate: function immediate() {
      if (!cb) {
        throw new ReferenceError('callback parameter is not defined. Call start before immediate.');
      }
      execute();
    },

    stop: function stop() {
      return cancel();
    }
  };
};

exports.default = intervalFunction;
module.exports = exports['default'];