/**
 * DevExtreme (cjs/__internal/ui/drawer/m_drawer.js)
 * Version: 24.1.7-build-24272-1937
 * Build date: Sat Sep 28 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.default = void 0;
var _fx = _interopRequireDefault(require("../../../animation/fx"));
var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator"));
var _element = require("../../../core/element");
var _renderer = _interopRequireDefault(require("../../../core/renderer"));
var _empty_template = require("../../../core/templates/empty_template");
var _deferred = require("../../../core/utils/deferred");
var _extend = require("../../../core/utils/extend");
var _position = require("../../../core/utils/position");
var _type = require("../../../core/utils/type");
var _window = require("../../../core/utils/window");
var _click = require("../../../events/click");
var _events_engine = _interopRequireDefault(require("../../../events/core/events_engine"));
var _visibility_change = require("../../../events/visibility_change");
var _ui = _interopRequireDefault(require("../../../ui/widget/ui.widget"));
var _m_drawer = require("./m_drawer.animation");
var _m_drawerRenderingStrategy = _interopRequireDefault(require("./m_drawer.rendering.strategy.overlap"));
var _m_drawerRenderingStrategy2 = _interopRequireDefault(require("./m_drawer.rendering.strategy.push"));
var _m_drawerRenderingStrategy3 = _interopRequireDefault(require("./m_drawer.rendering.strategy.shrink"));

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}
const DRAWER_CLASS = "dx-drawer";
const DRAWER_WRAPPER_CLASS = "dx-drawer-wrapper";
const DRAWER_PANEL_CONTENT_CLASS = "dx-drawer-panel-content";
const DRAWER_PANEL_CONTENT_HIDDEN_CLASS = "dx-drawer-panel-content-hidden";
const DRAWER_VIEW_CONTENT_CLASS = "dx-drawer-content";
const DRAWER_SHADER_CLASS = "dx-drawer-shader";
const INVISIBLE_STATE_CLASS = "dx-state-invisible";
const OPENED_STATE_CLASS = "dx-drawer-opened";
const ANONYMOUS_TEMPLATE_NAME = "content";
const PANEL_TEMPLATE_NAME = "panel";
const Drawer = _ui.default.inherit({
    _getDefaultOptions() {
        return (0, _extend.extend)(this.callBase(), {
            position: "left",
            opened: false,
            minSize: null,
            maxSize: null,
            shading: false,
            template: "panel",
            openedStateMode: "shrink",
            revealMode: "slide",
            animationEnabled: true,
            animationDuration: 400,
            closeOnOutsideClick: false,
            contentTemplate: "content"
        })
    },
    _init() {
        this.callBase();
        this._initStrategy();
        this.$element().addClass("dx-drawer");
        this._whenAnimationCompleted = void 0;
        this._whenPanelContentRendered = void 0;
        this._whenPanelContentRefreshed = void 0;
        this._$wrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-wrapper");
        this._$viewContentWrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-content");
        this._$wrapper.append(this._$viewContentWrapper);
        this.$element().append(this._$wrapper)
    },
    _initStrategy() {
        switch (this.option("openedStateMode")) {
            case "push":
            default:
                this._strategy = new _m_drawerRenderingStrategy2.default(this);
                break;
            case "shrink":
                this._strategy = new _m_drawerRenderingStrategy3.default(this);
                break;
            case "overlap":
                this._strategy = new _m_drawerRenderingStrategy.default(this)
        }
    },
    _getAnonymousTemplateName: () => "content",
    _initTemplates() {
        const defaultTemplates = {};
        defaultTemplates.panel = new _empty_template.EmptyTemplate;
        defaultTemplates.content = new _empty_template.EmptyTemplate;
        this._templateManager.addDefaultTemplates(defaultTemplates);
        this.callBase()
    },
    _viewContentWrapperClickHandler(e) {
        let closeOnOutsideClick = this.option("closeOnOutsideClick");
        if ((0, _type.isFunction)(closeOnOutsideClick)) {
            closeOnOutsideClick = closeOnOutsideClick(e)
        }
        if (closeOnOutsideClick && this.option("opened")) {
            this.stopAnimations();
            if (this.option("shading")) {
                e.preventDefault()
            }
            this.hide()
        }
    },
    _initMarkup() {
        this.callBase();
        this._toggleOpenedStateClass(this.option("opened"));
        this._renderPanelContentWrapper();
        this._refreshOpenedStateModeClass();
        this._refreshRevealModeClass();
        this._renderShader();
        this._refreshPositionClass();
        this._whenPanelContentRendered = (0, _deferred.Deferred)();
        this._strategy.renderPanelContent(this._whenPanelContentRendered);
        this._strategy.onPanelContentRendered();
        this._renderViewContent();
        _events_engine.default.off(this._$viewContentWrapper, _click.name);
        _events_engine.default.on(this._$viewContentWrapper, _click.name, this._viewContentWrapperClickHandler.bind(this));
        this._refreshWrapperChildrenOrder()
    },
    _render() {
        this._initMinMaxSize();
        this.callBase();
        this._whenPanelContentRendered.always((() => {
            this._initMinMaxSize();
            this._strategy.refreshPanelElementSize("slide" === this.option("revealMode"));
            this._renderPosition(this.option("opened"), true);
            this._removePanelManualPosition()
        }))
    },
    _removePanelManualPosition() {
        if (this._$panelContentWrapper.attr("manualposition")) {
            this._$panelContentWrapper.removeAttr("manualPosition");
            this._$panelContentWrapper.css({
                position: "",
                top: "",
                left: "",
                right: "",
                bottom: ""
            })
        }
    },
    _togglePanelContentHiddenClass() {
        const callback = () => {
            const {
                minSize: minSize,
                opened: opened
            } = this.option();
            const shouldBeSet = minSize ? false : !opened;
            this._$panelContentWrapper.toggleClass("dx-drawer-panel-content-hidden", shouldBeSet)
        };
        if (this._whenAnimationCompleted && !this.option("opened")) {
            (0, _deferred.when)(this._whenAnimationCompleted).done(callback)
        } else {
            callback()
        }
    },
    _renderPanelContentWrapper() {
        const {
            openedStateMode: openedStateMode,
            opened: opened,
            minSize: minSize
        } = this.option();
        this._$panelContentWrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-panel-content");
        this._togglePanelContentHiddenClass();
        const position = this.calcTargetPosition();
        if ("push" === openedStateMode && ["top", "bottom"].includes(position)) {
            this._$panelContentWrapper.addClass("dx-drawer-panel-content-push-top-or-bottom")
        }
        if ("overlap" !== openedStateMode && !opened && !minSize) {
            this._$panelContentWrapper.attr("manualposition", true);
            this._$panelContentWrapper.css({
                position: "absolute",
                top: "-10000px",
                left: "-10000px",
                right: "auto",
                bottom: "auto"
            })
        }
        this._$wrapper.append(this._$panelContentWrapper)
    },
    _refreshOpenedStateModeClass(prevOpenedStateMode) {
        if (prevOpenedStateMode) {
            this.$element().removeClass(`dx-drawer-${prevOpenedStateMode}`)
        }
        this.$element().addClass(`dx-drawer-${this.option("openedStateMode")}`)
    },
    _refreshPositionClass(prevPosition) {
        if (prevPosition) {
            this.$element().removeClass(`dx-drawer-${prevPosition}`)
        }
        this.$element().addClass(`dx-drawer-${this.calcTargetPosition()}`)
    },
    _refreshWrapperChildrenOrder() {
        const position = this.calcTargetPosition();
        if (this._strategy.isViewContentFirst(position, this.option("rtlEnabled"))) {
            this._$wrapper.prepend(this._$viewContentWrapper)
        } else {
            this._$wrapper.prepend(this._$panelContentWrapper)
        }
    },
    _refreshRevealModeClass(prevRevealMode) {
        if (prevRevealMode) {
            this.$element().removeClass(`dx-drawer-${prevRevealMode}`)
        }
        this.$element().addClass(`dx-drawer-${this.option("revealMode")}`)
    },
    _renderViewContent() {
        const contentTemplateOption = this.option("contentTemplate");
        const contentTemplate = this._getTemplate(contentTemplateOption);
        if (contentTemplate) {
            const $viewTemplate = contentTemplate.render({
                container: this.viewContent(),
                noModel: true,
                transclude: this._templateManager.anonymousTemplateName === contentTemplateOption
            });
            if ($viewTemplate.hasClass("ng-scope")) {
                (0, _renderer.default)(this._$viewContentWrapper).children().not(".dx-drawer-shader").replaceWith($viewTemplate)
            }
        }
    },
    _renderShader() {
        this._$shader = this._$shader || (0, _renderer.default)("<div>").addClass("dx-drawer-shader");
        this._$shader.appendTo(this.viewContent());
        this._toggleShaderVisibility(this.option("opened"))
    },
    _initSize() {
        this._initMinMaxSize()
    },
    _initMinMaxSize() {
        const realPanelSize = this.isHorizontalDirection() ? this.getRealPanelWidth() : this.getRealPanelHeight();
        this._maxSize = this.option("maxSize") || realPanelSize;
        this._minSize = this.option("minSize") || 0
    },
    calcTargetPosition() {
        const position = this.option("position");
        const rtl = this.option("rtlEnabled");
        let result = position;
        if ("before" === position) {
            result = rtl ? "right" : "left"
        } else if ("after" === position) {
            result = rtl ? "left" : "right"
        }
        return result
    },
    getOverlayTarget() {
        return this._$wrapper
    },
    getOverlay() {
        return this._overlay
    },
    getMaxSize() {
        return this._maxSize
    },
    getMinSize() {
        return this._minSize
    },
    getRealPanelWidth() {
        if ((0, _window.hasWindow)()) {
            if ((0, _type.isDefined)(this.option("templateSize"))) {
                return this.option("templateSize")
            }
            return (0, _position.getBoundingRect)(this._getPanelTemplateElement()).width
        }
        return 0
    },
    getRealPanelHeight() {
        if ((0, _window.hasWindow)()) {
            if ((0, _type.isDefined)(this.option("templateSize"))) {
                return this.option("templateSize")
            }
            return (0, _position.getBoundingRect)(this._getPanelTemplateElement()).height
        }
        return 0
    },
    _getPanelTemplateElement() {
        const $panelContent = this._strategy.getPanelContent();
        let $result = $panelContent;
        if ($panelContent.children().length) {
            $result = $panelContent.children().eq(0);
            if ($panelContent.hasClass("dx-overlay-content") && $result.hasClass("dx-template-wrapper") && $result.children().length) {
                $result = $result.children().eq(0)
            }
        }
        return $result.get(0)
    },
    getElementHeight($element) {
        const $children = $element.children();
        return $children.length ? (0, _position.getBoundingRect)($children.eq(0).get(0)).height : (0, _position.getBoundingRect)($element.get(0)).height
    },
    isHorizontalDirection() {
        const position = this.calcTargetPosition();
        return "left" === position || "right" === position
    },
    stopAnimations(jumpToEnd) {
        _fx.default.stop(this._$shader, jumpToEnd);
        _fx.default.stop((0, _renderer.default)(this.content()), jumpToEnd);
        _fx.default.stop((0, _renderer.default)(this.viewContent()), jumpToEnd);
        const overlay = this.getOverlay();
        if (overlay) {
            _fx.default.stop((0, _renderer.default)(overlay.$content()), jumpToEnd)
        }
    },
    setZIndex(zIndex) {
        this._$shader.css("zIndex", zIndex - 1);
        this._$panelContentWrapper.css("zIndex", zIndex)
    },
    resizeContent() {
        this.resizeViewContent
    },
    resizeViewContent() {
        (0, _visibility_change.triggerResizeEvent)(this.viewContent())
    },
    _isInvertedPosition() {
        const position = this.calcTargetPosition();
        return "right" === position || "bottom" === position
    },
    _renderPosition(isDrawerOpened, disableAnimation, jumpToEnd) {
        this.stopAnimations(jumpToEnd);
        if (!(0, _window.hasWindow)()) {
            return
        }(0, _renderer.default)(this.viewContent()).css("paddingLeft", 0);
        (0, _renderer.default)(this.viewContent()).css("paddingRight", 0);
        (0, _renderer.default)(this.viewContent()).css("paddingTop", 0);
        (0, _renderer.default)(this.viewContent()).css("paddingBottom", 0);
        let animationEnabled = this.option("animationEnabled");
        if (true === disableAnimation) {
            animationEnabled = false
        }
        if (isDrawerOpened) {
            this._toggleShaderVisibility(isDrawerOpened)
        }
        this._strategy.renderPosition(animationEnabled, this.option("animationDuration"))
    },
    _animationCompleteHandler() {
        this.resizeViewContent();
        if (this._whenAnimationCompleted) {
            this._whenAnimationCompleted.resolve()
        }
    },
    _getPositionCorrection() {
        return this._isInvertedPosition() ? -1 : 1
    },
    _dispose() {
        _m_drawer.animation.complete((0, _renderer.default)(this.viewContent()));
        this.callBase()
    },
    _visibilityChanged(visible) {
        if (visible) {
            this._dimensionChanged()
        }
    },
    _dimensionChanged() {
        this._initMinMaxSize();
        this._strategy.refreshPanelElementSize("slide" === this.option("revealMode"));
        this._renderPosition(this.option("opened"), true)
    },
    _toggleShaderVisibility(visible) {
        if (this.option("shading")) {
            this._$shader.toggleClass("dx-state-invisible", !visible);
            this._$shader.css("visibility", visible ? "visible" : "hidden")
        } else {
            this._$shader.toggleClass("dx-state-invisible", true)
        }
    },
    _toggleOpenedStateClass(opened) {
        this.$element().toggleClass("dx-drawer-opened", opened)
    },
    _refreshPanel() {
        (0, _renderer.default)(this.viewContent()).css("left", 0);
        (0, _renderer.default)(this.viewContent()).css("transform", "translate(0px, 0px)");
        (0, _renderer.default)(this.viewContent()).removeClass("dx-theme-background-color");
        this._removePanelContentWrapper();
        this._removeOverlay();
        this._renderPanelContentWrapper();
        this._refreshWrapperChildrenOrder();
        this._whenPanelContentRefreshed = (0, _deferred.Deferred)();
        this._strategy.renderPanelContent(this._whenPanelContentRefreshed);
        this._strategy.onPanelContentRendered();
        if ((0, _window.hasWindow)()) {
            this._whenPanelContentRefreshed.always((() => {
                this._strategy.refreshPanelElementSize("slide" === this.option("revealMode"));
                this._renderPosition(this.option("opened"), true, true);
                this._removePanelManualPosition()
            }))
        }
    },
    _clean() {
        this._cleanFocusState();
        this._removePanelContentWrapper();
        this._removeOverlay()
    },
    _removePanelContentWrapper() {
        if (this._$panelContentWrapper) {
            this._$panelContentWrapper.remove()
        }
    },
    _removeOverlay() {
        if (this._overlay) {
            this._overlay.dispose();
            delete this._overlay;
            delete this._$panelContentWrapper
        }
    },
    _optionChanged(args) {
        switch (args.name) {
            case "width":
                this.callBase(args);
                this._dimensionChanged();
                break;
            case "opened":
                this._renderPosition(this.option("opened"));
                this._toggleOpenedStateClass(args.value);
                this._togglePanelContentHiddenClass();
                break;
            case "position":
                this._refreshPositionClass(args.previousValue);
                this._refreshWrapperChildrenOrder();
                this._invalidate();
                break;
            case "contentTemplate":
            case "template":
                this._invalidate();
                break;
            case "openedStateMode":
                this._initStrategy();
                this._refreshOpenedStateModeClass(args.previousValue);
                this._refreshPanel();
                break;
            case "minSize":
                this._initMinMaxSize();
                this._renderPosition(this.option("opened"), true);
                this._togglePanelContentHiddenClass();
                break;
            case "maxSize":
                this._initMinMaxSize();
                this._renderPosition(this.option("opened"), true);
                break;
            case "revealMode":
                this._refreshRevealModeClass(args.previousValue);
                this._refreshPanel();
                break;
            case "shading":
                this._toggleShaderVisibility(this.option("opened"));
                break;
            case "animationEnabled":
            case "animationDuration":
            case "closeOnOutsideClick":
                break;
            default:
                this.callBase(args)
        }
    },
    content() {
        return (0, _element.getPublicElement)(this._$panelContentWrapper)
    },
    viewContent() {
        return (0, _element.getPublicElement)(this._$viewContentWrapper)
    },
    show() {
        return this.toggle(true)
    },
    hide() {
        return this.toggle(false)
    },
    toggle(opened) {
        const targetOpened = void 0 === opened ? !this.option("opened") : opened;
        this._whenAnimationCompleted = (0, _deferred.Deferred)();
        this.option("opened", targetOpened);
        return this._whenAnimationCompleted.promise()
    }
});
(0, _component_registrator.default)("dxDrawer", Drawer);
var _default = exports.default = Drawer;
