"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EasingInspector = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const client_id_1 = require("../../helpers/client-id");
const timeline_layout_1 = require("../../helpers/timeline-layout");
const plus_1 = require("../../icons/plus");
const render_frame_1 = require("../../state/render-frame");
const is_menu_item_1 = require("../Menu/is-menu-item");
const call_add_keyframe_1 = require("../Timeline/call-add-keyframe");
const EasingEditorModal_1 = require("../Timeline/EasingEditorModal");
const TimelineSelection_1 = require("../Timeline/TimelineSelection");
const update_selected_easing_1 = require("../Timeline/update-selected-easing");
const common_1 = require("./common");
const easing_inspector_selection_1 = require("./easing-inspector-selection");
const KeyframeEasingNavigator_1 = require("./KeyframeEasingNavigator");
const KeyframeSettings_1 = require("./KeyframeSettings");
const SequenceInspectorHeader_1 = require("./SequenceInspectorHeader");
const styles_1 = require("./styles");
const use_track_for_selection_1 = require("./use-track-for-selection");
const addKeyframeIcon = {
    display: 'block',
    height: 13,
    width: 12,
};
const EasingInspector = ({ selection }) => {
    var _a, _b;
    const track = (0, use_track_for_selection_1.useTrackForSelection)(selection);
    const videoConfig = (0, remotion_1.useVideoConfig)();
    const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
    const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
    const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
    const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
    const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
    const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
    const parentSelection = (0, react_1.useMemo)(() => (0, TimelineSelection_1.getTimelineSelectionFromNodePathInfo)(selection.nodePathInfo), [selection.nodePathInfo]);
    const easingUpdate = (0, react_1.useMemo)(() => (0, update_selected_easing_1.getSelectedEasingUpdate)({
        selection,
        sequences,
        overrideIdsToNodePaths: overrideIdToNodePathMappings,
        propStatuses,
    }), [overrideIdToNodePathMappings, propStatuses, selection, sequences]);
    const initialEasing = (_a = easingUpdate === null || easingUpdate === void 0 ? void 0 : easingUpdate.currentEasing) !== null && _a !== void 0 ? _a : null;
    const easingDetails = (0, react_1.useMemo)(() => {
        var _a, _b, _c, _d, _e, _f, _g;
        if (easingUpdate === null || track === null) {
            return null;
        }
        if (easingUpdate.type === 'sequence') {
            const sequenceDragOverrideValue = ((_a = getDragOverrides(easingUpdate.nodePath)) !== null && _a !== void 0 ? _a : {})[easingUpdate.fieldKey];
            if (!track.sequence.controls) {
                return {
                    defaultValue: undefined,
                    dragOverrideValue: sequenceDragOverrideValue,
                    fieldLabel: easingUpdate.fieldKey,
                };
            }
            const sequenceFields = (0, timeline_layout_1.getFieldsToShow)({
                schema: track.sequence.controls.schema,
                currentRuntimeValueDotNotation: track.sequence.controls.currentRuntimeValueDotNotation,
                getDragOverrides,
                propStatuses,
                nodePath: easingUpdate.nodePath,
            });
            const sequenceField = (_b = sequenceFields === null || sequenceFields === void 0 ? void 0 : sequenceFields.find((candidate) => candidate.key === easingUpdate.fieldKey)) !== null && _b !== void 0 ? _b : null;
            return {
                defaultValue: sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.fieldSchema.default,
                dragOverrideValue: sequenceDragOverrideValue,
                fieldLabel: (_d = (_c = sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.description) !== null && _c !== void 0 ? _c : sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.key) !== null && _d !== void 0 ? _d : easingUpdate.fieldKey,
            };
        }
        const effectDragOverrideValue = getEffectDragOverrides(easingUpdate.nodePath, easingUpdate.effectIndex)[easingUpdate.fieldKey];
        const effect = track.sequence.effects[easingUpdate.effectIndex];
        if (!effect) {
            return {
                defaultValue: undefined,
                dragOverrideValue: effectDragOverrideValue,
                fieldLabel: easingUpdate.fieldKey,
            };
        }
        const effectFields = (0, timeline_layout_1.getEffectFieldsToShow)({
            effect,
            effectIndex: easingUpdate.effectIndex,
            nodePath: easingUpdate.nodePath,
            propStatuses,
            getEffectDragOverrides,
        });
        const effectField = (_e = effectFields.find((candidate) => candidate.key === easingUpdate.fieldKey)) !== null && _e !== void 0 ? _e : null;
        return {
            defaultValue: effectField === null || effectField === void 0 ? void 0 : effectField.fieldSchema.default,
            dragOverrideValue: effectDragOverrideValue,
            fieldLabel: (_g = (_f = effectField === null || effectField === void 0 ? void 0 : effectField.description) !== null && _f !== void 0 ? _f : effectField === null || effectField === void 0 ? void 0 : effectField.key) !== null && _g !== void 0 ? _g : easingUpdate.fieldKey,
        };
    }, [
        easingUpdate,
        getDragOverrides,
        getEffectDragOverrides,
        propStatuses,
        track,
    ]);
    const fieldLabel = (_b = easingDetails === null || easingDetails === void 0 ? void 0 : easingDetails.fieldLabel) !== null && _b !== void 0 ? _b : null;
    const currentEasingSelection = (0, react_1.useMemo)(() => {
        if (easingUpdate === null || track === null) {
            return null;
        }
        return (0, easing_inspector_selection_1.getEasingSelectionFromCurrentKeyframes)({
            keyframeDisplayOffset: track.keyframeDisplayOffset,
            nodePathInfo: selection.nodePathInfo,
            propStatus: easingUpdate.propStatus,
            segmentIndex: easingUpdate.segmentIndex,
        });
    }, [easingUpdate, selection.nodePathInfo, track]);
    const state = (0, react_1.useMemo)(() => {
        if (initialEasing === null || currentEasingSelection === null) {
            return null;
        }
        return {
            initialEasing,
            selections: [currentEasingSelection],
        };
    }, [currentEasingSelection, initialEasing]);
    const onSelectParent = (0, react_1.useCallback)((event) => {
        event.stopPropagation();
        if (parentSelection === null) {
            return;
        }
        selectItems([parentSelection], { reveal: true });
    }, [parentSelection, selectItems]);
    const canAddKeyframeAtPlayhead = currentEasingSelection !== null &&
        timelinePosition > currentEasingSelection.fromFrame &&
        timelinePosition < currentEasingSelection.toFrame;
    const addKeyframeTime = (0, render_frame_1.renderFrame)(timelinePosition, videoConfig.fps);
    const addKeyframeDisabled = previewServerState.type !== 'connected';
    const onAddKeyframeAtPlayhead = (0, react_1.useCallback)((event) => {
        event.stopPropagation();
        if (!canAddKeyframeAtPlayhead ||
            easingUpdate === null ||
            easingDetails === null ||
            track === null ||
            previewServerState.type !== 'connected') {
            return;
        }
        const sourceFrame = timelinePosition - track.keyframeDisplayOffset;
        const value = remotion_1.Internals.getEffectiveVisualModeValue({
            propStatus: easingUpdate.propStatus,
            dragOverrideValue: easingDetails.dragOverrideValue,
            defaultValue: easingDetails.defaultValue,
            frame: sourceFrame,
            shouldResortToDefaultValueIfUndefined: true,
        });
        const keyframeSelection = {
            type: 'keyframe',
            nodePathInfo: selection.nodePathInfo,
            frame: timelinePosition,
        };
        if (easingUpdate.type === 'sequence') {
            (0, call_add_keyframe_1.callAddSequenceKeyframe)({
                fileName: easingUpdate.fileName,
                nodePath: easingUpdate.nodePath,
                fieldKey: easingUpdate.fieldKey,
                sourceFrame,
                value,
                schema: easingUpdate.schema,
                setPropStatuses,
                clientId: previewServerState.clientId,
            }).catch(() => undefined);
        }
        else {
            (0, call_add_keyframe_1.callAddEffectKeyframe)({
                fileName: easingUpdate.fileName,
                nodePath: easingUpdate.nodePath,
                effectIndex: easingUpdate.effectIndex,
                fieldKey: easingUpdate.fieldKey,
                sourceFrame,
                value,
                schema: easingUpdate.schema,
                setPropStatuses,
                clientId: previewServerState.clientId,
            }).catch(() => undefined);
        }
        selectItems([keyframeSelection], { reveal: true });
    }, [
        canAddKeyframeAtPlayhead,
        easingDetails,
        easingUpdate,
        previewServerState,
        selectItems,
        selection.nodePathInfo,
        setPropStatuses,
        timelinePosition,
        track,
    ]);
    const renderHeader = (0, react_1.useCallback)(() => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
            jsx_runtime_1.jsx(common_1.InspectorBackHeaderWithDivider, { disabled: parentSelection === null, onClick: onSelectParent, title: "Back to property", children: jsx_runtime_1.jsx("div", { style: styles_1.sectionHeaderTitle, children: fieldLabel }) }), easingUpdate === null || track === null ? null : (jsx_runtime_1.jsx(KeyframeEasingNavigator_1.KeyframeEasingNavigator, { currentSelection: currentEasingSelection !== null && currentEasingSelection !== void 0 ? currentEasingSelection : selection, includeEasings: true, keyframes: easingUpdate.propStatus.keyframes.map((keyframe) => ({
                    ...keyframe,
                    frame: keyframe.frame + track.keyframeDisplayOffset,
                })), nodePathInfo: selection.nodePathInfo }))] })), [
        currentEasingSelection,
        easingUpdate,
        fieldLabel,
        onSelectParent,
        parentSelection,
        selection,
        track,
    ]);
    if (state === null ||
        track === null ||
        currentEasingSelection === null ||
        easingUpdate === null) {
        return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Easing unavailable" });
    }
    return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [
            jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeaderWithDivider, { track: track }), jsx_runtime_1.jsx(EasingEditorModal_1.EasingEditor, { state: state, renderHeader: renderHeader }, (0, TimelineSelection_1.getTimelineSelectionKey)(currentEasingSelection)), jsx_runtime_1.jsx(KeyframeSettings_1.KeyframeSettings, { update: easingUpdate }), canAddKeyframeAtPlayhead ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
                    jsx_runtime_1.jsx("div", { style: styles_1.inspectorSectionDivider }), jsx_runtime_1.jsx("div", { style: styles_1.detailsContainer, children: jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: addKeyframeDisabled, onClick: onAddKeyframeAtPlayhead, renderIcon: (color) => (jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: addKeyframeIcon })), children: `Add keyframe at ${addKeyframeTime}` }) })
                ] })) : null] }));
};
exports.EasingInspector = EasingInspector;
