/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Dialog
 */
import "./DialogManagerBase.scss";
import * as React from "react";
import { Logger } from "@itwin/core-bentley";
import { UiEvent } from "@itwin/appui-abstract";
import { UiFramework } from "../UiFramework";
import { getCssVariableAsNumber } from "@itwin/core-react";
import { ThemeProvider } from "@itwin/itwinui-react";
/** Dialog Changed Event class.
 * @public
 * @deprecated in 4.13.0. This class should not be used by applications to instantiate objects.
 */
// eslint-disable-next-line deprecation/deprecation
export class DialogChangedEvent extends UiEvent {
}
/** Used if the 'dialog' z-index CSS variable cannot be read */
const ZINDEX_DEFAULT = 12000;
/** Dialog Manager class.
 * @internal
 */
export class DialogManagerBase {
    // eslint-disable-next-line deprecation/deprecation
    constructor(onDialogChangedEvent) {
        this._dialogs = new Array();
        this._onDialogChangedEvent = onDialogChangedEvent;
    }
    /** Initialize the modeless dialog manager */
    static initialize() {
        DialogManagerBase._topZIndex = DialogManagerBase.getDialogZIndexDefault();
    }
    static get topZIndex() {
        return DialogManagerBase._topZIndex;
    }
    static set topZIndex(zIndex) {
        DialogManagerBase._topZIndex = zIndex;
    }
    get dialogs() {
        return this._dialogs;
    }
    // eslint-disable-next-line deprecation/deprecation
    get onDialogChangedEvent() {
        return this._onDialogChangedEvent;
    }
    static getDialogZIndexDefault() {
        const variable = "--uicore-z-index-dialog";
        // eslint-disable-next-line deprecation/deprecation
        const value = getCssVariableAsNumber(variable);
        if (!isNaN(value))
            return value;
        Logger.logError(UiFramework.loggerCategory(this), `'${variable}' CSS variable not found`);
        return ZINDEX_DEFAULT;
    }
    /**
     * Triggers opening a dialog.
     * @param dialog Dialog React component.
     * @param id The unique Id the identifies the dialog.
     * @param parentDocument Optional document required when displaying a dialog in a child popup window.
     */
    openDialog(dialog, id, parentDocument) {
        if (!id)
            id = `Dialog-${++DialogManagerBase._sId}`;
        const owningDoc = parentDocument ?? document;
        this.pushDialog({ reactNode: dialog, id, parentDocument: owningDoc });
    }
    /** @internal */
    pushDialog(dialogInfo) {
        this._dialogs.push(dialogInfo);
        this.emitDialogChangedEvent();
    }
    closeDialog(dialog) {
        let targetDialog = dialog;
        if (!dialog)
            targetDialog = this.activeDialog;
        this.removeDialog(targetDialog);
        this.emitDialogChangedEvent();
    }
    /** @internal */
    closeAll() {
        this._dialogs = [];
        this.emitDialogChangedEvent();
    }
    /** @internal */
    removeDialog(dialog) {
        const index = this._dialogs.findIndex((dialogInfo) => {
            return dialog === dialogInfo.reactNode;
        });
        if (index >= 0)
            this._dialogs.splice(index, 1);
        if (this._dialogs.length < 1)
            DialogManagerBase.topZIndex = DialogManagerBase.getDialogZIndexDefault();
    }
    emitDialogChangedEvent() {
        this._onDialogChangedEvent.emit({
            dialogCount: this.dialogCount,
            activeDialog: this.activeDialog,
        });
    }
    update() {
        this.emitDialogChangedEvent();
    }
    get activeDialog() {
        if (this._dialogs.length > 0)
            return this._dialogs[this._dialogs.length - 1].reactNode;
        return undefined;
    }
    get dialogCount() {
        return this._dialogs.length;
    }
}
DialogManagerBase._sId = 0;
DialogManagerBase._topZIndex = ZINDEX_DEFAULT;
/** DialogRenderer React component.
 * @internal
 */
export class DialogRendererBase extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {
            parentDocument: undefined,
            renderer: undefined,
        };
        this._handleRefSet = (el) => {
            this.setState({
                parentDocument: el?.ownerDocument ?? undefined,
                renderer: el ?? undefined,
            });
        };
        this._handleDialogChangedEvent = () => {
            this.forceUpdate();
        };
    }
    render() {
        if (this.props.dialogManager.dialogCount <= 0)
            return null;
        return (React.createElement("div", { className: "uifw-dialog-dialogManagerBase_renderer", ref: this._handleRefSet },
            React.createElement(ThemeProvider, { portalContainer: this.state.renderer }, this.state.parentDocument &&
                this.props.dialogManager.dialogs
                    .filter((info) => info.parentDocument === this.state.parentDocument)
                    .map((info) => {
                    return (React.createElement(React.Fragment, { key: info.id }, info.reactNode));
                }))));
    }
    componentDidMount() {
        this.props.dialogManager.onDialogChangedEvent.addListener(this._handleDialogChangedEvent);
    }
    componentWillUnmount() {
        this.props.dialogManager.onDialogChangedEvent.removeListener(this._handleDialogChangedEvent);
    }
}
//# sourceMappingURL=DialogManagerBase.js.map