"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 Dialog
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.DialogRendererBase = exports.DialogManagerBase = exports.DialogChangedEvent = void 0;
const React = require("react");
const core_bentley_1 = require("@itwin/core-bentley");
const appui_abstract_1 = require("@itwin/appui-abstract");
const UiFramework_1 = require("../UiFramework");
const core_react_1 = require("@itwin/core-react");
/** Dialog Changed Event class.
 * @public
 */
class DialogChangedEvent extends appui_abstract_1.UiEvent {
}
exports.DialogChangedEvent = DialogChangedEvent;
/** Used if the 'dialog' z-index CSS variable cannot be read */
const ZINDEX_DEFAULT = 12000;
/** Dialog Manager class.
 * @internal
 */
class DialogManagerBase {
    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;
    }
    get onDialogChangedEvent() {
        return this._onDialogChangedEvent;
    }
    static getDialogZIndexDefault() {
        const variable = "--uicore-z-index-dialog";
        const value = (0, core_react_1.getCssVariableAsNumber)(variable);
        // istanbul ignore next
        if (!isNaN(value))
            return value;
        core_bentley_1.Logger.logError(UiFramework_1.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}`;
        // istanbul ignore next
        const owningDoc = parentDocument !== null && parentDocument !== void 0 ? 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;
exports.DialogManagerBase = DialogManagerBase;
/** DialogRenderer React component.
 * @internal
 */
class DialogRendererBase extends React.PureComponent {
    constructor() {
        super(...arguments);
        /** @internal */
        this.state = {
            parentDocument: null,
        };
        this._handleRefSet = (popupDiv) => {
            var _a;
            this.setState({ parentDocument: (_a = popupDiv === null || popupDiv === void 0 ? void 0 : popupDiv.ownerDocument) !== null && _a !== void 0 ? _a : null });
        };
        this._handleDialogChangedEvent = (_args) => {
            this.forceUpdate();
        };
    }
    render() {
        if (this.props.dialogManager.dialogCount <= 0)
            return null;
        return (React.createElement("div", { className: "appui-react-dialog-render-container", ref: this._handleRefSet }, this.state.parentDocument &&
            this.props.dialogManager.dialogs
                .filter((info) => info.parentDocument === this.state.parentDocument)
                .map((dialogInfo) => {
                return (React.createElement(React.Fragment, { key: dialogInfo.id }, dialogInfo.reactNode));
            })));
    }
    componentDidMount() {
        this.props.dialogManager.onDialogChangedEvent.addListener(this._handleDialogChangedEvent);
    }
    componentWillUnmount() {
        this.props.dialogManager.onDialogChangedEvent.removeListener(this._handleDialogChangedEvent);
    }
}
exports.DialogRendererBase = DialogRendererBase;
//# sourceMappingURL=DialogManagerBase.js.map