/** @private */
const isSupported = typeof requestIdleCallback === 'function';

/**
 * @author: Aamir Khan
 * A minimal implementation of the native IdleDeadline interface.
 * The IdleDeadline interface is used as the data type of the input parameter to idle callbacks established by calling Window.requestIdleCallback(). It offers a method, timeRemaining(), which lets you determine how much longer the user agent estimates it will remain idle and a property, didTimeout, which lets you determine if your callback is executing because its timeout duration expired.

 */
class IdleDeadline {
/**
 * @constructor
 * @param {number} initTime
 */
  constructor(initTime) {this.initTime_ = initTime;}
  
  /**
   * @return {boolean} 
   * */
  get didTimeout() {
    return false;
  }

  /** @return {number} */
  timeRemaining() {
    return Math.max(0, 50 - (Date.now() - this.initTime_));
  }
}

/**
 * A minimal shim for the requestIdleCallback function. This accepts a
 * callback function and runs it at the next idle period, passing in an
 * object with a `timeRemaining()` method.
 * @private
 * @param {!Function} callback
 * @return {number}
 */
const requestIdleCallbackShim = (callback) => {
  const deadline = new IdleDeadline(Date.now());
  return setTimeout(() => callback(deadline), 0);
};


/**
 * A minimal shim for the  cancelIdleCallback function. This accepts a
 * handle identifying the idle callback to cancel.
 * @private
 * @param {number|null} handle
 */
const cancelIdleCallbackShim = (handle) => {
  clearTimeout(handle);
};


/**
 * The native `requestIdleCallback()` function or `cancelIdleCallbackShim()`
 *.if the browser doesn't support it.
 * @param {!Function} callback
 * @return {number}
 */
export const reqIdleCb = isSupported ? requestIdleCallback : requestIdleCallbackShim;


/**
 * The native `cancelIdleCallback()` function or `cancelIdleCallbackShim()`
 * if the browser doesn't support it.
 * @param {number} handle
 */
export const cancelIdleCb = isSupported ? cancelIdleCallback : cancelIdleCallbackShim;