import * as i0 from '@angular/core';
import { Directive, Optional, Inject, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PROP_STRING, PROP_NUMBER, register, StylableComponent, APPLY_STYLES_TYPE, styler, getKeyboardFocusableElements, provideAsWidgetRef, WmComponentsModule } from '@wm/components/base';
import * as i3 from '@angular/router';
import { NavigationStart } from '@angular/router';
import * as i1 from '@wm/core';
import { $appDigest, addClass, switchClass, isMobile, removeClass, toggleClass } from '@wm/core';
import * as i2 from '@wm/components/page';
import { SwipeAnimation } from '@swipey';

const registerProps = () => {
    register('wm-left-panel', new Map([
        ['animation', { value: 'slide-in', ...PROP_STRING }],
        ['class', PROP_STRING],
        ['columnwidth', { value: 3, ...PROP_NUMBER }],
        ['content', PROP_STRING],
        ['gestures', { value: 'on', ...PROP_STRING }],
        ['name', PROP_STRING],
        ['xscolumnwidth', { value: 10, ...PROP_NUMBER }],
        ['hint', PROP_STRING],
        ['arialabel', PROP_STRING]
    ]));
};

class LeftPanelAnimator extends SwipeAnimation {
    constructor(leftPanel) {
        super();
        this.leftPanel = leftPanel;
        this.init(this.leftPanel.$ele, this.leftPanel.$page);
    }
    bounds(e, length) {
        let offset = 0;
        this.setGesturesEnabled(this.leftPanel.isGesturesEnabled());
        if (!this._width) {
            this._pageContainerWidth = this.leftPanel.$page.width();
            this._leftPanelWidth = this.leftPanel.$ele.width();
            this._maxX = this._leftPanelWidth / this._pageContainerWidth * 100;
            this._width = this.leftPanel.animation === AnimationType.SLIDE_IN ? this._pageContainerWidth : this._leftPanelWidth;
        }
        this._expanded = this.leftPanel.expanded;
        if (this._expanded) {
            return {
                'center': this._leftPanelWidth,
                'lower': -(this._leftPanelWidth - offset)
            };
        }
        if (this.leftPanel.app.isTabletApplicationType) {
            offset = 53.32;
        }
        if (e && (e.pageX || (e.touches && e.touches[0].pageX)) > offset + 100) {
            return {
                strict: true
            };
        }
        return {
            'center': 0,
            'upper': this._leftPanelWidth - offset
        };
    }
    context() {
        return {
            'w': this._width,
            'pageW': this._pageContainerWidth,
            'leftW': this._leftPanelWidth,
            'maxX': this._maxX,
            'limit': (min, v, max) => {
                if (v < min) {
                    return min;
                }
                if (v > max) {
                    return max;
                }
                return v;
            }
        };
    }
    animation() {
        this._$animatedElements = this.leftPanel.$ele;
        if (this.leftPanel.animation === AnimationType.SLIDE_IN) {
            this._$animatedElements = this._$animatedElements.add(this.leftPanel.$page);
            if (this.leftPanel.app.isTabletApplicationType) {
                return [
                    {
                        'target': this.leftPanel.$ele,
                        'css': {
                            'transform': 'translate3d(${{ limit(-100, -($d * 100 / leftW), 0) + \'%\' }}, 0, 0)'
                        }
                    },
                    {
                        'target': this.leftPanel.$page,
                        'css': {
                            'transform': 'translate3d(${{ (($d) * 100 / pageW) + \'%\' }}, 0, 0)',
                            'width': '${{ (pageW - $d) + \'px\' }}',
                            'z-index': 101
                        }
                    }
                ];
            }
            return [
                {
                    'target': this.leftPanel.$ele,
                    'css': {
                        'transform': 'translate3d(-100%, 0, 0)',
                        'opacity': 1,
                        'z-index': 101
                    }
                },
                {
                    'target': this.leftPanel.$page,
                    'css': {
                        'transform': 'translate3d(${{ limit( 0, ((($D + $d) * 100 / w)), maxX ) + \'%\' }}, 0, 0)',
                        'opacity': 1,
                        'z-index': 101
                    }
                }
            ];
        }
        else {
            return {
                'transform': 'translate3d(${{ limit( -100, ((($D + $d) * 100 / w) - 100), 0 ) + \'%\'}}, 0, 0)',
                'opacity': 1,
                'z-index': 101
            };
        }
    }
    onLower() {
        this._expanded = false;
        this.leftPanel.collapse();
        this.resetTransition();
        $appDigest();
    }
    onUpper() {
        this._expanded = true;
        this.leftPanel.expand();
        this.resetTransition();
        $appDigest();
    }
    resetTransition() {
        if (this._$animatedElements) {
            /*
             * This timeout is for preventing UI flicker at the end of animation.
             */
            setTimeout(() => {
                this._$animatedElements.css({
                    'transform': '',
                    'opacity': '',
                    'z-index': '',
                    'width': ''
                });
            }, 100);
        }
    }
}

const DEFAULT_CLS = 'app-left-panel left-panel-collapsed';
const WIDGET_CONFIG = {
    widgetType: 'wm-left-panel',
    hostClass: DEFAULT_CLS
};
var AnimationType;
(function (AnimationType) {
    AnimationType["SLIDE_IN"] = "slide-in";
    AnimationType["SLIDE_OVER"] = "slide-over";
})(AnimationType || (AnimationType = {}));
class LeftPanelDirective extends StylableComponent {
    static { this.initializeProps = registerProps(); }
    //If "spa" attribute is set LayoutDirective will present and PageDirective is undefined else PageDirective will present and LayoutDirective is undefined
    constructor(app, page, layout, inj, router, explicitContext) {
        super(inj, WIDGET_CONFIG, explicitContext);
        this.app = app;
        this.page = page;
        this.layout = layout;
        styler(this.nativeElement, this, APPLY_STYLES_TYPE.CONTAINER);
        this.$ele = this.$element;
        this.$page = this.getAttr('spa') && layout && layout.$element || page && page.$element;
        addClass(this.$page[0], 'left-panel-collapsed-container');
        if (this.columnwidth) {
            this.setLeftPanelWidth(['md', 'sm'], this.columnwidth);
        }
        if (this.app.isTabletApplicationType) {
            addClass(this.nativeElement, 'wm-tablet-app-left-panel');
        }
        const onRouteChange = router.events.subscribe(e => {
            if (e instanceof NavigationStart) {
                this.collapse();
            }
        });
        this.registerDestroyListener(() => onRouteChange.unsubscribe());
    }
    collapse() {
        addClass(this.nativeElement, 'swipee-transition');
        switchClass(this.nativeElement, 'left-panel-collapsed', 'left-panel-expanded');
        if (this.expanded) {
            setTimeout(() => {
                const leftNavButton = $('.app-header-action');
                leftNavButton.attr('aria-expanded', 'false');
                leftNavButton.focus();
            }, 50);
        }
        if (isMobile()) {
            addClass(this.nativeElement, 'hidden');
        }
        this.expanded = false;
        switchClass(this.$page[0], 'left-panel-collapsed-container', 'left-panel-expanded-container');
        if (this.animation === AnimationType.SLIDE_IN) {
            this.setPageWidthAndPosition(['md', 'sm'], null, this.columnwidth);
            this.setPageWidthAndPosition(['xs'], null, this.xscolumnwidth);
        }
        if (this._destroyCollapseActionListener) {
            this._destroyCollapseActionListener();
        }
        (this.getAttr("spa") && this.layout || this.page).notify('wmLeftPanel:collapse');
    }
    expand() {
        removeClass(this.nativeElement, 'hidden');
        removeClass(this.nativeElement, 'swipee-transition');
        switchClass(this.nativeElement, 'left-panel-expanded', 'left-panel-collapsed');
        this.expanded = true;
        if (!(this.app.isTabletApplicationType && this.animation === AnimationType.SLIDE_IN)) {
            this._destroyCollapseActionListener = this.listenForCollapseAction();
        }
        switchClass(this.$page[0], 'left-panel-expanded-container', 'left-panel-collapsed-container');
        if (this.animation === AnimationType.SLIDE_IN) {
            this.setPageWidthAndPosition(['md', 'sm'], this.columnwidth);
            this.setPageWidthAndPosition(['xs'], this.xscolumnwidth);
        }
        (this.getAttr("spa") && this.layout || this.page).notify('wmLeftPanel:expand');
        $('.app-header-action').attr('aria-expanded', `${this.expanded}`);
        const focusableElements = getKeyboardFocusableElements(this.nativeElement);
        const firstFocusableElement = focusableElements[0];
        const lastFocusableElement = focusableElements[focusableElements.length - 1];
        setTimeout(() => {
            $(firstFocusableElement).focus();
        }, 50);
        $(firstFocusableElement).on('keydown', (event) => {
            if (event.shiftKey && event.key === 'Tab') {
                this.collapse();
            }
        });
        $(lastFocusableElement).on('keydown', (event) => {
            if (event.key === 'Tab') {
                this.collapse();
            }
        });
        this.$element.on('keydown', (event) => {
            if (event.key === 'Escape') {
                this.collapse();
            }
        });
    }
    isGesturesEnabled() {
        return this.gestures === 'on';
    }
    isVisible() {
        return this.expanded;
    }
    onPropertyChange(key, nv, ov) {
        switch (key) {
            case 'animation':
                if (nv === AnimationType.SLIDE_IN) {
                    removeClass(this.$page[0], 'slide-over-left-panel-container');
                    addClass(this.$page[0], 'slide-in-left-panel-container');
                    this.setPageWidthAndPosition(['md', 'sm'], this.columnwidth);
                    this.setPageWidthAndPosition(['xs'], this.xscolumnwidth);
                }
                else if (nv === AnimationType.SLIDE_OVER) {
                    removeClass(this.$page[0], 'slide-in-left-panel-container');
                    addClass(this.$page[0], 'slide-over-left-panel-container');
                }
                this._leftPanelAnimator = new LeftPanelAnimator(this);
                switchClass(this.nativeElement, nv, ov);
                break;
            case 'columnwidth':
                this.setLeftPanelWidth(['md', 'sm'], nv, ov);
                if (this.animation === AnimationType.SLIDE_IN) {
                    this.setPageWidthAndPosition(['md', 'sm'], nv, ov);
                }
                break;
            case 'expanded':
                toggleClass(this.nativeElement, 'left-panel-expanded', nv);
                toggleClass(this.nativeElement, 'left-panel-collapsed', !nv);
                break;
            case 'xscolumnwidth':
                this.setLeftPanelWidth(['xs'], nv, ov);
                if (this.animation === AnimationType.SLIDE_IN) {
                    this.setPageWidthAndPosition(['xs'], nv, ov);
                }
                break;
            default:
                super.onPropertyChange(key, nv, ov);
        }
    }
    toggle() {
        if (this.app.isTabletApplicationType) {
            setTimeout(() => {
                this.expanded ? this.collapse() : this.expand();
            }, 50);
        }
        else {
            this.$ele.swipeAnimation(this.expanded ? 'gotoLower' : 'gotoUpper');
        }
    }
    listenForCollapseAction() {
        const eventName = 'click.leftNavToggle';
        let skipEvent = false;
        this.$ele.on(eventName, () => {
            skipEvent = true;
        });
        this.$page.on(eventName, () => {
            if (!skipEvent) {
                this.toggle();
            }
            skipEvent = false;
        });
        return () => {
            this.$ele.off(eventName);
            this.$page.off(eventName);
        };
    }
    setLeftPanelWidth(devices, newVal, oldVal) {
        devices.forEach(device => {
            if (newVal) {
                addClass(this.nativeElement, `col-${device}-${newVal}`);
            }
            if (oldVal) {
                removeClass(this.nativeElement, `col-${device}-${oldVal}`);
            }
        });
    }
    setPageWidthAndPosition(devices, newVal, oldVal) {
        devices.forEach(device => {
            if (newVal) {
                addClass(this.$page[0], `left-panel-container-${device}-${12 - newVal}`);
            }
            if (oldVal) {
                removeClass(this.$page[0], `left-panel-container-${device}-${12 - oldVal}`);
            }
        });
    }
    static { this.ɵfac = function LeftPanelDirective_Factory(t) { return new (t || LeftPanelDirective)(i0.ɵɵdirectiveInject(i1.App), i0.ɵɵdirectiveInject(i2.PageDirective, 8), i0.ɵɵdirectiveInject(i2.LayoutDirective, 8), i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i3.Router), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: LeftPanelDirective, selectors: [["", "wmLeftPanel", ""]], exportAs: ["wmLeftPanel"], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(LeftPanelDirective)
            ]), i0.ɵɵInheritDefinitionFeature] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LeftPanelDirective, [{
        type: Directive,
        args: [{
                selector: '[wmLeftPanel]',
                providers: [
                    provideAsWidgetRef(LeftPanelDirective)
                ],
                exportAs: 'wmLeftPanel'
            }]
    }], () => [{ type: i1.App }, { type: i2.PageDirective, decorators: [{
                type: Optional
            }] }, { type: i2.LayoutDirective, decorators: [{
                type: Optional
            }] }, { type: i0.Injector }, { type: i3.Router }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], null); })();

const components = [
    LeftPanelDirective
];
class LeftPanelModule {
    static { this.ɵfac = function LeftPanelModule_Factory(t) { return new (t || LeftPanelModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: LeftPanelModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
            WmComponentsModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LeftPanelModule, [{
        type: NgModule,
        args: [{
                imports: [
                    CommonModule,
                    WmComponentsModule
                ],
                declarations: [...components],
                exports: [...components]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(LeftPanelModule, { declarations: [LeftPanelDirective], imports: [CommonModule,
        WmComponentsModule], exports: [LeftPanelDirective] }); })();

/**
 * Generated bundle index. Do not edit.
 */

export { AnimationType, LeftPanelDirective, LeftPanelModule };
//# sourceMappingURL=index.mjs.map
