import { vglobal } from "./../vrender";

import { isObject } from "./isx";

export function debounce(func, wait, options) {
    let lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, maxing = !1, leading = !1, trailing = !0;
    const useRAF = !wait && 0 !== wait && "function" == typeof vglobal.getRequestAnimationFrame();
    if ("function" != typeof func) throw new TypeError("Expected a function");
    function invokeFunc(time) {
        const args = lastArgs, thisArg = lastThis;
        return lastThis = void 0, lastArgs = void 0, lastInvokeTime = time, result = func.apply(thisArg, args), 
        result;
    }
    function startTimer(pendingFunc, wait) {
        return useRAF ? vglobal.getRequestAnimationFrame()(pendingFunc) : setTimeout(pendingFunc, wait);
    }
    function shouldInvoke(time) {
        const timeSinceLastCall = time - lastCallTime;
        return void 0 === lastCallTime || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && time - lastInvokeTime >= maxWait;
    }
    function timerExpired() {
        const time = Date.now();
        if (shouldInvoke(time)) return function(time) {
            return timerId = void 0, trailing && lastArgs ? invokeFunc(time) : (lastThis = void 0, 
            lastArgs = void 0, result);
        }(time);
        timerId = startTimer(timerExpired, function(time) {
            const timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait && -(time - lastCallTime);
            return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
        }(time));
    }
    return wait = +wait || 0, isObject(options) && (leading = !!options.leading, maxing = "maxWait" in options, 
    maxing && (maxWait = Math.max(+options.maxWait || 0, wait)), trailing = "trailing" in options ? !!options.trailing : trailing), 
    function(...args) {
        const time = Date.now(), isInvoking = shouldInvoke(time);
        if (lastArgs = args, lastThis = this, lastCallTime = time, isInvoking) {
            if (void 0 === timerId) return function(time) {
                return lastInvokeTime = time, timerId = startTimer(timerExpired, wait), leading ? invokeFunc(time) : result;
            }(lastCallTime);
            if (maxing) return timerId = startTimer(timerExpired, wait), invokeFunc(lastCallTime);
        }
        return void 0 === timerId && (timerId = startTimer(timerExpired, wait)), result;
    };
}
//# sourceMappingURL=debounce.js.map
