"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get default () {
        return _default;
    },
    get parseDelay () {
        return parseDelay;
    }
});
const _feature = require("./../helpers/feature");
function _check_private_redeclaration(obj, privateCollection) {
    if (privateCollection.has(obj)) {
        throw new TypeError("Cannot initialize the same private elements twice on an object");
    }
}
function _class_apply_descriptor_get(receiver, descriptor) {
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}
function _class_apply_descriptor_set(receiver, descriptor, value) {
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
}
function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to " + action + " private field on non-instance");
    }
    return privateMap.get(receiver);
}
function _class_private_field_get(receiver, privateMap) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
    return _class_apply_descriptor_get(receiver, descriptor);
}
function _class_private_field_init(obj, privateMap, value) {
    _check_private_redeclaration(obj, privateMap);
    privateMap.set(obj, value);
}
function _class_private_field_set(receiver, privateMap, value) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
    _class_apply_descriptor_set(receiver, descriptor, value);
    return value;
}
function _class_private_method_get(receiver, privateSet, fn) {
    if (!privateSet.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return fn;
}
function _class_private_method_init(obj, privateSet) {
    _check_private_redeclaration(obj, privateSet);
    privateSet.add(obj);
}
var /**
   * Animation frame request id.
   *
   * @type {number}
   */ _timer = /*#__PURE__*/ new WeakMap(), /**
   * Function to invoke repeatedly.
   *
   * @type {Function}
   */ _func = /*#__PURE__*/ new WeakMap(), /**
   * Flag which indicates if interval object was stopped.
   *
   * @type {boolean}
   * @default true
   */ _stopped = /*#__PURE__*/ new WeakMap(), /**
   * Interval time (in milliseconds) of the last callback call.
   *
   * @type {number}
   */ _then = /*#__PURE__*/ new WeakMap(), /**
   * Bounded function `func`.
   *
   * @type {Function}
   */ _callback = /*#__PURE__*/ new WeakMap(), /**
   * Loop callback, fired on every animation frame.
   */ ___callback = /*#__PURE__*/ new WeakSet();
/**
 * @class Interval
 */ class Interval {
    static create(func, delay) {
        return new Interval(func, delay);
    }
    /**
   * Start loop.
   *
   * @returns {Interval}
   */ start() {
        if (_class_private_field_get(this, _stopped)) {
            _class_private_field_set(this, _then, Date.now());
            _class_private_field_set(this, _stopped, false);
            _class_private_field_set(this, _timer, (0, _feature.requestAnimationFrame)(_class_private_field_get(this, _callback)));
        }
        return this;
    }
    /**
   * Stop looping.
   *
   * @returns {Interval}
   */ stop() {
        if (!_class_private_field_get(this, _stopped)) {
            _class_private_field_set(this, _stopped, true);
            (0, _feature.cancelAnimationFrame)(_class_private_field_get(this, _timer));
            _class_private_field_set(this, _timer, null);
        }
        return this;
    }
    constructor(func, delay){
        _class_private_method_init(this, ___callback);
        _class_private_field_init(this, _timer, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _func, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _stopped, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _then, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _callback, {
            writable: true,
            value: void 0
        });
        _class_private_field_set(this, _timer, null);
        _class_private_field_set(this, _stopped, true);
        _class_private_field_set(this, _then, null);
        _class_private_field_set(this, _func, func);
        this.delay = parseDelay(delay);
        _class_private_field_set(this, _callback, ()=>_class_private_method_get(this, ___callback, __callback).call(this));
    }
}
function __callback() {
    _class_private_field_set(this, _timer, (0, _feature.requestAnimationFrame)(_class_private_field_get(this, _callback)));
    if (this.delay) {
        const now = Date.now();
        const elapsed = now - _class_private_field_get(this, _then);
        if (elapsed > this.delay) {
            _class_private_field_set(this, _then, now - elapsed % this.delay);
            _class_private_field_get(this, _func).call(this);
        }
    } else {
        _class_private_field_get(this, _func).call(this);
    }
}
const _default = Interval;
function parseDelay(delay) {
    let result = delay;
    if (typeof result === 'string' && /fps$/.test(result)) {
        result = 1000 / parseInt(result.replace('fps', '') || 0, 10);
    }
    return result;
}
