import isBrowser from './isBrowser';
var SCROLL_TIME = 250;
var w = isBrowser ? window : {};
var d = isBrowser ? document : {};
var originalScroll = w.scroll || w.scrollTo;
var now = w.performance && w.performance.now
    ? w.performance.now.bind(w.performance)
    : Date.now;
function scrollElement(x, y) {
    this.scrollLeft = x;
    this.scrollTop = y;
}
function ease(k) {
    return 0.5 * (1 - Math.cos(Math.PI * k));
}
function step(context, callback) {
    var time = now();
    var elapsed = (time - context.startTime) / context.duration;
    elapsed = elapsed > 1 ? 1 : elapsed;
    var value = ease(elapsed);
    var currentX = context.startX + (context.x - context.startX) * value;
    var currentY = context.startY + (context.y - context.startY) * value;
    context.method.call(context.scrollable, currentX, currentY);
    if (currentX !== context.x || currentY !== context.y) {
        requestAnimationFrame(step.bind(w, context, callback));
    }
    else {
        callback();
    }
}
export function smoothScroll(el, x, y, duration) {
    if (duration === void 0) { duration = SCROLL_TIME; }
    return new Promise(function (resolve, reject) {
        if (!isBrowser) {
            return reject();
        }
        var scrollable;
        var startX;
        var startY;
        var method;
        var startTime = now();
        if (el === d.body || el === w) {
            scrollable = w;
            startX = w.scrollX || w.pageXOffset;
            startY = w.scrollY || w.pageYOffset;
            method = originalScroll;
        }
        else {
            scrollable = el;
            startX = el.scrollLeft;
            startY = el.scrollTop;
            method = scrollElement;
        }
        step({
            duration: duration,
            scrollable: scrollable,
            method: method,
            startTime: startTime,
            startX: startX,
            startY: startY,
            x: x,
            y: y,
        }, resolve);
    });
}
export default smoothScroll;
