/*---------------------------------------------------------------------------------------------
 * 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
 */
import * as React from "react";
import { ViewportComponent } from "@itwin/imodel-components-react";
import { FillCentered } from "@itwin/core-react";
import { UiFramework } from "../UiFramework.js";
import { DefaultViewOverlay } from "./DefaultViewOverlay.js";
import { ViewportContentControl } from "./ViewportContentControl.js";
import { StandardRotationNavigationAidControl } from "../navigationaids/StandardRotationNavigationAid.js";
import { UiError } from "@itwin/appui-abstract";
import { useReduxFrameworkState } from "../uistate/useReduxFrameworkState.js";
import { ConfigurableUiContext } from "../configurableui/ConfigurableUiContent.js";
/* eslint-disable @typescript-eslint/no-deprecated */
/** Viewport that is connected to the IModelConnection property in the Redux store. The application must set up the Redux store and include the FrameworkReducer.
 * @note Requires redux provider.
 * @public
 * @deprecated in 4.15.0. Use {@link @itwin/imodel-components-react#ViewportComponent} instead.
 */
export function IModelConnectedViewport(props) {
    const iModel = useReduxFrameworkState((state) => state?.sessionState.iModelConnection);
    const viewState = useReduxFrameworkState((state) => state?.sessionState.defaultViewState);
    if (!iModel)
        return null;
    return React.createElement(ViewportComponent, { imodel: iModel, viewState: viewState, ...props });
}
/** @internal */
export function ViewOverlayHost({ viewport, featureOptions, userSuppliedOverlay, }) {
    const reduxDisplayViewOverlay = useReduxFrameworkState((state) => state?.configurableUiState.viewOverlayDisplay);
    const configurableUi = React.useContext(ConfigurableUiContext);
    const displayViewOverlay = configurableUi?.viewOverlay ?? reduxDisplayViewOverlay ?? true;
    if (!displayViewOverlay)
        return null;
    return userSuppliedOverlay ? (React.createElement(React.Fragment, null, userSuppliedOverlay(viewport))) : (React.createElement(DefaultViewOverlay, { viewport: viewport, featureOptions: featureOptions }));
}
/** iModel Viewport Control
 * @public
 * @deprecated in 4.16.0. Use {@link @itwin/imodel-components-react#ViewportComponent} component instead.
 */
export class IModelViewportControl extends ViewportContentControl {
    _options;
    static get id() {
        return "UiFramework.IModelViewportControl";
    }
    _featureOptions = {};
    _viewState;
    _iModelConnection;
    _alwaysUseSuppliedViewState;
    _userSuppliedViewOverlay;
    constructor(info, _options) {
        _options = _options ?? {};
        super(info, _options);
        this._options = _options;
        this._options = _options;
        if (_options.featureOptions)
            this._featureOptions = _options.featureOptions;
        this._alwaysUseSuppliedViewState =
            _options.alwaysUseSuppliedViewState ?? false;
        this._userSuppliedViewOverlay = _options.supplyViewOverlay;
        if (!_options.deferNodeInitialization)
            this.initializeReactNode();
    }
    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.getIModelConnection() &&
                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();
    }
    /**
     * 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.
     */
    _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 UiError(UiFramework.loggerCategory("IModelViewport"), "No ViewState could be determined");
        return viewState;
    };
    /** Get the React component that will contain the Viewport */
    getImodelConnectedViewportReactElement() {
        return (React.createElement(IModelConnectedViewport, { viewportRef: (v) => {
                this.viewport = v;
                // for convenience, if window defined bind viewport to window
                if (undefined !== window)
                    window.viewport = v;
                if (!UiFramework.frontstages.isLoading)
                    UiFramework.frontstages.activeFrontstageDef?.setActiveViewFromViewport(v);
            }, getViewOverlay: this._getViewOverlay }));
    }
    /** Get the React component that will contain the Viewport */
    getImodelViewportReactElement(iModelConnection, viewState) {
        return (React.createElement(ViewportComponent, { viewState: viewState, imodel: iModelConnection, controlId: this.controlId, viewportRef: (v) => {
                this.viewport = v;
                // for convenience, if window defined bind viewport to window
                if (undefined !== window)
                    window.viewport = v;
                if (!UiFramework.frontstages.isLoading)
                    UiFramework.frontstages.activeFrontstageDef?.setActiveViewFromViewport(v);
            }, getViewOverlay: this._getViewOverlay }));
    }
    /** Get the React component that will be shown when no iModel data is available */
    getNoContentReactElement(_options) {
        return (React.createElement(FillCentered, null, UiFramework.translate("general.no-content")));
    }
    /** Get the React.Element for a ViewSelector change. */
    getReactElementForViewSelectorChange(iModelConnection, _unusedViewDefinitionId, viewState, _name) {
        return this.getImodelViewportReactElement(iModelConnection, viewState);
    }
    /** Get the default ViewOverlay unless parameter is set to not use it. May be override in an application specific sub-class  */
    _getViewOverlay = (vp) => {
        return (React.createElement(ViewOverlayHost, { viewport: vp, featureOptions: this._featureOptions, userSuppliedOverlay: this._userSuppliedViewOverlay, "data-testid": "ViewOverlay" }));
    };
    /** Get the NavigationAidControl associated with this ContentControl */
    get navigationAidControl() {
        if (this.viewport)
            return super.navigationAidControl;
        else
            return StandardRotationNavigationAidControl.navigationAidId;
    }
}
//# sourceMappingURL=IModelViewport.js.map