var __rest = this && this.__rest || function(s, e) {
    var t = {};
    for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
    if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
        var i = 0;
        for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
    }
    return t;
};

import { isValidNumber, merge } from "@visactor/vutils";

import { BasePlugin } from "../../base/base-plugin";

import { registerChartPlugin } from "../register";

import { ScrollBar as ScrollBarComponent } from "@visactor/vrender-components";

import { Event } from "../../../event/event";

const SCROLLBAR_EVENT = "scrollDrag", SCROLLBAR_END_EVENT = "scrollUp", DefaultTheme = {
    size: 10,
    railStyle: void 0,
    sliderStyle: void 0
};

export class ScrollPlugin extends BasePlugin {
    get lastScrollX() {
        return this._lastScrollX;
    }
    get lastScrollY() {
        return this._lastScrollY;
    }
    constructor() {
        super(ScrollPlugin.type), this.type = "chartScroll", this.name = ScrollPlugin.type, 
        this._lastScrollX = 0, this._lastScrollY = 0, this._scrollLimit = {
            x: {
                min: 0,
                max: 0,
                size: 0,
                percent: 0
            },
            y: {
                min: 0,
                max: 0,
                size: 0,
                percent: 0
            }
        }, this.onWheel = e => {
            var _a, _b;
            !1 !== this._spec.preventDefault && (e.preventDefault(), e.stopPropagation());
            const scrollX = e.deltaX, scrollY = e.deltaY, rootMark = this.getRootMark();
            if (!rootMark) return;
            const {percent: yPercent, y: y} = null !== (_a = this._computeFinalScrollY(rootMark.attribute.y - scrollY)) && void 0 !== _a ? _a : {}, {percent: xPercent, x: x} = null !== (_b = this._computeFinalScrollX(rootMark.attribute.x - scrollX)) && void 0 !== _b ? _b : {}, eventResult = {};
            isValidNumber(x) && (this._updateScrollX(rootMark, x, xPercent), eventResult.x = x), 
            isValidNumber(y) && (this._updateScrollY(rootMark, y, yPercent), eventResult.y = y), 
            this._event.emit("chartScroll", eventResult);
        };
    }
    onInit(service, chartSpec) {
        var _a;
        this._spec = null !== (_a = chartSpec[ScrollPlugin.type]) && void 0 !== _a ? _a : {}, 
        this._service = service, this._bindEvent(service);
    }
    onLayoutRectUpdate(service) {
        const viewBoxSize = service.globalInstance.getChart().getViewRect(), canvasSize = service.globalInstance.getChart().getCanvasRect();
        this._scrollLimit.x.min = Math.min(canvasSize.width - viewBoxSize.width, 0), this._scrollLimit.x.percent = Math.abs(canvasSize.width / viewBoxSize.width), 
        this._scrollLimit.x.size = viewBoxSize.width, this._scrollLimit.y.min = Math.min(canvasSize.height - viewBoxSize.height, 0), 
        this._scrollLimit.y.percent = Math.abs(canvasSize.height / viewBoxSize.height), 
        this._scrollLimit.y.size = viewBoxSize.height, this._event || (this._event = new Event(this._service.globalInstance.getChart().getOption().eventDispatcher, null)), 
        this._xScrollComponent && (this._xScrollComponent.setAttributes({
            width: canvasSize.width,
            y: canvasSize.height - DefaultTheme.size
        }), this._xScrollComponent.setAttributes({
            visible: this._scrollLimit.x.percent < 1
        })), this._yScrollComponent && (this._yScrollComponent.setAttributes({
            height: canvasSize.height,
            x: canvasSize.width - DefaultTheme.size
        }), this._yScrollComponent.setAttributes({
            visible: this._scrollLimit.y.percent < 1
        }));
    }
    onAfterRender() {}
    release() {
        var _a;
        null === (_a = this._service.globalInstance.getStage()) || void 0 === _a || _a.off("wheel", this.onWheel);
    }
    _bindEvent(service) {
        var _a;
        null === (_a = service.globalInstance.getStage()) || void 0 === _a || _a.on("wheel", this.onWheel);
    }
    getRootMark() {
        var _a;
        return null === (_a = this._service.globalInstance.getStage()) || void 0 === _a ? void 0 : _a.find((node => "root" === node.name), !0);
    }
    _computeFinalScrollY(y) {
        var _a;
        if (this._lastScrollY === y) return null;
        if (this._lastScrollY = y, !1 === (null === (_a = this._spec.y) || void 0 === _a ? void 0 : _a.enable)) return null;
        const finalY = Math.max(this._scrollLimit.y.min, Math.min(y, this._scrollLimit.y.max));
        return {
            y: finalY,
            percent: Math.abs(finalY / this._scrollLimit.y.size)
        };
    }
    _computeFinalScrollX(x) {
        var _a;
        if (this._lastScrollX === x) return null;
        if (this._lastScrollX = x, !1 === (null === (_a = this._spec.x) || void 0 === _a ? void 0 : _a.enable)) return null;
        const finalX = Math.max(this._scrollLimit.x.min, Math.min(x, this._scrollLimit.x.max));
        return {
            x: finalX,
            percent: Math.abs(finalX / this._scrollLimit.x.size)
        };
    }
    _updateScrollY(rootMark, y, percent) {
        this._getYScrollComponent().setAttribute("range", [ percent, percent + this._scrollLimit.y.percent ]), 
        rootMark.setAttributes({
            y: y
        });
    }
    _getYScrollComponent() {
        var _a, _b, _c, _d, _e;
        if (!this._yScrollComponent) {
            const canvasSize = this._service.globalInstance.getChart().getCanvasRect(), viewSize = this._service.globalInstance.getChart().getViewRect(), _f = null !== (_b = null === (_a = this._spec) || void 0 === _a ? void 0 : _a.y) && void 0 !== _b ? _b : {}, {enable: enable} = _f, rest = __rest(_f, [ "enable" ]);
            this._yScrollComponent = new ScrollBarComponent(Object.assign(Object.assign({}, rest), {
                zIndex: 9999,
                x: canvasSize.width - DefaultTheme.size,
                y: 0,
                width: DefaultTheme.size,
                height: canvasSize.height,
                range: [ 0, canvasSize.height / viewSize.height ],
                direction: "vertical",
                delayTime: null !== (_c = null == rest ? void 0 : rest.delayTime) && void 0 !== _c ? _c : 30,
                realTime: null === (_d = null == rest ? void 0 : rest.realTime) || void 0 === _d || _d,
                railStyle: DefaultTheme.railStyle,
                sliderStyle: DefaultTheme.sliderStyle,
                visible: canvasSize.height < viewSize.height
            })), this._yScrollComponent.addEventListener("scrollDrag", (e => {
                var _a;
                const value = e.detail.value, {percent: percent, y: y} = null !== (_a = this._computeFinalScrollY(-value[0] * this._scrollLimit.y.size)) && void 0 !== _a ? _a : {};
                void 0 !== percent && void 0 !== y && (this._updateScrollY(this.getRootMark(), y, percent), 
                this._event.emit("chartScroll", {
                    y: y
                }));
            })), this._yScrollComponent.addEventListener("scrollUp", (e => {
                var _a;
                const value = e.detail.value, {percent: percent, y: y} = null !== (_a = this._computeFinalScrollY(-value[0] * this._scrollLimit.y.size)) && void 0 !== _a ? _a : {};
                void 0 !== percent && void 0 !== y && (this._updateScrollY(this.getRootMark(), y, percent), 
                this._event.emit("chartScroll", {
                    y: y
                }));
            })), null === (_e = this.getRootMark().parent) || void 0 === _e || _e.addChild(this._yScrollComponent);
        }
        return this._yScrollComponent;
    }
    _updateScrollX(rootMark, x, percent) {
        this._getXScrollComponent().setAttribute("range", [ percent, percent + this._scrollLimit.x.percent ]), 
        rootMark.setAttributes({
            x: x
        });
    }
    _getXScrollComponent() {
        var _a, _b, _c, _d, _e;
        if (!this._xScrollComponent) {
            const canvasSize = this._service.globalInstance.getChart().getCanvasRect(), viewSize = this._service.globalInstance.getChart().getViewRect(), _f = null !== (_b = null === (_a = this._spec) || void 0 === _a ? void 0 : _a.x) && void 0 !== _b ? _b : {}, {enable: enable} = _f, rest = __rest(_f, [ "enable" ]);
            this._xScrollComponent = new ScrollBarComponent(Object.assign(Object.assign({}, rest), {
                zIndex: 9999,
                x: 0,
                y: canvasSize.height - DefaultTheme.size,
                width: canvasSize.width,
                height: DefaultTheme.size,
                range: [ 0, canvasSize.width / viewSize.width ],
                direction: "horizontal",
                delayTime: null !== (_c = null == rest ? void 0 : rest.delayTime) && void 0 !== _c ? _c : 30,
                realTime: null === (_d = null == rest ? void 0 : rest.realTime) || void 0 === _d || _d,
                sliderStyle: DefaultTheme.sliderStyle,
                railStyle: DefaultTheme.railStyle,
                visible: canvasSize.width < viewSize.width
            })), this._xScrollComponent.addEventListener("scrollDrag", (e => {
                var _a;
                const value = e.detail.value, {percent: percent, x: x} = null !== (_a = this._computeFinalScrollX(-value[0] * this._scrollLimit.x.size)) && void 0 !== _a ? _a : {};
                void 0 !== percent && void 0 !== x && (this._updateScrollX(this.getRootMark(), x, percent), 
                this._event.emit("chartScroll", {
                    x: x
                }));
            })), this._xScrollComponent.addEventListener("scrollUp", (e => {
                var _a;
                const value = e.detail.value, {percent: percent, x: x} = null !== (_a = this._computeFinalScrollX(-value[0] * this._scrollLimit.x.size)) && void 0 !== _a ? _a : {};
                void 0 !== percent && void 0 !== x && (this._updateScrollX(this.getRootMark(), x, percent), 
                this._event.emit("chartScroll", {
                    x: x
                }));
            })), null === (_e = this.getRootMark().parent) || void 0 === _e || _e.addChild(this._xScrollComponent);
        }
        return this._xScrollComponent;
    }
    scrollTo({x: x, y: y}) {
        var _a, _b;
        const rootMark = this.getRootMark();
        if (rootMark) {
            if (void 0 !== x) {
                const {x: finalX, percent: percent} = null !== (_a = this._computeFinalScrollX(x)) && void 0 !== _a ? _a : {};
                void 0 !== finalX && void 0 !== percent && this._updateScrollX(rootMark, finalX, percent);
            }
            if (void 0 !== y) {
                const {y: finalY, percent: percent} = null !== (_b = this._computeFinalScrollY(y)) && void 0 !== _b ? _b : {};
                void 0 !== finalY && void 0 !== percent && this._updateScrollY(rootMark, finalY, percent);
            }
        }
    }
}

ScrollPlugin.pluginType = "chart", ScrollPlugin.type = "chartScroll";

export const registerScrollPlugin = theme => {
    var _a, _b, _c, _d, _e;
    DefaultTheme.size = null !== (_a = null == theme ? void 0 : theme.size) && void 0 !== _a ? _a : DefaultTheme.size, 
    DefaultTheme.railStyle = merge({}, null !== (_b = DefaultTheme.railStyle) && void 0 !== _b ? _b : {}, null !== (_c = null == theme ? void 0 : theme.railStyle) && void 0 !== _c ? _c : {}), 
    DefaultTheme.sliderStyle = merge({}, null !== (_d = DefaultTheme.sliderStyle) && void 0 !== _d ? _d : {}, null !== (_e = null == theme ? void 0 : theme.sliderStyle) && void 0 !== _e ? _e : {}), 
    registerChartPlugin(ScrollPlugin);
};
//# sourceMappingURL=scroll.js.map
