"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 ContentView
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.IModelViewportControl = exports.ViewOverlayHost = exports.IModelConnectedViewport = void 0;
const React = require("react");
const presentation_components_1 = require("@itwin/presentation-components");
const imodel_components_react_1 = require("@itwin/imodel-components-react");
const core_react_1 = require("@itwin/core-react");
const connectIModel_1 = require("../redux/connectIModel");
const UiFramework_1 = require("../UiFramework");
const DefaultViewOverlay_1 = require("./DefaultViewOverlay");
const ViewportContentControl_1 = require("./ViewportContentControl");
const StandardRotationNavigationAid_1 = require("../navigationaids/StandardRotationNavigationAid");
const appui_abstract_1 = require("@itwin/appui-abstract");
const react_redux_1 = require("react-redux");
// create a HOC viewport component that supports unified selection
// eslint-disable-next-line @typescript-eslint/naming-convention
const UnifiedSelectionViewport = (0, presentation_components_1.viewWithUnifiedSelection)(imodel_components_react_1.ViewportComponent);
/** Viewport that is connected to the IModelConnection property in the Redux store. The application must set up the Redux store and include the FrameworkReducer.
 * @public
 */
exports.IModelConnectedViewport = (0, connectIModel_1.connectIModelConnectionAndViewState)(null, null)(UnifiedSelectionViewport); // eslint-disable-line @typescript-eslint/naming-convention
/** View Overlay component -- exported for testing
 * @internal
 */
// istanbul ignore next
function ViewOverlayHost({ viewport, featureOptions, userSuppliedOverlay }) {
    const displayViewOverlay = (0, react_redux_1.useSelector)((state) => {
        const frameworkState = state[UiFramework_1.UiFramework.frameworkStateKey];
        return frameworkState ? frameworkState.configurableUiState.viewOverlayDisplay : true;
    });
    if (!displayViewOverlay)
        return null;
    return userSuppliedOverlay ? React.createElement(React.Fragment, null, userSuppliedOverlay(viewport)) : React.createElement(DefaultViewOverlay_1.DefaultViewOverlay, { viewport: viewport, featureOptions: featureOptions });
}
exports.ViewOverlayHost = ViewOverlayHost;
/** iModel Viewport Control
 * @public
 */
// istanbul ignore next
class IModelViewportControl extends ViewportContentControl_1.ViewportContentControl {
    constructor(info, _options) {
        var _a;
        super(info, _options);
        this._options = _options;
        this._featureOptions = {};
        /**
         * This is passed as a function to the ViewportComponent as the `viewState` prop in getImodelViewportReactElement().
         * It is called by ViewportComponent on a mount to resolve the viewState.
         */
        this._determineViewState = () => {
            let viewState;
            if (this.viewport && !this._alwaysUseSuppliedViewState)
                viewState = this.viewport.view;
            else if (this._viewState) {
                if (typeof this._viewState === "function")
                    viewState = this._viewState();
                else
                    viewState = this._viewState;
            }
            else
                throw new appui_abstract_1.UiError(UiFramework_1.UiFramework.loggerCategory(this), "No ViewState could be determined");
            return viewState;
        };
        /** Get the default ViewOverlay unless parameter is set to not use it. May be override in an application specific sub-class  */
        this._getViewOverlay = (vp) => {
            return React.createElement(ViewOverlayHost, { viewport: vp, featureOptions: this._featureOptions, userSuppliedOverlay: this._userSuppliedViewOverlay, "data-testid": "ViewOverlay" });
        };
        if (_options.featureOptions)
            this._featureOptions = _options.featureOptions;
        this._alwaysUseSuppliedViewState = (_a = _options.alwaysUseSuppliedViewState) !== null && _a !== void 0 ? _a : false;
        this._userSuppliedViewOverlay = _options.supplyViewOverlay;
        if (!_options.deferNodeInitialization)
            this.initializeReactNode();
    }
    static get id() {
        return "UiFramework.IModelViewportControl";
    }
    initializeReactNode() {
        const options = this._options;
        if (options.viewState)
            this._viewState = options.viewState;
        const iModelConnection = (typeof options.iModelConnection === "function") ? options.iModelConnection() : options.iModelConnection;
        if (this._viewState && iModelConnection) {
            /** Passing _determineViewState as a function reference; it is not called here. */
            this._reactNode = this.getImodelViewportReactElement(iModelConnection, this._determineViewState);
        }
        else {
            if (UiFramework_1.UiFramework.getIModelConnection() && UiFramework_1.UiFramework.getDefaultViewState()) {
                this._reactNode = this.getImodelConnectedViewportReactElement();
            }
            else {
                this._reactNode = this.getNoContentReactElement(options);
                this.setIsReady();
            }
        }
    }
    getReactNode() {
        if (!React.isValidElement(this._reactNode) && this._options.deferNodeInitialization)
            this.initializeReactNode();
        return this.getKeyedReactNode();
    }
    /** Get the React component that will contain the Viewport */
    getImodelConnectedViewportReactElement() {
        return React.createElement(exports.IModelConnectedViewport, { viewportRef: (v) => {
                var _a;
                this.viewport = v;
                // for convenience, if window defined bind viewport to window
                if (undefined !== window)
                    window.viewport = v;
                if (!UiFramework_1.UiFramework.frontstages.isLoading)
                    (_a = UiFramework_1.UiFramework.frontstages.activeFrontstageDef) === null || _a === void 0 ? void 0 : _a.setActiveViewFromViewport(v);
            }, getViewOverlay: this._getViewOverlay });
    }
    /** Get the React component that will contain the Viewport */
    getImodelViewportReactElement(iModelConnection, viewState) {
        return React.createElement(UnifiedSelectionViewport, { viewState: viewState, imodel: iModelConnection, controlId: this.controlId, viewportRef: (v) => {
                var _a;
                this.viewport = v;
                // for convenience, if window defined bind viewport to window
                if (undefined !== window)
                    window.viewport = v;
                if (!UiFramework_1.UiFramework.frontstages.isLoading)
                    (_a = UiFramework_1.UiFramework.frontstages.activeFrontstageDef) === null || _a === void 0 ? void 0 : _a.setActiveViewFromViewport(v);
            }, getViewOverlay: this._getViewOverlay });
    }
    /** Get the React component that will be shown when no iModel data is available */
    getNoContentReactElement(_options) {
        const noContent = UiFramework_1.UiFramework.translate("general.no-content");
        return React.createElement(core_react_1.FillCentered, null,
            " ",
            noContent,
            " ");
    }
    /** Get the React.Element for a ViewSelector change. */
    getReactElementForViewSelectorChange(iModelConnection, _unusedViewDefinitionId, viewState, _name) {
        return this.getImodelViewportReactElement(iModelConnection, viewState);
    }
    /** Get the NavigationAidControl associated with this ContentControl */
    get navigationAidControl() {
        if (this.viewport)
            return super.navigationAidControl;
        else
            return StandardRotationNavigationAid_1.StandardRotationNavigationAidControl.navigationAidId;
    }
}
exports.IModelViewportControl = IModelViewportControl;
UiFramework_1.UiFramework.controls.register(IModelViewportControl.id, IModelViewportControl);
//# sourceMappingURL=IModelViewport.js.map