"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Timeline = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const calculate_timeline_1 = require("../../helpers/calculate-timeline");
const client_id_1 = require("../../helpers/client-id");
const colors_1 = require("../../helpers/colors");
const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
const is_current_selected_still_1 = require("../../helpers/is-current-selected-still");
const open_in_editor_1 = require("../../helpers/open-in-editor");
const call_api_1 = require("../call-api");
const ContextMenu_1 = require("../ContextMenu");
const import_assets_1 = require("../import-assets");
const is_menu_item_1 = require("../Menu/is-menu-item");
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
const SplitterContainer_1 = require("../Splitter/SplitterContainer");
const SplitterElement_1 = require("../Splitter/SplitterElement");
const SplitterHandle_1 = require("../Splitter/SplitterHandle");
const MaxTimelineTracks_1 = require("./MaxTimelineTracks");
const SequencePropsObserver_1 = require("./SequencePropsObserver");
const should_show_track_in_timeline_1 = require("./should-show-track-in-timeline");
const should_subscribe_to_sequence_props_1 = require("./should-subscribe-to-sequence-props");
const SubscribeToNodePaths_1 = require("./SubscribeToNodePaths");
const timeline_refs_1 = require("./timeline-refs");
const TimelineDragHandler_1 = require("./TimelineDragHandler");
const TimelineHeightContainer_1 = require("./TimelineHeightContainer");
const TimelineInOutDragHandler_1 = require("./TimelineInOutDragHandler");
const TimelineInOutPointer_1 = require("./TimelineInOutPointer");
const TimelineKeyframeTracksContext_1 = require("./TimelineKeyframeTracksContext");
const TimelineList_1 = require("./TimelineList");
const TimelinePinchZoom_1 = require("./TimelinePinchZoom");
const TimelinePlayCursorSyncer_1 = require("./TimelinePlayCursorSyncer");
const TimelineScrollable_1 = require("./TimelineScrollable");
const TimelineSelection_1 = require("./TimelineSelection");
const TimelineSlider_1 = require("./TimelineSlider");
const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
const TimelineTracks_1 = require("./TimelineTracks");
const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
const use_resolved_stack_1 = require("./use-resolved-stack");
const container = {
    minHeight: '100%',
    flex: 1,
    display: 'flex',
    height: 0,
    overflowY: 'auto',
    backgroundColor: colors_1.BACKGROUND,
};
const noop = () => undefined;
const TimelineContextMenuArea = ({ children }) => {
    var _a, _b;
    const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
    const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
    const [isAddingSolid, setIsAddingSolid] = (0, react_1.useState)(false);
    const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const previewConnected = previewServerState.type === 'connected';
    const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
    const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
    const currentComposition = (0, react_1.useMemo)(() => {
        var _a;
        if (currentCompositionId === null) {
            return null;
        }
        return ((_a = compositions.find((composition) => composition.id === currentCompositionId)) !== null && _a !== void 0 ? _a : null);
    }, [compositions, currentCompositionId]);
    const resolvedCompositionLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _a !== void 0 ? _a : null);
    const compositionFile = (_b = resolvedCompositionLocation === null || resolvedCompositionLocation === void 0 ? void 0 : resolvedCompositionLocation.source) !== null && _b !== void 0 ? _b : null;
    const compositionComponentInfo = (0, open_in_editor_1.useCachedCompositionComponentInfo)({
        compositionFile,
        compositionId: currentCompositionId,
    });
    const canInsertSolid = previewInteractive &&
        (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
        currentCompositionId !== null &&
        compositionFile !== null &&
        videoConfig !== null &&
        !isAddingSolid;
    const canInsertAsset = previewInteractive &&
        !window.remotion_isReadOnlyStudio &&
        (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
        currentCompositionId !== null &&
        compositionFile !== null &&
        !isAddingAsset;
    const insertSolid = (0, react_1.useCallback)(async () => {
        if (!canInsertSolid ||
            currentCompositionId === null ||
            compositionFile === null ||
            videoConfig === null) {
            return;
        }
        setIsAddingSolid(true);
        try {
            const result = await (0, call_api_1.callApi)('/api/insert-jsx-element', {
                compositionFile,
                compositionId: currentCompositionId,
                element: {
                    type: 'solid',
                    width: videoConfig.width,
                    height: videoConfig.height,
                    position: null,
                },
            });
            if (result.success) {
                (0, NotificationCenter_1.showNotification)('Added <Solid> to source file', 2000);
                return;
            }
            (0, NotificationCenter_1.showNotification)(result.reason, 4000);
        }
        catch (err) {
            (0, NotificationCenter_1.showNotification)(err.message, 4000);
        }
        finally {
            setIsAddingSolid(false);
        }
    }, [canInsertSolid, compositionFile, currentCompositionId, videoConfig]);
    const insertAsset = (0, react_1.useCallback)(async () => {
        if (!canInsertAsset ||
            currentCompositionId === null ||
            compositionFile === null) {
            return;
        }
        const files = await (0, import_assets_1.pickFilesToImport)();
        if (files.length === 0) {
            return;
        }
        setIsAddingAsset(true);
        try {
            await (0, import_assets_1.importAssets)({
                files,
                compositionFile,
                compositionId: currentCompositionId,
                destinationDimensions: null,
                dropPosition: null,
            });
        }
        finally {
            setIsAddingAsset(false);
        }
    }, [canInsertAsset, compositionFile, currentCompositionId]);
    const contextMenuItems = (0, react_1.useMemo)(() => {
        return [
            {
                type: 'item',
                id: 'insert-solid',
                label: 'Add <Solid>',
                value: 'insert-solid',
                onClick: insertSolid,
                keyHint: null,
                leftItem: null,
                subMenu: null,
                quickSwitcherLabel: null,
                disabled: !canInsertSolid,
            },
            {
                type: 'item',
                id: 'insert-asset',
                label: 'Add asset',
                value: 'insert-asset',
                onClick: insertAsset,
                keyHint: null,
                leftItem: null,
                subMenu: null,
                quickSwitcherLabel: null,
                disabled: !canInsertAsset,
            },
        ];
    }, [insertSolid, canInsertSolid, insertAsset, canInsertAsset]);
    return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, values: contextMenuItems, onOpen: null, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: children }));
};
const TimelineInner = () => {
    var _a;
    const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
    const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
    const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
    const isStill = (0, is_current_selected_still_1.useIsStill)();
    const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const previewConnected = previewServerState.type === 'connected';
    const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
    const videoConfigIsNull = videoConfig === null;
    const timeline = (0, react_1.useMemo)(() => {
        if (videoConfigIsNull) {
            return [];
        }
        return (0, calculate_timeline_1.calculateTimeline)({
            sequences,
            overrideIdsToNodePaths: overrideIdToNodePathMappings,
            compositions,
        });
    }, [
        sequences,
        videoConfigIsNull,
        overrideIdToNodePathMappings,
        compositions,
    ]);
    const durationInFrames = (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 0;
    const filtered = (0, react_1.useMemo)(() => {
        return timeline.filter((t) => (0, should_show_track_in_timeline_1.shouldShowTrackInTimeline)(t, durationInFrames));
    }, [durationInFrames, timeline]);
    const shown = (0, react_1.useMemo)(() => {
        return filtered.length > MaxTimelineTracks_1.MAX_TIMELINE_TRACKS
            ? filtered.slice(0, MaxTimelineTracks_1.MAX_TIMELINE_TRACKS)
            : filtered;
    }, [filtered]);
    const hasBeenCut = filtered.length > shown.length;
    return (jsx_runtime_1.jsxs(TimelineContextMenuArea, { children: [sequences.map((sequence) => {
                if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewInteractive)) {
                    return null;
                }
                return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
            }), interactivity_enabled_1.studioInteractivityEnabled ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
                                    jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
                                            jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
                                                        jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null, jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
                                                    ] }) })
                                        ] })
                                ] })) })
                    ] }) })
        ] }));
};
exports.Timeline = react_1.default.memo(TimelineInner);
