/*!
 * Built by Revolist OU ❤️
 */
import { h, Host, } from "@stencil/core";
import LocalScrollService, { getContentSize, } from "../../services/local.scroll.service";
import { AutohideScrollPlugin } from "./autohide-scroll.plugin";
import { LocalScrollTimer } from "../../services/local.scroll.timer";
import { getScrollbarSize } from "../../utils";
/**
 * Virtual scroll component
 */
export class RevogrScrollVirtual {
    constructor() {
        /**
         * Scroll dimension (`X` - `rgCol` or `Y` - `rgRow`)
         */
        this.dimension = 'rgRow';
        this.scrollSize = 0;
    }
    async setScroll(e) {
        var _a;
        if (this.dimension !== e.dimension) {
            return;
        }
        this.localScrollTimer.latestScrollUpdate(e.dimension);
        (_a = this.localScrollService) === null || _a === void 0 ? void 0 : _a.setScroll(e);
        if (e.coordinate) {
            this.autohideScrollPlugin.checkScroll({
                scrollSize: this.scrollSize,
                contentSize: this.realSize,
                virtualSize: this.virtualSize,
            });
        }
    }
    /**
     * Update if `delta` exists in case we don't know current position or if it's external change
     */
    async changeScroll(e) {
        if (e.delta) {
            const scrollProperty = e.dimension === 'rgRow' ? 'scrollTop' : 'scrollLeft';
            const currentPhysicalCoordinate = this.element[scrollProperty];
            return this.localScrollService.setScrollByDelta(e, currentPhysicalCoordinate);
        }
        return e;
    }
    connectedCallback() {
        this.autohideScrollPlugin = new AutohideScrollPlugin(this.element);
        this.localScrollTimer = new LocalScrollTimer('ontouchstart' in document.documentElement ? 0 : 10);
        this.localScrollService = new LocalScrollService({
            runScroll: e => this.scrollVirtual.emit(e),
            applyScroll: e => {
                this.localScrollTimer.setCoordinate(e);
                const type = e.dimension === 'rgRow' ? 'scrollTop' : 'scrollLeft';
                // this will trigger on scroll event
                this.element[type] = e.coordinate;
            },
        });
    }
    disconnectedCallback() {
        this.autohideScrollPlugin.clear();
    }
    componentWillLoad() {
        this.scrollSize = getScrollbarSize(document);
    }
    componentDidRender() {
        let scrollSize = 0;
        if (this.dimension === 'rgRow') {
            scrollSize = this.element.scrollHeight > this.element.clientHeight ? this.scrollSize : 0;
            this.element.style.minWidth = `${scrollSize}px`;
        }
        else {
            scrollSize = this.element.scrollWidth > this.element.clientWidth ? this.scrollSize : 0;
            this.element.style.minHeight = `${scrollSize}px`;
        }
        this.autohideScrollPlugin.setScrollSize(scrollSize);
        this.localScrollService.setParams({
            contentSize: this.realSize,
            clientSize: this.dimension === 'rgRow' ? this.element.clientHeight : this.element.clientWidth,
            virtualSize: this.clientSize,
        }, this.dimension);
    }
    onScroll(e) {
        if (!(e.target instanceof Element)) {
            return;
        }
        const target = e.target;
        let type = 'scrollLeft';
        if (this.dimension === 'rgRow') {
            type = 'scrollTop';
        }
        const setScroll = () => {
            var _a;
            (_a = this.localScrollService) === null || _a === void 0 ? void 0 : _a.scroll(target[type] || 0, this.dimension);
        };
        // apply after throttling
        if (this.localScrollTimer.isReady(this.dimension, target[type])) {
            setScroll();
        }
        else {
            this.localScrollTimer.throttleLastScrollUpdate(this.dimension, target[type] || 0, () => setScroll());
        }
    }
    render() {
        const size = getContentSize(this.realSize, this.dimension === 'rgRow' ? this.element.clientHeight : this.element.clientWidth, this.clientSize);
        return (h(Host, { key: '7213817ef941eee4050b714266598ec0c2961ee9', onScroll: (e) => this.onScroll(e) }, h("div", { key: '501da49c63253ab943172494b9dbf5399be56cee', style: {
                [this.dimension === 'rgRow' ? 'height' : 'width']: `${size}px`,
            } })));
    }
    static get is() { return "revogr-scroll-virtual"; }
    static get originalStyleUrls() {
        return {
            "$": ["revogr-scroll-style.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["revogr-scroll-style.css"]
        };
    }
    static get properties() {
        return {
            "dimension": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "DimensionType",
                    "resolved": "\"rgCol\" | \"rgRow\"",
                    "references": {
                        "DimensionType": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionType",
                            "referenceLocation": "DimensionType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Scroll dimension (`X` - `rgCol` or `Y` - `rgRow`)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "dimension",
                "defaultValue": "'rgRow'"
            },
            "realSize": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Dimensions"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "real-size"
            },
            "virtualSize": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Virtual size"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "virtual-size"
            },
            "clientSize": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Client size"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "client-size"
            }
        };
    }
    static get events() {
        return [{
                "method": "scrollVirtual",
                "name": "scrollvirtual",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Scroll event"
                },
                "complexType": {
                    "original": "ViewPortScrollEvent",
                    "resolved": "D",
                    "references": {
                        "ViewPortScrollEvent": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::ViewPortScrollEvent",
                            "referenceLocation": "ViewPortScrollEvent"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "setScroll": {
                "complexType": {
                    "signature": "(e: ViewPortScrollEvent) => Promise<void>",
                    "parameters": [{
                            "name": "e",
                            "type": "{ dimension: DimensionType; coordinate: number; delta?: number | undefined; outside?: boolean | undefined; }",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "ViewPortScrollEvent": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::ViewPortScrollEvent",
                            "referenceLocation": "ViewPortScrollEvent"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "changeScroll": {
                "complexType": {
                    "signature": "(e: ViewPortScrollEvent) => Promise<ViewPortScrollEvent>",
                    "parameters": [{
                            "name": "e",
                            "type": "{ dimension: DimensionType; coordinate: number; delta?: number | undefined; outside?: boolean | undefined; }",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "ViewPortScrollEvent": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::ViewPortScrollEvent",
                            "referenceLocation": "ViewPortScrollEvent"
                        }
                    },
                    "return": "Promise<ViewPortScrollEvent>"
                },
                "docs": {
                    "text": "Update if `delta` exists in case we don't know current position or if it's external change",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "element"; }
}
