/*---------------------------------------------------------------------------------------------
 * 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
 */
import produce from "immer";
import { UiEvent } from "@itwin/appui-abstract";
import { WidgetDef } from "../widgets/WidgetDef";
import { WidgetHost } from "../widgets/WidgetHost";
import { StagePanelLocation } from "./StagePanelLocation";
import { StagePanelSection } from "./StagePanelSection";
import { InternalFrontstageManager } from "../frontstage/InternalFrontstageManager";
import { UiFramework } from "../UiFramework";
/** Enum for StagePanel state.
 * @public
 */
export 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 || (StagePanelState = {}));
/** Panel state changed event class.
 * @beta
 */
export class PanelStateChangedEvent extends UiEvent {
}
/** @internal */
export class PanelSizeChangedEvent extends UiEvent {
}
/**
 * A StagePanelDef represents each Stage Panel within a Frontstage.
 * @public
 */
export class StagePanelDef extends WidgetHost {
    /** Constructor for PanelDef. */
    constructor() {
        super();
        this._location = StagePanelLocation.Left;
        this._start = new StagePanelSectionDef();
        this._end = new StagePanelSectionDef();
    }
    /** @internal */
    static create(config, location) {
        const def = new StagePanelDef();
        def.initializeFromConfig(config, location);
        return def;
    }
    /** @internal */
    initializeFromConfig(config, location) {
        var _a, _b;
        this._location = location;
        this._initialConfig = config;
        this._start.initializeFromConfig((_a = config === null || config === void 0 ? void 0 : config.sections) === null || _a === void 0 ? void 0 : _a.start);
        this._end.initializeFromConfig((_b = config === null || config === void 0 ? void 0 : config.sections) === null || _b === void 0 ? void 0 : _b.end);
    }
    /** @internal */
    get initialConfig() {
        return this._initialConfig;
    }
    /** Current size of the panel */
    get size() {
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        const state = frontstageDef === null || frontstageDef === void 0 ? void 0 : frontstageDef.nineZoneState;
        if (!state)
            return this.defaultSize;
        const side = toPanelSide(this.location);
        const panel = state.panels[side];
        return panel.size;
    }
    set size(size) {
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        if (!frontstageDef)
            return;
        const side = toPanelSide(this.location);
        frontstageDef.dispatch({
            type: "PANEL_SET_SIZE",
            side,
            size,
        });
    }
    /** @internal */
    handleSizeChanged(size) {
        InternalFrontstageManager.onPanelSizeChangedEvent.emit({
            panelDef: this,
            size,
        });
    }
    /** Indicates whether the panel is resizable. */
    get resizable() {
        var _a, _b;
        return (_b = (_a = this._initialConfig) === null || _a === void 0 ? void 0 : _a.resizable) !== null && _b !== void 0 ? _b : true;
    }
    /** Indicates whether the panel is pinned. */
    get pinned() {
        var _a, _b;
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        const state = frontstageDef === null || frontstageDef === void 0 ? void 0 : frontstageDef.nineZoneState;
        if (!state)
            return (_b = (_a = this.initialConfig) === null || _a === void 0 ? void 0 : _a.pinned) !== null && _b !== void 0 ? _b : true;
        const side = toPanelSide(this.location);
        const panel = state.panels[side];
        return panel.pinned;
    }
    set pinned(pinned) {
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        if (!frontstageDef)
            return;
        const side = toPanelSide(this.location);
        frontstageDef.dispatch({
            type: "PANEL_SET_PINNED",
            side,
            pinned,
        });
    }
    /** @internal */
    handlePinnedChanged(pinned) {
        UiFramework.frontstages.onPanelPinnedChangedEvent.emit({
            panelDef: this,
            pinned,
        });
    }
    /** Location of panel. */
    get location() {
        return this._location;
    }
    /** Panel state. Defaults to PanelState.Open. */
    get panelState() {
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        const state = frontstageDef === null || frontstageDef === void 0 ? void 0 : frontstageDef.nineZoneState;
        if (!state)
            return this.defaultState;
        const side = toPanelSide(this.location);
        return getPanelState(state, side);
    }
    set panelState(panelState) {
        const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
        if (!frontstageDef)
            return;
        const side = toPanelSide(this.location);
        const collapsed = panelState === StagePanelState.Open ? false : true;
        frontstageDef.dispatch({
            type: "PANEL_SET_COLLAPSED",
            collapsed,
            side,
        });
    }
    /** @internal */
    handlePanelStateChanged(panelState) {
        UiFramework.frontstages.onPanelStateChangedEvent.emit({
            panelDef: this,
            panelState,
        });
    }
    /** @internal */
    get defaultState() {
        var _a;
        const defaultState = (_a = this._initialConfig) === null || _a === void 0 ? void 0 : _a.defaultState;
        return defaultState !== null && defaultState !== void 0 ? defaultState : StagePanelState.Open;
    }
    /** @internal */
    get defaultSize() {
        var _a;
        return (_a = this._initialConfig) === null || _a === void 0 ? void 0 : _a.size;
    }
    /** 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.Start, allStageWidgetDefs);
        this._end.updateDynamicWidgetDefs(stageId, stageUsage, location, StagePanelSection.End, allStageWidgetDefs);
    }
    /** @internal */
    getPanelSectionDef(section) {
        switch (section) {
            case StagePanelSection.Start: {
                return this._start;
            }
            case StagePanelSection.End: {
                return this._end;
            }
        }
    }
}
/** @internal */
export class StagePanelSectionDef extends WidgetHost {
    /** @internal */
    initializeFromConfig(config) {
        config === null || config === void 0 ? void 0 : config.forEach((widgetConfig) => {
            const widgetDef = WidgetDef.create(widgetConfig);
            this.addWidgetDef(widgetDef);
        });
    }
}
/** @internal */
export function toPanelSide(location) {
    switch (location) {
        case StagePanelLocation.Bottom:
            return "bottom";
        case StagePanelLocation.Left:
            return "left";
        case StagePanelLocation.Right:
            return "right";
        case StagePanelLocation.Top:
            return "top";
    }
}
/** @internal */
export const setPanelPinned = produce((nineZone, side, pinned) => {
    const panel = nineZone.panels[side];
    panel.pinned = pinned;
});
/** @internal */
export function getPanelState(state, side) {
    const panel = state.panels[side];
    return panel.collapsed ? StagePanelState.Minimized : StagePanelState.Open;
}
//# sourceMappingURL=StagePanelDef.js.map