"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RenderButton = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = require("react");
const react_dom_1 = __importDefault(require("react-dom"));
const remotion_1 = require("remotion");
const client_id_1 = require("../helpers/client-id");
const colors_1 = require("../helpers/colors");
const use_keybinding_1 = require("../helpers/use-keybinding");
const caret_1 = require("../icons/caret");
const render_1 = require("../icons/render");
const in_out_1 = require("../state/in-out");
const modals_1 = require("../state/modals");
const z_index_1 = require("../state/z-index");
const layout_1 = require("./layout");
const is_menu_item_1 = require("./Menu/is-menu-item");
const portals_1 = require("./Menu/portals");
const styles_1 = require("./Menu/styles");
const MenuContent_1 = require("./NewComposition/MenuContent");
const splitButtonContainer = {
    display: 'inline-flex',
    flexDirection: 'row',
    alignItems: 'stretch',
    borderRadius: 4,
    border: `1px solid ${colors_1.BLACK_ALPHA_60}`,
    backgroundColor: colors_1.INPUT_BACKGROUND,
    overflow: 'hidden',
};
const mainButtonStyle = {
    paddingLeft: 7,
    paddingRight: 7,
    paddingTop: 7,
    paddingBottom: 7,
    background: colors_1.TRANSPARENT,
    border: 'none',
    color: colors_1.WHITE,
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    fontSize: 14,
    fontFamily: 'inherit',
};
const dividerStyle = {
    width: 1,
    backgroundColor: colors_1.BLACK_ALPHA_60,
    alignSelf: 'stretch',
};
const dropdownTriggerStyle = {
    paddingLeft: 6,
    paddingRight: 6,
    paddingTop: 7,
    paddingBottom: 7,
    background: colors_1.TRANSPARENT,
    border: 'none',
    color: colors_1.WHITE,
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
};
const mainButtonContent = {
    paddingLeft: 4,
    paddingRight: 6,
};
const label = {
    fontSize: 14,
};
const RENDER_TYPE_STORAGE_KEY = 'remotion.renderType';
const getInitialRenderType = (readOnlyStudio) => {
    if (readOnlyStudio) {
        return 'client-render';
    }
    try {
        const stored = localStorage.getItem(RENDER_TYPE_STORAGE_KEY);
        if (stored === 'server-render' || stored === 'client-render') {
            return stored;
        }
    }
    catch (_a) {
        // localStorage might not be available
    }
    return 'server-render';
};
const RenderButton = ({ readOnlyStudio, }) => {
    const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
    const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
    const [preferredRenderType, setPreferredRenderType] = (0, react_1.useState)(() => getInitialRenderType(readOnlyStudio));
    const [dropdownOpened, setDropdownOpened] = (0, react_1.useState)(false);
    const dropdownRef = (0, react_1.useRef)(null);
    const containerRef = (0, react_1.useRef)(null);
    const { currentZIndex } = (0, z_index_1.useZIndex)();
    const size = player_1.PlayerInternals.useElementSize(dropdownRef, {
        triggerOnWindowResize: true,
        shouldApplyCssTransforms: true,
    });
    const refresh = size === null || size === void 0 ? void 0 : size.refresh;
    const onPointerDown = (0, react_1.useCallback)((e) => {
        // Prevent deselection of currently selected items
        e.stopPropagation();
        setDropdownOpened((o) => {
            if (!o) {
                refresh === null || refresh === void 0 ? void 0 : refresh();
            }
            return !o;
        });
    }, [refresh]);
    const onMenuPointerDown = (0, react_1.useCallback)((e) => {
        // Prevent deselection of currently selected items
        e.stopPropagation();
    }, []);
    const onClickDropdown = (0, react_1.useCallback)((e) => {
        e.stopPropagation();
        const isKeyboardInitiated = e.detail === 0;
        if (!isKeyboardInitiated) {
            return;
        }
        setDropdownOpened((o) => {
            if (!o) {
                refresh === null || refresh === void 0 ? void 0 : refresh();
                window.addEventListener('pointerup', (evt) => {
                    if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
                        setDropdownOpened(false);
                    }
                }, {
                    once: true,
                });
            }
            return !o;
        });
    }, [refresh]);
    const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
        .previewServerState.type;
    const canServerRender = connectionStatus === 'connected';
    const renderType = (0, react_1.useMemo)(() => {
        if (readOnlyStudio) {
            return preferredRenderType === 'render-command'
                ? 'render-command'
                : 'client-render';
        }
        if (connectionStatus === 'disconnected') {
            return 'client-render';
        }
        return preferredRenderType;
    }, [connectionStatus, preferredRenderType, readOnlyStudio]);
    const shortcut = (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? '' : '(R)';
    const tooltip = renderType === 'render-command'
        ? 'Copy a CLI command to render this composition ' + shortcut
        : 'Export the current composition ' + shortcut;
    const iconStyle = (0, react_1.useMemo)(() => {
        return {
            style: {
                height: 16,
                color: colors_1.CURRENT_COLOR,
            },
        };
    }, []);
    const video = remotion_1.Internals.useVideo();
    const { getCurrentFrame } = player_1.PlayerInternals.usePlayer();
    const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
    const openServerRenderModal = (0, react_1.useCallback)((copyCommandOnly) => {
        var _a;
        var _b, _c;
        if (!video) {
            return null;
        }
        const defaults = window.remotion_renderDefaults;
        if (!defaults) {
            throw new TypeError('Expected defaults');
        }
        setSelectedModal({
            type: 'server-render',
            readOnlyStudio: copyCommandOnly,
            compositionId: video.id,
            initialFrame: getCurrentFrame(),
            initialStillImageFormat: defaults.stillImageFormat,
            initialVideoImageFormat: null,
            initialJpegQuality: defaults.jpegQuality,
            initialScale: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : 1,
            initialLogLevel: defaults.logLevel,
            initialConcurrency: defaults.concurrency,
            maxConcurrency: defaults.maxConcurrency,
            minConcurrency: defaults.minConcurrency,
            initialMuted: defaults.muted,
            initialEnforceAudioTrack: defaults.enforceAudioTrack,
            initialProResProfile: defaults.proResProfile,
            initialx264Preset: defaults.x264Preset,
            initialGopSize: defaults.gopSize,
            initialPixelFormat: null,
            initialAudioBitrate: defaults.audioBitrate,
            initialVideoBitrate: defaults.videoBitrate,
            initialEveryNthFrame: defaults.everyNthFrame,
            initialNumberOfGifLoops: defaults.numberOfGifLoops,
            initialDelayRenderTimeout: defaults.delayRenderTimeout,
            defaultConfigurationAudioCodec: defaults.audioCodec,
            initialEnvVariables: window.process.env,
            initialDisableWebSecurity: defaults.disableWebSecurity,
            initialDarkMode: defaults.darkMode,
            initialOpenGlRenderer: defaults.openGlRenderer,
            initialHeadless: defaults.headless,
            initialIgnoreCertificateErrors: defaults.ignoreCertificateErrors,
            initialOffthreadVideoCacheSizeInBytes: defaults.offthreadVideoCacheSizeInBytes,
            initialOffthreadVideoThreads: defaults.offthreadVideoThreads,
            defaultProps: (_c = props[video.id]) !== null && _c !== void 0 ? _c : video.defaultProps,
            inFrameMark: inFrame,
            outFrameMark: outFrame,
            initialColorSpace: defaults.colorSpace,
            initialMultiProcessOnLinux: defaults.multiProcessOnLinux,
            defaultConfigurationVideoCodec: defaults.codec,
            initialEncodingBufferSize: defaults.encodingBufferSize,
            initialEncodingMaxRate: defaults.encodingMaxRate,
            initialUserAgent: defaults.userAgent,
            initialBeep: defaults.beepOnFinish,
            initialRepro: defaults.repro,
            initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
            renderTypeOfLastRender: null,
            defaulMetadata: defaults.metadata,
            initialHardwareAcceleration: defaults.hardwareAcceleration,
            initialSampleRate: defaults.sampleRate,
            initialChromeMode: defaults.chromeMode,
            initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
            renderDefaults: defaults,
        });
    }, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
    const openClientRenderModal = (0, react_1.useCallback)(() => {
        var _a;
        if (!video) {
            return null;
        }
        const defaults = window.remotion_renderDefaults;
        if (!defaults) {
            throw new TypeError('Expected defaults');
        }
        setSelectedModal({
            type: 'web-render',
            compositionId: video.id,
            initialFrame: getCurrentFrame(),
            defaultProps: (_a = props[video.id]) !== null && _a !== void 0 ? _a : video.defaultProps,
            inFrameMark: inFrame,
            outFrameMark: outFrame,
            initialLogLevel: defaults.logLevel,
            initialLicenseKey: defaults.publicLicenseKey,
            initialStillImageFormat: defaults.stillImageFormat,
            initialScale: defaults.scale,
            initialDelayRenderTimeout: defaults.delayRenderTimeout,
            initialDefaultOutName: null,
            initialContainer: null,
            initialVideoCodec: null,
            initialAudioCodec: null,
            initialAudioBitrate: null,
            initialVideoBitrate: null,
            initialHardwareAcceleration: null,
            initialKeyframeIntervalInSeconds: null,
            initialTransparent: null,
            initialMuted: null,
            initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
            initialPageResponsiveness: 'medium',
        });
    }, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
    const onClick = (0, react_1.useCallback)(() => {
        if (renderType === 'render-command') {
            openServerRenderModal(true);
            return;
        }
        if (renderType === 'server-render') {
            openServerRenderModal(false);
        }
        else {
            openClientRenderModal();
        }
    }, [renderType, openServerRenderModal, openClientRenderModal]);
    const onHideDropdown = (0, react_1.useCallback)(() => {
        setDropdownOpened(false);
    }, []);
    const handleRenderTypeChange = (0, react_1.useCallback)((newType) => {
        setPreferredRenderType(newType);
        try {
            localStorage.setItem(RENDER_TYPE_STORAGE_KEY, newType);
        }
        catch (_a) {
            // localStorage might not be available
        }
        setDropdownOpened(false);
        if (newType === 'server-render') {
            openServerRenderModal(false);
        }
        else if (newType === 'render-command') {
            openServerRenderModal(true);
        }
        else {
            openClientRenderModal();
        }
    }, [openClientRenderModal, openServerRenderModal]);
    const dropdownValues = (0, react_1.useMemo)(() => {
        if (readOnlyStudio) {
            return [
                {
                    type: 'item',
                    id: 'client-render',
                    label: 'Render on web',
                    value: 'client-render',
                    onClick: () => handleRenderTypeChange('client-render'),
                    keyHint: null,
                    leftItem: null,
                    subMenu: null,
                    quickSwitcherLabel: null,
                },
                {
                    type: 'item',
                    id: 'render-command',
                    label: 'Render via CLI',
                    value: 'render-command',
                    onClick: () => handleRenderTypeChange('render-command'),
                    keyHint: null,
                    leftItem: null,
                    subMenu: null,
                    quickSwitcherLabel: null,
                },
            ];
        }
        return [
            {
                type: 'item',
                id: 'server-render',
                label: 'Server-side render',
                value: 'server-render',
                onClick: () => handleRenderTypeChange('server-render'),
                keyHint: null,
                leftItem: null,
                subMenu: null,
                quickSwitcherLabel: null,
            },
            {
                type: 'item',
                id: 'client-render',
                label: 'Client-side render',
                value: 'client-render',
                onClick: () => handleRenderTypeChange('client-render'),
                keyHint: null,
                leftItem: null,
                subMenu: null,
                quickSwitcherLabel: null,
            },
        ];
    }, [handleRenderTypeChange, readOnlyStudio]);
    const spaceToBottom = (0, react_1.useMemo)(() => {
        const margin = 10;
        if (size && dropdownOpened) {
            return size.windowSize.height - (size.top + size.height) - margin;
        }
        return 0;
    }, [dropdownOpened, size]);
    const spaceToTop = (0, react_1.useMemo)(() => {
        const margin = 10;
        if (size && dropdownOpened) {
            return size.top - margin;
        }
        return 0;
    }, [dropdownOpened, size]);
    const derivedMaxHeight = (0, react_1.useMemo)(() => {
        return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
    }, [spaceToBottom, spaceToTop]);
    const portalStyle = (0, react_1.useMemo)(() => {
        if (!dropdownOpened || !size) {
            return null;
        }
        const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
        return {
            ...(verticalLayout === 'top'
                ? {
                    ...styles_1.menuContainerTowardsBottom,
                    top: size.top + size.height,
                }
                : {
                    ...styles_1.menuContainerTowardsTop,
                    bottom: size.windowSize.height - size.top,
                }),
            right: size.windowSize.width - size.left - size.width,
        };
    }, [dropdownOpened, size, spaceToBottom, spaceToTop]);
    const containerStyle = (0, react_1.useMemo)(() => {
        return {
            ...splitButtonContainer,
            borderColor: colors_1.BLACK_ALPHA_60,
            opacity: 1,
            cursor: 'pointer',
        };
    }, []);
    const renderLabel = renderType === 'server-render'
        ? 'Render'
        : renderType === 'render-command'
            ? 'Render via CLI'
            : 'Render on web';
    if (!video) {
        return null;
    }
    return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
            jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: !canServerRender, onClick: () => openServerRenderModal(false), type: "button" }), ' ', jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-client", onClick: openClientRenderModal, type: "button" }), jsx_runtime_1.jsxs("div", { ref: containerRef, style: containerStyle, title: tooltip, children: [
                    jsx_runtime_1.jsx("button", { type: "button", style: mainButtonStyle, onClick: onClick, id: "render-modal-button", children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", style: mainButtonContent, children: [
                                jsx_runtime_1.jsx(render_1.ThinRenderIcon, { fill: colors_1.CURRENT_COLOR_LOWERCASE, svgProps: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("span", { style: label, children: renderLabel })
                            ] }) }), jsx_runtime_1.jsx("div", { style: dividerStyle }), jsx_runtime_1.jsx("button", { ref: dropdownRef, type: "button", style: dropdownTriggerStyle, className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, onPointerDown: onPointerDown, onClick: onClickDropdown, children: jsx_runtime_1.jsx(caret_1.CaretDown, {}) })
                ] }), portalStyle
                ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHideDropdown, onEscape: onHideDropdown, children: jsx_runtime_1.jsx("div", { style: portalStyle, onPointerDown: onMenuPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: () => { }, onPreviousMenu: () => { }, values: dropdownValues, onHide: onHideDropdown, leaveLeftSpace: false, preselectIndex: dropdownValues.findIndex((v) => v.id === renderType), topItemCanBeUnselected: false, fixedHeight: derivedMaxHeight }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
                : null] }));
};
exports.RenderButton = RenderButton;
