"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 AccuDraw
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccuDrawFieldContainer = void 0;
require("./AccuDrawFieldContainer.scss");
const classnames_1 = require("classnames");
const React = require("react");
const core_frontend_1 = require("@itwin/core-frontend");
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_react_1 = require("@itwin/core-react");
const imodel_components_react_1 = require("@itwin/imodel-components-react");
const AccuDrawInputField_1 = require("./AccuDrawInputField");
const FrameworkAccuDraw_1 = require("./FrameworkAccuDraw");
const angle_svg_1 = require("./angle.svg");
const distance_svg_1 = require("./distance.svg");
const UiFramework_1 = require("../UiFramework");
let AccuDrawContainerIndex = 0;
function determineShowZ(vp) {
    const showZ = vp !== undefined ? /* istanbul ignore next */ vp.view.is3d() : false;
    return showZ;
}
const defaultXLabel = "X";
const defaultYLabel = "Y";
const defaultZLabel = "Z";
const defaultAngleIcon = appui_abstract_1.IconSpecUtilities.createWebComponentIconSpec(angle_svg_1.default);
const defaultDistanceIcon = appui_abstract_1.IconSpecUtilities.createWebComponentIconSpec(distance_svg_1.default);
/** AccuDraw Ui Field Container displays [[AccuDrawInputField]] for each field
 * @beta */
function AccuDrawFieldContainer(props) {
    const { className, style, orientation, uiSettingsStorage, showZOverride, ...otherProps } = props;
    const [containerIndex] = React.useState(() => ++AccuDrawContainerIndex);
    const xInputRef = React.useRef(null);
    const yInputRef = React.useRef(null);
    const zInputRef = React.useRef(null);
    const angleInputRef = React.useRef(null);
    const distanceInputRef = React.useRef(null);
    const focusField = React.useRef(undefined);
    const [mode, setMode] = React.useState(core_frontend_1.CompassMode.Rectangular);
    const [xLock, setXLock] = React.useState(false);
    const [yLock, setYLock] = React.useState(false);
    const [zLock, setZLock] = React.useState(false);
    const [angleLock, setAngleLock] = React.useState(false);
    const [distanceLock, setDistanceLock] = React.useState(false);
    const [showZ, setShowZ] = React.useState(true);
    const [xLabel, setXLabel] = React.useState(defaultXLabel);
    const [yLabel, setYLabel] = React.useState(defaultYLabel);
    const [zLabel, setZLabel] = React.useState(defaultZLabel);
    const [angleLabel, setAngleLabel] = React.useState(undefined);
    const [distanceLabel, setDistanceLabel] = React.useState(undefined);
    const [xIcon, setXIcon] = React.useState(undefined);
    const [yIcon, setYIcon] = React.useState(undefined);
    const [zIcon, setZIcon] = React.useState(undefined);
    const [angleIcon, setAngleIcon] = React.useState(defaultAngleIcon);
    const [distanceIcon, setDistanceIcon] = React.useState(defaultDistanceIcon);
    const [xStyle, setXStyle] = React.useState(undefined);
    const [yStyle, setYStyle] = React.useState(undefined);
    const [zStyle, setZStyle] = React.useState(undefined);
    const [angleStyle, setAngleStyle] = React.useState(undefined);
    const [distanceStyle, setDistanceStyle] = React.useState(undefined);
    const getInputRef = (field) => {
        let inputRef;
        switch (field) {
            case core_frontend_1.ItemField.X_Item:
                inputRef = xInputRef;
                break;
            case core_frontend_1.ItemField.Y_Item:
                inputRef = yInputRef;
                break;
            case core_frontend_1.ItemField.Z_Item:
                inputRef = zInputRef;
                break;
            case core_frontend_1.ItemField.ANGLE_Item:
                inputRef = angleInputRef;
                break;
            case core_frontend_1.ItemField.DIST_Item:
                inputRef = distanceInputRef;
                break;
        }
        return inputRef;
    };
    React.useEffect(() => {
        setXLock(core_frontend_1.IModelApp.accuDraw.getFieldLock(core_frontend_1.ItemField.X_Item));
        setYLock(core_frontend_1.IModelApp.accuDraw.getFieldLock(core_frontend_1.ItemField.Y_Item));
        setZLock(core_frontend_1.IModelApp.accuDraw.getFieldLock(core_frontend_1.ItemField.Z_Item));
        setAngleLock(core_frontend_1.IModelApp.accuDraw.getFieldLock(core_frontend_1.ItemField.ANGLE_Item));
        setDistanceLock(core_frontend_1.IModelApp.accuDraw.getFieldLock(core_frontend_1.ItemField.DIST_Item));
        const handleSetFieldLock = (args) => {
            switch (args.field) {
                case core_frontend_1.ItemField.X_Item:
                    setXLock(args.lock);
                    break;
                case core_frontend_1.ItemField.Y_Item:
                    setYLock(args.lock);
                    break;
                case core_frontend_1.ItemField.Z_Item:
                    setZLock(args.lock);
                    break;
                case core_frontend_1.ItemField.ANGLE_Item:
                    setAngleLock(args.lock);
                    break;
                case core_frontend_1.ItemField.DIST_Item:
                    setDistanceLock(args.lock);
                    break;
            }
        };
        return FrameworkAccuDraw_1.FrameworkAccuDraw.onAccuDrawSetFieldLockEvent.addListener(handleSetFieldLock);
    }, []);
    const setFocusToField = React.useCallback((field) => {
        const inputRef = getInputRef(field);
        // istanbul ignore else
        if (inputRef.current && document.activeElement !== inputRef.current) {
            inputRef.current.focus();
            inputRef.current.select();
        }
    }, []);
    React.useEffect(() => {
        const handleSetFieldFocus = (args) => {
            focusField.current = args.field;
            setFocusToField(focusField.current);
        };
        return FrameworkAccuDraw_1.FrameworkAccuDraw.onAccuDrawSetFieldFocusEvent.addListener(handleSetFieldFocus);
    }, [setFocusToField]);
    React.useEffect(() => {
        const handleGrabInputFocus = () => {
            // istanbul ignore else
            if (focusField.current)
                setFocusToField(focusField.current);
        };
        return FrameworkAccuDraw_1.FrameworkAccuDraw.onAccuDrawGrabInputFocusEvent.addListener(handleGrabInputFocus);
    }, [setFocusToField]);
    React.useEffect(() => {
        setMode(core_frontend_1.IModelApp.accuDraw.compassMode);
        const handleSetMode = (args) => {
            setMode(args.mode);
        };
        return FrameworkAccuDraw_1.FrameworkAccuDraw.onAccuDrawSetCompassModeEvent.addListener(handleSetMode);
    }, []);
    const handleValueChanged = React.useCallback((field, stringValue) => {
        FrameworkAccuDraw_1.FrameworkAccuDraw.setFieldValueFromUi(field, stringValue);
    }, []);
    const handleEscPressed = React.useCallback(() => {
        UiFramework_1.UiFramework.keyboardShortcuts.setFocusToHome();
    }, []);
    React.useEffect(() => {
        setShowZ(showZOverride || determineShowZ(core_frontend_1.IModelApp.viewManager.selectedView));
        // istanbul ignore next
        const handleSelectedViewportChanged = (args) => {
            setShowZ(determineShowZ(args.current));
        };
        return core_frontend_1.IModelApp.viewManager.onSelectedViewportChanged.addListener(handleSelectedViewportChanged);
    }, [showZOverride]);
    React.useEffect(() => {
        const createFieldStyle = (inStyle, backgroundColor, foregroundColor) => {
            let fieldStyle;
            let rgbaString = "";
            if (inStyle || backgroundColor || foregroundColor) {
                fieldStyle = inStyle ? inStyle : {};
                if (backgroundColor) {
                    rgbaString =
                        typeof backgroundColor === "string"
                            ? backgroundColor
                            : (0, imodel_components_react_1.getCSSColorFromDef)(backgroundColor);
                    fieldStyle = { ...fieldStyle, backgroundColor: rgbaString };
                }
                if (foregroundColor) {
                    rgbaString =
                        typeof foregroundColor === "string"
                            ? foregroundColor
                            : (0, imodel_components_react_1.getCSSColorFromDef)(foregroundColor);
                    fieldStyle = { ...fieldStyle, color: rgbaString };
                }
            }
            return fieldStyle;
        };
        const processAccuDrawUiSettings = (settings) => {
            setXStyle(settings
                ? createFieldStyle(settings.xStyle, settings.xBackgroundColor, settings.xForegroundColor)
                : undefined);
            setYStyle(settings
                ? createFieldStyle(settings.yStyle, settings.yBackgroundColor, settings.yForegroundColor)
                : undefined);
            setZStyle(settings
                ? createFieldStyle(settings.zStyle, settings.zBackgroundColor, settings.zForegroundColor)
                : undefined);
            setAngleStyle(settings
                ? createFieldStyle(settings.angleStyle, settings.angleBackgroundColor, settings.angleForegroundColor)
                : undefined);
            setDistanceStyle(settings
                ? createFieldStyle(settings.distanceStyle, settings.distanceBackgroundColor, settings.distanceForegroundColor)
                : undefined);
            setXLabel(settings && settings.xLabel !== undefined
                ? settings.xLabel
                : defaultXLabel);
            setYLabel(settings && settings.yLabel !== undefined
                ? settings.yLabel
                : defaultYLabel);
            setZLabel(settings && settings.zLabel !== undefined
                ? settings.zLabel
                : defaultZLabel);
            setAngleLabel(settings && settings.angleLabel !== undefined
                ? settings.angleLabel
                : undefined);
            setDistanceLabel(settings && settings.distanceLabel !== undefined
                ? settings.distanceLabel
                : undefined);
            setXIcon(settings && settings.xIcon !== undefined ? settings.xIcon : undefined);
            setYIcon(settings && settings.yIcon !== undefined ? settings.yIcon : undefined);
            setZIcon(settings && settings.zIcon !== undefined ? settings.zIcon : undefined);
            setAngleIcon(settings && settings.angleIcon !== undefined
                ? settings.angleIcon
                : defaultAngleIcon);
            setDistanceIcon(settings && settings.distanceIcon !== undefined
                ? settings.distanceIcon
                : defaultDistanceIcon);
        };
        if (FrameworkAccuDraw_1.FrameworkAccuDraw.uiStateStorage)
            processAccuDrawUiSettings(FrameworkAccuDraw_1.FrameworkAccuDraw.uiStateStorage);
        // istanbul ignore next
        const handleAccuDrawUiSettingsChanged = () => {
            processAccuDrawUiSettings(FrameworkAccuDraw_1.FrameworkAccuDraw.uiStateStorage);
        };
        return FrameworkAccuDraw_1.FrameworkAccuDraw.onAccuDrawUiSettingsChangedEvent.addListener(handleAccuDrawUiSettingsChanged);
    }, []);
    const classNames = (0, classnames_1.default)("uifw-accudraw-field-container", orientation === core_react_1.Orientation.Vertical
        ? "uifw-accudraw-field-container-vertical"
        : "uifw-accudraw-field-container-horizontal", className);
    const delay = 250;
    const labelCentered = xLabel !== undefined &&
        xLabel.length === 1 &&
        yLabel !== undefined &&
        yLabel.length === 1 &&
        zLabel !== undefined &&
        zLabel.length === 1;
    return (React.createElement("div", { className: classNames, style: style, ...otherProps },
        mode === core_frontend_1.CompassMode.Rectangular && (React.createElement(React.Fragment, null,
            React.createElement(AccuDrawInputField_1.AccuDrawInputField, { ref: xInputRef, isLocked: xLock, className: "uifw-accudraw-x-value", style: xStyle, field: core_frontend_1.ItemField.X_Item, id: `uifw-accudraw-x-${containerIndex}`, "data-testid": "uifw-accudraw-x", label: xLabel, iconSpec: xIcon, labelCentered: labelCentered, valueChangedDelay: delay, onValueChanged: (stringValue) => handleValueChanged(core_frontend_1.ItemField.X_Item, stringValue), onEscPressed: handleEscPressed }),
            React.createElement(AccuDrawInputField_1.AccuDrawInputField, { ref: yInputRef, isLocked: yLock, className: "uifw-accudraw-y-value", style: yStyle, field: core_frontend_1.ItemField.Y_Item, id: `uifw-accudraw-y-${containerIndex}`, "data-testid": "uifw-accudraw-y", label: yLabel, iconSpec: yIcon, labelCentered: labelCentered, valueChangedDelay: delay, onValueChanged: (stringValue) => handleValueChanged(core_frontend_1.ItemField.Y_Item, stringValue), onEscPressed: handleEscPressed }),
            showZ && (React.createElement(AccuDrawInputField_1.AccuDrawInputField, { ref: zInputRef, isLocked: zLock, className: "uifw-accudraw-z-value", style: zStyle, field: core_frontend_1.ItemField.Z_Item, id: `uifw-accudraw-z-${containerIndex}`, "data-testid": "uifw-accudraw-z", label: zLabel, iconSpec: zIcon, labelCentered: labelCentered, valueChangedDelay: delay, onValueChanged: (stringValue) => handleValueChanged(core_frontend_1.ItemField.Z_Item, stringValue), onEscPressed: handleEscPressed })))),
        mode === core_frontend_1.CompassMode.Polar && (React.createElement(React.Fragment, null,
            React.createElement(AccuDrawInputField_1.AccuDrawInputField, { ref: angleInputRef, isLocked: angleLock, className: "uifw-accudraw-angle-value", style: angleStyle, field: core_frontend_1.ItemField.ANGLE_Item, id: `uifw-accudraw-angle-${containerIndex}`, "data-testid": "uifw-accudraw-angle", label: angleLabel, iconSpec: angleIcon, valueChangedDelay: delay, onValueChanged: (stringValue) => handleValueChanged(core_frontend_1.ItemField.ANGLE_Item, stringValue), onEscPressed: handleEscPressed }),
            React.createElement(AccuDrawInputField_1.AccuDrawInputField, { ref: distanceInputRef, isLocked: distanceLock, className: "uifw-accudraw-distance-value", style: distanceStyle, field: core_frontend_1.ItemField.DIST_Item, id: `uifw-accudraw-distance-${containerIndex}`, "data-testid": "uifw-accudraw-distance", label: distanceLabel, iconSpec: distanceIcon, valueChangedDelay: delay, onValueChanged: (stringValue) => handleValueChanged(core_frontend_1.ItemField.DIST_Item, stringValue), onEscPressed: handleEscPressed })))));
}
exports.AccuDrawFieldContainer = AccuDrawFieldContainer;
//# sourceMappingURL=AccuDrawFieldContainer.js.map