"use strict";
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Frontstage
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.setPanelPinned = exports.setPanelSize = exports.toPanelSide = exports.StagePanelSectionDef = exports.StagePanelDef = exports.PanelSizeChangedEvent = exports.PanelStateChangedEvent = exports.StagePanelState = void 0;
const immer_1 = require("immer");
const appui_abstract_1 = require("@itwin/appui-abstract");
const WidgetDef_1 = require("../widgets/WidgetDef");
const WidgetHost_1 = require("../widgets/WidgetHost");
const StagePanelLocation_1 = require("./StagePanelLocation");
const StagePanelSection_1 = require("./StagePanelSection");
const InternalFrontstageManager_1 = require("../frontstage/InternalFrontstageManager");
const UiFramework_1 = require("../UiFramework");
/** Enum for StagePanel state.
 * @public
 */
var StagePanelState;
(function (StagePanelState) {
    StagePanelState[StagePanelState["Off"] = 0] = "Off";
    StagePanelState[StagePanelState["Minimized"] = 1] = "Minimized";
    StagePanelState[StagePanelState["Open"] = 2] = "Open";
    StagePanelState[StagePanelState["Popup"] = 3] = "Popup";
})(StagePanelState = exports.StagePanelState || (exports.StagePanelState = {}));
/** Panel state changed event class.
 * @beta
 */
class PanelStateChangedEvent extends appui_abstract_1.UiEvent {
}
exports.PanelStateChangedEvent = PanelStateChangedEvent;
/** @internal */
class PanelSizeChangedEvent extends appui_abstract_1.UiEvent {
}
exports.PanelSizeChangedEvent = PanelSizeChangedEvent;
/**
 * A StagePanelDef represents each Stage Panel within a Frontstage.
 * @public
 */
class StagePanelDef extends WidgetHost_1.WidgetHost {
    /** Constructor for PanelDef.
     */
    constructor() {
        super();
        this._panelState = StagePanelState.Open;
        this._defaultState = StagePanelState.Open;
        this._resizable = true;
        this._pinned = true;
        this._location = StagePanelLocation_1.StagePanelLocation.Left;
        this._start = new StagePanelSectionDef();
        this._end = new StagePanelSectionDef();
    }
    /** @internal */
    get maxSizeSpec() {
        return this._maxSizeSpec;
    }
    /** @internal */
    get minSize() {
        return this._minSize;
    }
    /** Default size of the panel */
    get size() {
        // istanbul ignore else
        if (UiFramework_1.UiFramework.frontstages.activeFrontstageDef) {
            const [_, size] = UiFramework_1.UiFramework.frontstages.activeFrontstageDef.getPanelCurrentState(this);
            return size;
        }
        // istanbul ignore next
        return this._defaultSize;
    }
    set size(size) {
        if (this._size === size)
            return;
        // istanbul ignore else
        const frontstageDef = UiFramework_1.UiFramework.frontstages.activeFrontstageDef;
        // istanbul ignore else
        if (frontstageDef && frontstageDef.nineZoneState) {
            const side = toPanelSide(this.location);
            frontstageDef.nineZoneState = (0, exports.setPanelSize)(frontstageDef.nineZoneState, side, size);
            const panel = frontstageDef.nineZoneState.panels[side];
            if (panel.size === this._size)
                return;
            size = panel.size;
        }
        this._size = size;
        InternalFrontstageManager_1.InternalFrontstageManager.onPanelSizeChangedEvent.emit({
            panelDef: this,
            size,
        });
    }
    /** Indicates whether the panel is resizable. */
    // istanbul ignore next
    get resizable() {
        return this._resizable;
    }
    /** Indicates whether the panel is pinned. */
    get pinned() {
        if (UiFramework_1.UiFramework.frontstages.activeFrontstageDef) {
            const state = UiFramework_1.UiFramework.frontstages.activeFrontstageDef.getPanelCurrentState(this);
            return state[2];
        }
        // istanbul ignore next
        return false;
    }
    set pinned(pinned) {
        if (this._pinned === pinned)
            return;
        // istanbul ignore else
        const frontstageDef = UiFramework_1.UiFramework.frontstages.activeFrontstageDef;
        // istanbul ignore else
        if (frontstageDef && frontstageDef.nineZoneState) {
            const side = toPanelSide(this.location);
            frontstageDef.nineZoneState = (0, exports.setPanelPinned)(frontstageDef.nineZoneState, side, pinned);
        }
        this._pinned = pinned;
        UiFramework_1.UiFramework.frontstages.onPanelPinnedChangedEvent.emit({
            panelDef: this,
            pinned,
        });
    }
    /** Location of panel. */
    get location() {
        return this._location;
    }
    /** Panel state. Defaults to PanelState.Open. */
    get panelState() {
        // istanbul ignore else
        if (UiFramework_1.UiFramework.frontstages.activeFrontstageDef) {
            const [state] = UiFramework_1.UiFramework.frontstages.activeFrontstageDef?.getPanelCurrentState(this);
            return state;
        }
        // istanbul ignore next
        return this.defaultState;
    }
    set panelState(panelState) {
        if (panelState === this._panelState)
            return;
        const frontstageDef = UiFramework_1.UiFramework.frontstages.activeFrontstageDef;
        if (frontstageDef && frontstageDef.nineZoneState) {
            const side = toPanelSide(this.location);
            frontstageDef.nineZoneState = (0, immer_1.default)(frontstageDef.nineZoneState, (nineZone) => {
                const panel = nineZone.panels[side];
                switch (panelState) {
                    case StagePanelState.Minimized: {
                        panel.collapsed = true;
                        break;
                    }
                    case StagePanelState.Open: {
                        panel.collapsed = false;
                        break;
                    }
                    case StagePanelState.Off: {
                        panel.collapsed = true;
                        break;
                    }
                }
            });
        }
        this._panelState = panelState;
        UiFramework_1.UiFramework.frontstages.onPanelStateChangedEvent.emit({
            panelDef: this,
            panelState,
        });
    }
    /** @internal */
    get defaultState() {
        return this._defaultState;
    }
    /** @internal */
    get defaultSize() {
        return this._defaultSize;
    }
    /** @internal */
    static create(config, location) {
        const def = new StagePanelDef();
        def.initializeFromConfig(config, location);
        return def;
    }
    /** @internal */
    initializeFromConfig(config, location) {
        this._location = location;
        if (!config)
            return;
        this._size = config.size;
        this._defaultSize = config.size;
        this._maxSizeSpec = config.maxSize;
        this._minSize = config.minSize;
        if (config.defaultState !== undefined) {
            this._defaultState = config.defaultState;
            this._panelState = config.defaultState;
        }
        this._resizable = config.resizable ?? true;
        if (config.pinned !== undefined)
            this._pinned = config.pinned;
        const sections = config.sections;
        this._start.initializeFromConfig(sections?.start);
        this._end.initializeFromConfig(sections?.end);
    }
    /** Gets the list of Widgets. */
    get widgetDefs() {
        return [
            ...super.widgetDefs,
            ...this._start.widgetDefs,
            ...this._end.widgetDefs,
        ];
    }
    /** @internal */
    updateDynamicWidgetDefs(stageId, stageUsage, location, _section, allStageWidgetDefs) {
        this._start.updateDynamicWidgetDefs(stageId, stageUsage, location, StagePanelSection_1.StagePanelSection.Start, allStageWidgetDefs);
        this._end.updateDynamicWidgetDefs(stageId, stageUsage, location, StagePanelSection_1.StagePanelSection.End, allStageWidgetDefs);
    }
    /** @internal */
    getPanelSectionDef(section) {
        switch (section) {
            case StagePanelSection_1.StagePanelSection.Start: {
                return this._start;
            }
            case StagePanelSection_1.StagePanelSection.End: {
                return this._end;
            }
        }
    }
}
exports.StagePanelDef = StagePanelDef;
/** @internal */
class StagePanelSectionDef extends WidgetHost_1.WidgetHost {
    /** @internal */
    initializeFromConfig(config) {
        config?.forEach((widgetConfig) => {
            const widgetDef = WidgetDef_1.WidgetDef.create(widgetConfig);
            this.addWidgetDef(widgetDef);
        });
    }
}
exports.StagePanelSectionDef = StagePanelSectionDef;
/** @internal */
function toPanelSide(location) {
    switch (location) {
        case StagePanelLocation_1.StagePanelLocation.Bottom:
            return "bottom";
        case StagePanelLocation_1.StagePanelLocation.Left:
            return "left";
        case StagePanelLocation_1.StagePanelLocation.Right:
            return "right";
        case StagePanelLocation_1.StagePanelLocation.Top:
            return "top";
    }
}
exports.toPanelSide = toPanelSide;
/** @internal */
exports.setPanelSize = (0, immer_1.default)((nineZone, side, size) => {
    const panel = nineZone.panels[side];
    panel.size =
        size === undefined
            ? size
            : Math.min(Math.max(size, panel.minSize), panel.maxSize);
});
/** @internal */
exports.setPanelPinned = (0, immer_1.default)((nineZone, side, pinned) => {
    const panel = nineZone.panels[side];
    panel.pinned = pinned;
});
//# sourceMappingURL=StagePanelDef.js.map