"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var dependents_1 = require("../dependents");
var bbox_1 = tslib_1.__importDefault(require("../util/bbox"));
var util_1 = require("@antv/util");
var base_1 = tslib_1.__importDefault(require("./base"));
var data_range_1 = require("./helper/data-range");
var constant_1 = require("@antv/g2/lib/constant");
var constants_1 = require("../base/constants");
var DEFAULT_PADDING = 4;
var DEFAULT_SIZE = 8;
var DEFAULT_CATEGORY_SIZE = 32;
var MIN_THUMB_LENGTH = 20;
var SCROLL_BAR_Z_INDEX = 999;
var getValidScrollbarConfig = function (cfg) {
    if (cfg === void 0) { cfg = {}; }
    var _cfg = tslib_1.__assign({ type: 'horizontal', categorySize: DEFAULT_CATEGORY_SIZE, width: DEFAULT_SIZE, height: DEFAULT_SIZE, padding: [0, 0, 0, 0] }, cfg);
    // default padding
    if (!cfg.padding) {
        _cfg.padding =
            _cfg.type === 'horizontal' ? [DEFAULT_PADDING, 0, DEFAULT_PADDING, 0] : [0, DEFAULT_PADDING, 0, DEFAULT_PADDING];
    }
    return _cfg;
};
var ScrollbarInteraction = /** @class */ (function (_super) {
    tslib_1.__extends(ScrollbarInteraction, _super);
    function ScrollbarInteraction() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.onChangeFn = util_1.throttle(_this.onChange.bind(_this), 20, {
            leading: true,
        });
        return _this;
    }
    ScrollbarInteraction.getInteractionRange = function (layerRange, interaction) {
        var config = getValidScrollbarConfig(interaction);
        var _a = config.padding, paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3];
        if (config.type === 'horizontal') {
            return new bbox_1.default(layerRange.minX, layerRange.maxY - config.height - paddingTop - paddingBottom, layerRange.width, config.height + paddingTop + paddingBottom);
        }
        else {
            return new bbox_1.default(layerRange.maxX - config.width - paddingLeft - paddingRight, layerRange.minY, config.width + paddingLeft + paddingRight, layerRange.height);
        }
    };
    ScrollbarInteraction.prototype.render = function () {
        var _this = this;
        var layer = this.getViewLayer();
        var view = this.view;
        this.ratio = 0;
        this.thumbOffset = 0;
        var callback = function () {
            var padding = _this.view.padding;
            // if we're not in `auto padding` process
            if (padding === 'auto' || util_1.isEqual(padding, [0, 0, 0, 1])) {
                return;
            }
            if (!_this.trackLen) {
                _this.measureScrollBar();
                _this.changeViewData(_this.getScrollRange(), true);
            }
            else {
                _this.renderScrollbar();
            }
        };
        var changeDataCallback = function () {
            // reset
            _this.trackLen = 0;
        };
        view.on(constant_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback);
        this.addDisposable(function () { return view.off(constant_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); });
        view.on(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback);
        this.addDisposable(function () { return view.off(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); });
        layer.on(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_CHANGE_DATA, changeDataCallback);
        this.addDisposable(function () { return layer.off(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_CHANGE_DATA, changeDataCallback); });
    };
    ScrollbarInteraction.prototype.start = function () {
        return;
    };
    ScrollbarInteraction.prototype.clear = function () {
        if (this.scrollbar) {
            this.scrollbar.destroy();
            this.scrollbar = null;
        }
        if (this.container) {
            this.container.remove(true);
            this.container = null;
        }
        this.trackLen = null;
        this.thumbLen = null;
    };
    ScrollbarInteraction.prototype.renderScrollbar = function () {
        var config = getValidScrollbarConfig(this.getInteractionConfig());
        var range = this.getRange();
        var isHorizontal = config.type !== 'vertical';
        var panelRange = this.view.coordinateBBox;
        var _a = config.padding, paddingTop = _a[0], paddingLeft = _a[3];
        var position = isHorizontal
            ? { x: panelRange.minX + paddingLeft, y: range.minY + paddingTop }
            : { x: range.minX + paddingLeft, y: panelRange.minY + paddingTop };
        if (!this.scrollbar) {
            this.container = this.canvas.addGroup();
            this.scrollbar = new dependents_1.Scrollbar({
                container: this.container,
                x: position.x,
                y: position.y,
                isHorizontal: isHorizontal,
                trackLen: this.trackLen,
                thumbLen: this.thumbLen,
                thumbOffset: this.ratio * this.trackLen,
            });
            this.scrollbar.init();
            this.scrollbar.render();
            this.scrollbar.get('group').set('zIndex', SCROLL_BAR_Z_INDEX);
            this.scrollbar.on('scrollchange', this.onChangeFn);
        }
        else {
            this.scrollbar.update({
                trackLen: this.trackLen,
                thumbLen: this.thumbLen,
                thumbOffset: this.thumbOffset,
                x: position.x,
                y: position.y,
            });
            this.scrollbar.render();
        }
    };
    ScrollbarInteraction.prototype.measureScrollBar = function () {
        var config = getValidScrollbarConfig(this.getInteractionConfig());
        var _a = config.padding, paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3];
        var isHorizontal = config.type !== 'vertical';
        var panelRange = this.view.coordinateBBox;
        var xScale = this.view.getXScale();
        var yScales = this.view.getYScales().filter(function (scale) { return scale; });
        this.cnt = xScale.values.length;
        this.xScaleCfg = { field: xScale.field, values: xScale.values || [] };
        this.yScalesCfg = yScales;
        this.step = Math.floor((isHorizontal ? panelRange.width : panelRange.height) / config.categorySize);
        this.trackLen = isHorizontal
            ? panelRange.width - paddingLeft - paddingRight
            : panelRange.height - paddingTop - paddingBottom;
        this.thumbLen = Math.max(this.trackLen * util_1.clamp(this.step / xScale.values.length, 0, 1), MIN_THUMB_LENGTH);
    };
    ScrollbarInteraction.prototype.getScrollRange = function () {
        var startIdx = Math.floor((this.cnt - this.step) * util_1.clamp(this.ratio, 0, 1));
        var endIdx = Math.min(startIdx + this.step, this.cnt);
        return [startIdx, endIdx];
    };
    ScrollbarInteraction.prototype.changeViewData = function (_a, render) {
        var _this = this;
        var startIdx = _a[0], endIdx = _a[1];
        var config = getValidScrollbarConfig(this.getInteractionConfig());
        var viewLayer = this.getViewLayer();
        var meta = viewLayer.options.meta;
        var origData = viewLayer.getData();
        var newData = data_range_1.getDataByScaleRange(this.xScaleCfg.field, this.xScaleCfg.values, origData, [startIdx, endIdx], config.type === 'vertical');
        // ScrollBar在滚动过程中保持Y轴上scale配置: min/max/ticks
        this.yScalesCfg.forEach(function (cfg) {
            var metaCfg = util_1.get(meta, cfg.field) || {};
            _this.view.scale(cfg.field, tslib_1.__assign(tslib_1.__assign({ formatter: cfg.formatter }, metaCfg), { type: cfg.type, min: cfg.min, max: cfg.max }));
        });
        if (render) {
            this.view.data(newData);
            this.view.render();
        }
        else {
            this.view.changeData(newData);
        }
    };
    ScrollbarInteraction.prototype.onChange = function (_a) {
        var ratio = _a.ratio, thumbOffset = _a.thumbOffset;
        this.ratio = ratio;
        this.thumbOffset = thumbOffset;
        var origAnimate = this.view.getOptions().animate;
        this.view.animate(false);
        this.changeViewData(this.getScrollRange(), true);
        this.view.animate(origAnimate);
        // update scrollbar
        this.renderScrollbar();
    };
    return ScrollbarInteraction;
}(base_1.default));
exports.default = ScrollbarInteraction;
//# sourceMappingURL=scrollbar.js.map