import { __awaiter } from "tslib";
import { debounce } from 'lodash';
import { isMobile } from '../../utils/is-mobile';
/**
 * 基于 Canvas 的高清适配方案
 * 1. 双屏切换, devicePixelRatio 变化时
 * 2. Mac 触控板缩放
 * 3. 浏览器窗口缩放
 */
export class HdAdapter {
    constructor(spreadsheet) {
        this.viewport = window;
        this.init = () => {
            this.initDevicePixelRatioListener();
            this.initDeviceZoomListener();
        };
        this.destroy = () => {
            this.removeDevicePixelRatioListener();
            this.removeDeviceZoomListener();
        };
        this.removeDevicePixelRatioListener = () => {
            var _a;
            if ((_a = this.devicePixelRatioMedia) === null || _a === void 0 ? void 0 : _a.removeEventListener) {
                this.devicePixelRatioMedia.removeEventListener('change', this.renderByDevicePixelRatioChanged);
            }
            else {
                this.devicePixelRatioMedia.removeListener(this.renderByDevicePixelRatioChanged);
            }
        };
        this.initDeviceZoomListener = () => {
            var _a, _b;
            if (isMobile()) {
                return;
            }
            /*
             * VisualViewport support browser zoom & mac touch tablet
             * @ts-ignore
             */
            (_b = (_a = this.viewport) === null || _a === void 0 ? void 0 : _a.visualViewport) === null || _b === void 0 ? void 0 : _b.addEventListener('resize', this.renderByZoomScaleWithoutResizeEffect);
        };
        this.removeDeviceZoomListener = () => {
            var _a, _b;
            if (isMobile()) {
                return;
            }
            (_b = (_a = this.viewport) === null || _a === void 0 ? void 0 : _a.visualViewport) === null || _b === void 0 ? void 0 : _b.removeEventListener('resize', this.renderByZoomScaleWithoutResizeEffect);
        };
        /**
         * DPR 改变也会触发 visualViewport 的 resize 事件, 预期是只监听双指缩放, 所以这里规避掉
         * @see https://github.com/antvis/S2/issues/2072
         */
        this.renderByZoomScaleWithoutResizeEffect = (event) => __awaiter(this, void 0, void 0, function* () {
            this.isDevicePixelRatioChange = false;
            yield this.renderByZoomScale(event);
        });
        /**
         * 如果是浏览器窗口的放大缩小 (command +/-), 也会触发
         */
        this.renderByDevicePixelRatioChanged = () => __awaiter(this, void 0, void 0, function* () {
            this.isDevicePixelRatioChange = true;
            yield this.renderByDevicePixelRatio();
        });
        this.renderByDevicePixelRatio = (...args_1) => __awaiter(this, [...args_1], void 0, function* (ratio = window.devicePixelRatio) {
            var _a;
            if (this.spreadsheet.destroyed) {
                return;
            }
            const { container, options: { width, height }, } = this.spreadsheet;
            const canvas = this.spreadsheet.getCanvasElement();
            const currentRatio = Math.ceil(ratio);
            const lastRatio = (_a = container.getConfig().devicePixelRatio) !== null && _a !== void 0 ? _a : 1;
            if (lastRatio === currentRatio || !canvas) {
                return;
            }
            // https://github.com/antvis/G/issues/1143
            container.getConfig().devicePixelRatio = currentRatio;
            container.resize(width, height);
            yield this.spreadsheet.render(false);
        });
        this.renderByZoomScale = debounce((event) => __awaiter(this, void 0, void 0, function* () {
            if (this.spreadsheet.destroyed) {
                return;
            }
            const target = event.target;
            const ratio = Math.ceil(target === null || target === void 0 ? void 0 : target.scale);
            /**
             * github.com/antvis/S2/issues/2884
             * 如果是触控板双指缩放触发的 resize 事件, offsetLeft 可以获取到值
             * 如果是浏览器窗口的放大缩小 (command +/-), offsetLeft 始终是 0
             */
            const isTouchPadZoom = (this.zoomOffsetLeft || 0) !== ((target === null || target === void 0 ? void 0 : target.offsetLeft) || 0);
            if (ratio >= 1 && isTouchPadZoom && !this.isDevicePixelRatioChange) {
                const maxDPR = Math.max(ratio, window.devicePixelRatio);
                yield this.renderByDevicePixelRatio(maxDPR);
                this.zoomOffsetLeft = target.offsetLeft;
            }
        }), 350);
        this.spreadsheet = spreadsheet;
        this.isDevicePixelRatioChange = false;
        this.zoomOffsetLeft = 0;
    }
    initDevicePixelRatioListener() {
        var _a;
        this.devicePixelRatioMedia = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
        if ((_a = this.devicePixelRatioMedia) === null || _a === void 0 ? void 0 : _a.addEventListener) {
            this.devicePixelRatioMedia.addEventListener('change', this.renderByDevicePixelRatioChanged);
        }
        else {
            this.devicePixelRatioMedia.addListener(this.renderByDevicePixelRatioChanged);
        }
    }
}
//# sourceMappingURL=index.js.map