import { __decorate, __metadata } from "tslib";
import { Host, h, } from "@stencil/core";
import { BEM } from "../../utils/bem";
import { balBreakpoints } from "../../utils/breakpoints";
import { ListenToBreakpoints } from "../../utils/breakpoints/breakpoints.decorator";
import { ListenToConfig, defaultConfig } from "../../utils/config";
import { stopEventBubbling } from "../../utils/form-input";
import { ListenToMutation } from "../../utils/mutation";
import { ListenToResize } from "../../utils/resize";
import { ListenToSwipe } from "../../utils/swipe";
import { SwiperUtil } from "../../utils/swiper";
import { ListenToVisibility } from "../../utils/visibility";
import { TabControl } from "./controls/tab-control";
export class Carousel {
    constructor() {
        this.swiper = new SwiperUtil();
        this.swiperIsLastSlideVisible = false;
        this.hasAnimated = false;
        this.isMobile = balBreakpoints.isMobile;
        this.language = defaultConfig.language;
        /**
         * PUBLIC PROPERTY API
         * ------------------------------------------------------
         */
        /**
         * Defines the active slide index.
         */
        this.value = 0;
        /**
         * When how many slides are moved when going forward or backward.
         */
        this.steps = 1;
        /**
         * Defines how many slides are visible in the container for the user.
         * `auto` will use the size of the actual item content
         */
        this.itemsPerView = 1;
        /**
         * Defines the layout of the navigation controls.
         */
        this.controls = 'none';
        /**
         * Defines the layout of the navigation controls.
         */
        this.space = 'none';
        /**
         * @deprecated
         * Defines the role of the carousel.
         */
        this.htmlRole = 'list';
        /**
         * If `true` items move under the controls, instead of having a gap
         */
        this.controlsOverflow = false;
        /**
         * If `true` the carousel can be used on dark background
         */
        this.inverted = false;
        /**
         * If `true` the carousel uses the full height
         */
        this.fullHeight = false;
        /**
         * Defines the image aspect ratio.
         * Should be combined with the interface `product`
         */
        this.aspectRatio = '16by9';
        /**
         * Defines special looks.
         */
        this.interface = '';
        /**
         * If `true` the controls will be sticky to the top.
         */
        this.controlsSticky = false;
        /**
         * If `true` vertical scrolling on mobile is enabled.
         */
        this.scrollY = true;
        /**
         * If `true` a light border is shown at the bottom.
         */
        this.border = false;
        this.mutationObserverActive = true;
    }
    onValueChange() {
        this.swiper.index = this.value;
    }
    onStepsChange() {
        this.swiper.steps = this.steps;
    }
    onItemsPerViewChange() {
        this.swiper.itemsPerView = this.itemsPerView;
    }
    onControlsChange() {
        this.swiper.controls = this.controls;
    }
    onSpaceChange() {
        this.swiper.gapSpace = this.space;
    }
    onInterFaceChange() {
        this.swiper.gapSpace = this.interface === 'product' ? 'normal' : this.space;
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    connectedCallback() {
        this.swiper.connectedCallback(this);
        this.onControlsChange();
        this.onItemsPerViewChange();
        this.onStepsChange();
        this.onSpaceChange();
        this.onInterFaceChange();
        this.onValueChange();
    }
    disconnectedCallback() {
        this.swiper.disconnectedCallback();
    }
    /**
     * LISTENERS
     * ------------------------------------------------------
     */
    async blockVerticalScrolling(ev) {
        var _a;
        if (!this.scrollY && ((_a = this.el) === null || _a === void 0 ? void 0 : _a.contains(ev.target))) {
            stopEventBubbling(ev);
        }
    }
    mutationListener() {
        this.swiper.notifyChange();
    }
    visibilityListener() {
        this.swiper.notifyChange();
    }
    swipeListener({ left, right }) {
        if (left) {
            this.next();
        }
        else if (right) {
            this.previous();
        }
    }
    breakpointListener(breakpoints) {
        this.isMobile = breakpoints.mobile;
        this.swiper.notifyChange();
    }
    resizeListener() {
        this.swiper.notifyChange();
    }
    /**
     * @internal define config for the component
     */
    async configChanged(state) {
        this.language = state.language;
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    async previous(steps = this.steps) {
        this.swiper.previous(steps);
    }
    async next(steps = this.steps) {
        this.swiper.next(steps);
    }
    /**
     * @internal
     */
    async getContainerId() {
        return this.swiper.containerId;
    }
    /**
     * GETTERS
     * ------------------------------------------------------
     */
    swiperGetAllChildrenElements() {
        return Array.from(this.el.querySelectorAll('bal-carousel-item'));
    }
    /**
     * EVENT HANDLERS
     * ------------------------------------------------------
     */
    swiperOnChange(index) {
        this.value = index;
        this.balChange.emit(index);
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        const block = BEM.block('carousel');
        const inner = block.element('inner');
        const container = inner.element('container');
        return (h(Host, { key: '561107c8e3c5eb7a80b3e2a8b113ed13f2fdfb5d', class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.swiper.cssSwiper()), block.class()), block.modifier(this.interface).class(this.interface !== '')), block.modifier(`full-height`).class(this.fullHeight)), block.modifier('controls-sticky').class(this.controlsSticky)), block.modifier(`controls-tabs`).class(this.controls === 'tabs')) }, this.controls === 'tabs' ? (h(TabControl, { value: this.value, items: this.swiper.getAllControlItems(), containerId: this.swiper.containerId, onControlChange: item => this.swiper.onControlChange(item.value) })) : (''), h("div", { key: '6adb9641efe5f488a940ffac297bcc7b3932c92a', class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.swiper.cssInnerSwiper()), inner.class()), inner.modifier(`is-${this.aspectRatio}`).class()), inner.modifier(`inverted`).class(this.inverted)), inner.modifier(`full-height`).class(this.fullHeight)), ref: el => (this.swiper.innerEl = el) }, h("div", { key: 'fb4083afd4a967761c25200e8630f171b02a6c2d', id: this.swiper.containerId, role: this.controls === 'tabs' ? '' : 'list', class: Object.assign(Object.assign(Object.assign(Object.assign({}, this.swiper.cssSwiperContainer()), container.class()), container.modifier(`border`).class(this.border)), container.modifier(`is-${this.aspectRatio}`).class()), ref: el => (this.swiper.containerEl = el) }, h("slot", { key: 'c46d996cc3904bcdc38951f155e3a49f73f284f8' }), this.border ? (h("div", { id: `${this.swiper.id}-border`, "aria-hidden": "true", class: Object.assign(Object.assign({}, container.element('border').class()), container.element('border').modifier('inverted').class(this.inverted)), ref: el => (this.swiper.borderEl = el) })) : (''))), this.swiper.renderControls()));
    }
    static get is() { return "bal-carousel"; }
    static get originalStyleUrls() {
        return {
            "$": ["bal-carousel.sass"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bal-carousel.css"]
        };
    }
    static get properties() {
        return {
            "value": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the active slide index."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value",
                "defaultValue": "0"
            },
            "steps": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When how many slides are moved when going forward or backward."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "steps",
                "defaultValue": "1"
            },
            "itemsPerView": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "'auto' | 1 | 2 | 3 | 4",
                    "resolved": "\"auto\" | 1 | 2 | 3 | 4",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines how many slides are visible in the container for the user.\n`auto` will use the size of the actual item content"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "items-per-view",
                "defaultValue": "1"
            },
            "controls": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'small' | 'large' | 'dots' | 'tabs' | 'none'",
                    "resolved": "\"dots\" | \"large\" | \"none\" | \"small\" | \"tabs\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the layout of the navigation controls."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "controls",
                "defaultValue": "'none'"
            },
            "space": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'normal' | 'medium' | 'none'",
                    "resolved": "\"medium\" | \"none\" | \"normal\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the layout of the navigation controls."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "space",
                "defaultValue": "'none'"
            },
            "htmlRole": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'tablist' | 'list' | ''",
                    "resolved": "\"\" | \"list\" | \"tablist\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "deprecated",
                            "text": "Defines the role of the carousel."
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "html-role",
                "defaultValue": "'list'"
            },
            "controlsOverflow": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` items move under the controls, instead of having a gap"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "controls-overflow",
                "defaultValue": "false"
            },
            "inverted": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` the carousel can be used on dark background"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "inverted",
                "defaultValue": "false"
            },
            "fullHeight": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` the carousel uses the full height"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "full-height",
                "defaultValue": "false"
            },
            "aspectRatio": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'1by1' | '3by2' | '4by3' | '16by9'",
                    "resolved": "\"16by9\" | \"1by1\" | \"3by2\" | \"4by3\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines the image aspect ratio.\nShould be combined with the interface `product`"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "aspect-ratio",
                "defaultValue": "'16by9'"
            },
            "interface": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'card' | 'image' | 'product' | ''",
                    "resolved": "\"\" | \"card\" | \"image\" | \"product\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines special looks."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "interface",
                "defaultValue": "''"
            },
            "controlsSticky": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` the controls will be sticky to the top."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "controls-sticky",
                "defaultValue": "false"
            },
            "scrollY": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` vertical scrolling on mobile is enabled."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "scroll-y",
                "defaultValue": "true"
            },
            "border": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true` a light border is shown at the bottom."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "border",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "hasAnimated": {},
            "isMobile": {},
            "language": {}
        };
    }
    static get events() {
        return [{
                "method": "balChange",
                "name": "balChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when a option got selected."
                },
                "complexType": {
                    "original": "BalEvents.BalCarouselChangeDetail",
                    "resolved": "number",
                    "references": {
                        "BalEvents": {
                            "location": "global",
                            "id": "global::BalEvents"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "configChanged": {
                "complexType": {
                    "signature": "(state: BalConfigState) => Promise<void>",
                    "parameters": [{
                            "name": "state",
                            "type": "BalConfigState",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "BalConfigState": {
                            "location": "import",
                            "path": "../../utils/config",
                            "id": "src/utils/config/index.ts::BalConfigState"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "define config for the component"
                        }]
                }
            },
            "previous": {
                "complexType": {
                    "signature": "(steps?: number) => Promise<void>",
                    "parameters": [{
                            "name": "steps",
                            "type": "number",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "PUBLIC METHODS\n------------------------------------------------------",
                    "tags": []
                }
            },
            "next": {
                "complexType": {
                    "signature": "(steps?: number) => Promise<void>",
                    "parameters": [{
                            "name": "steps",
                            "type": "number",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "getContainerId": {
                "complexType": {
                    "signature": "() => Promise<string>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<string>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "onValueChange"
            }, {
                "propName": "steps",
                "methodName": "onStepsChange"
            }, {
                "propName": "itemsPerView",
                "methodName": "onItemsPerViewChange"
            }, {
                "propName": "controls",
                "methodName": "onControlsChange"
            }, {
                "propName": "space",
                "methodName": "onSpaceChange"
            }, {
                "propName": "interface",
                "methodName": "onInterFaceChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "touchmove",
                "method": "blockVerticalScrolling",
                "target": "window",
                "capture": false,
                "passive": false
            }];
    }
}
__decorate([
    ListenToMutation({ tags: ['bal-carousel-item'], characterData: false }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], Carousel.prototype, "mutationListener", null);
__decorate([
    ListenToVisibility(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], Carousel.prototype, "visibilityListener", null);
__decorate([
    ListenToSwipe(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], Carousel.prototype, "swipeListener", null);
__decorate([
    ListenToBreakpoints(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], Carousel.prototype, "breakpointListener", null);
__decorate([
    ListenToResize(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], Carousel.prototype, "resizeListener", null);
__decorate([
    ListenToConfig(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Carousel.prototype, "configChanged", null);
