import classNames from 'classnames';
import omit from 'lodash.omit';
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import Draggable from "react-draggable";
import {ContextMenuTrigger} from 'react-contextmenu';
import {BorderedMenuItem, ContextMenu, DangerousMenuItem, MenuItem} from '../context-menu/context-menu.jsx';
import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl';
import {connect} from 'react-redux';
import MediaQuery from 'react-responsive';
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
import tabStyles from 'react-tabs/style/react-tabs.css';
import VM from 'scratch-vm';
import Renderer from 'scratch-render';

import Blocks from '../../containers/blocks.jsx';
import CostumeTab from '../../containers/costume-tab.jsx';
import TargetPane from '../../containers/target-pane.jsx';
import SoundTab from '../../containers/sound-tab.jsx';
import VariablesTab from '../../containers/variables-tab.jsx';
import FilesTab from '../../containers/files-tab.jsx';
import StageWrapper from '../../containers/stage-wrapper.jsx';
import Loader from '../loader/loader.jsx';
import Box from '../box/box.jsx';
import MenuBar from '../menu-bar/menu-bar.jsx';
import CostumeLibrary from '../../containers/costume-library.jsx';
import BackdropLibrary from '../../containers/backdrop-library.jsx';
import Watermark from '../../containers/watermark.jsx';

import Backpack from '../../containers/backpack.jsx';
import BrowserModal from '../browser-modal/browser-modal.jsx';
import TipsLibrary from '../../containers/tips-library.jsx';
import Cards from '../../containers/cards.jsx';
import Alerts from '../../containers/alerts.jsx';
import DragLayer from '../../containers/drag-layer.jsx';
import ConnectionModal from '../../containers/connection-modal.jsx';
import TelemetryModal from '../telemetry-modal/telemetry-modal.jsx';
import TWUsernameModal from '../../containers/tw-username-modal.jsx';
import TWSettingsModal from '../../containers/tw-settings-modal.jsx';
import TWSecurityManager from '../../containers/tw-security-manager.jsx';
import TWCustomExtensionModal from '../../containers/tw-custom-extension-modal.jsx';
import TWRestorePointManager from '../../containers/tw-restore-point-manager.jsx';
import TWFontsModal from '../../containers/tw-fonts-modal.jsx';
import PMExtensionModals from '../../containers/pm-extension-modals.jsx';

import layout, {STAGE_SIZE_MODES} from '../../lib/layout-constants';
import {resolveStageSize} from '../../lib/screen-utils';

import {isRendererSupported, isBrowserSupported} from '../../lib/tw-environment-support-prober';

import styles from './gui.css';
import { ReactComponent as PlusIcon } from './add-tab.svg';
import { ReactComponent as AddExtensionIcon } from './icon--extensions.svg';
import { ReactComponent as CodeIcon } from './icon--code.svg';
import { ReactComponent as CostumesIcon } from './icon--costumes.svg';
import { ReactComponent as SoundsIcon } from './icon--sounds.svg';
import { ReactComponent as VariablesIcon } from './icon--variables.svg';
import { ReactComponent as FilesIcon } from './icon--files.svg';

const urlParams = new URLSearchParams(location.search);

const IsLocal = String(window.location.href).startsWith(`http://localhost:`);
const IsLiveTests = urlParams.has('livetests');

const messages = defineMessages({
    addExtension: {
        id: 'gui.gui.addExtension',
        description: 'Button to add an extension in the target pane',
        defaultMessage: 'Add Extension'
    }
});

const getFullscreenBackgroundColor = () => {
    const params = new URLSearchParams(location.search);
    if (params.has('fullscreen-background')) {
        return params.get('fullscreen-background');
    }
    if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        return '#111';
    }
    return 'white';
};

const safeJSONParse = (json, defaul, mustBeArray) => {
    try {
        const parsed = JSON.parse(json);
        if (mustBeArray && !Array.isArray(parsed)) throw 'Not array';
        return parsed;
    } catch {
        return defaul;
    }
};

const fullscreenBackgroundColor = getFullscreenBackgroundColor();

const GUIComponent = props => {
    const {
        accountNavOpen,
        activeTabIndex,
        alertsVisible,
        authorId,
        authorThumbnailUrl,
        authorUsername,
        basePath,
        backdropLibraryVisible,
        backpackHost,
        backpackVisible,
        blocksTabVisible,
        cardsVisible,
        canChangeLanguage,
        canCreateNew,
        canEditTitle,
        canManageFiles,
        canRemix,
        canSave,
        canCreateCopy,
        canShare,
        canUseCloud,
        children,
        connectionModalVisible,
        costumeLibraryVisible,
        costumesTabVisible,
        customStageSize,
        enableCommunity,
        intl,
        isCreating,
        isDark,
        isEmbedded,
        isFullScreen,
        isPlayerOnly,
        isRtl,
        isShared,
        isWindowFullScreen,
        isTelemetryEnabled,
        loading,
        logo,
        renderLogin,
        onClickAbout,
        onClickAccountNav,
        onCloseAccountNav,
        onClickAddonSettings,
        onClickNewWindow,
        onClickTheme,
        onClickPackager,
        onLogOut,
        onOpenRegistration,
        onToggleLoginOpen,
        onActivateCostumesTab,
        onActivateSoundsTab,
        onActivateVariablesTab,
        onActivateFilesTab,
        onActivateTab,
        onClickLogo,
        onExtensionButtonClick,
        onProjectTelemetryEvent,
        onRequestCloseBackdropLibrary,
        onRequestCloseCostumeLibrary,
        onRequestCloseTelemetryModal,
        onSeeCommunity,
        onShare,
        onShowPrivacyPolicy,
        onStartSelectingFileUpload,
        onStartFolderUpload,
        onTelemetryModalCancel,
        onTelemetryModalOptIn,
        onTelemetryModalOptOut,
        showComingSoon,
        soundsTabVisible,
        variablesTabVisible,
        filesTabVisible,
        stageSizeMode,
        targetIsStage,
        telemetryModalVisible,
        tipsLibraryVisible,
        usernameModalVisible,
        settingsModalVisible,
        customExtensionModalVisible,
        fontsModalVisible,
        isPlayground,
        vm,
        ...componentProps
    } = omit(props, 'dispatch');
    if (children) {
        return <Box {...componentProps}>{children}</Box>;
    }

    const tabClassNames = {
        tabs: styles.tabs,
        tab: classNames(tabStyles.reactTabsTab, styles.tab),
        tabList: classNames(tabStyles.reactTabsTabList, styles.tabList),
        tabPanel: classNames(tabStyles.reactTabsTabPanel, styles.tabPanel),
        tabPanelSelected: classNames(tabStyles.reactTabsTabPanelSelected, styles.isSelected),
        tabSelected: classNames(tabStyles.reactTabsTabSelected, styles.isSelected)
    };

    // We can't move this into it's own component or it'll break the selected tab styles & disable switching to the code tab
    // Moving the whole TabList element will also break the code panel from resizing properly
    const getTabOrder = () => {
        const tabOrderStr = localStorage.getItem('pm:taborder') || '["code", "costume", "sound"]';
        const tabOrder = safeJSONParse(tabOrderStr, [], true);

        return tabOrder;
    };
    const tabOrder = getTabOrder();
    
    const ContextMenuWrapTab = ({ children, ...props }) => {
        const {tabId} = props;
        const disabled = tabId === 'code';

        return (<><ContextMenuTrigger disable={disabled} id={`remove-editor-tab-${tabId}`}>
                {children}
            </ContextMenuTrigger>
            {ReactDOM.createPortal(<ContextMenu id={`remove-editor-tab-${tabId}`}>
                <DangerousMenuItem onClick={() => removeTabFromEditor(tabId)}>
                    <FormattedMessage
                        defaultMessage="delete"
                        description="Menu item to delete in the right click menu"
                        id="gui.spriteSelectorItem.contextMenuDelete"
                    />
                </DangerousMenuItem>
            </ContextMenu>, document.body)}
        </>);
    };

    // currently each tab can decide whether or not its hidden, remove this once rearranging tabs is supported
    const codeTab = (<Tab className={classNames(tabClassNames.tab, tabOrder.includes('code') ? null : styles.tabDisabled)}>
            <ContextMenuWrapTab tabId="code">
                <CodeIcon />
                <FormattedMessage
                    defaultMessage="Code"
                    description="Button to get to the code panel"
                    id="gui.gui.codeTab"
                />
            </ContextMenuWrapTab>
        </Tab>);
    const costumesTab = (<Tab className={classNames(tabClassNames.tab, tabOrder.includes('costume') ? null : styles.tabDisabled)} onClick={onActivateCostumesTab}>
            <ContextMenuWrapTab tabId="costume">
                <CostumesIcon />
                {targetIsStage ? (
                    <FormattedMessage
                        defaultMessage="Backdrops"
                        description="Button to get to the backdrops panel"
                        id="gui.gui.backdropsTab"
                    />
                ) : (
                    <FormattedMessage
                        defaultMessage="Costumes"
                        description="Button to get to the costumes panel"
                        id="gui.gui.costumesTab"
                    />
                )}
            </ContextMenuWrapTab>
        </Tab>);
    const soundsTab = (<Tab className={classNames(tabClassNames.tab, tabOrder.includes('sound') ? null : styles.tabDisabled)} onClick={onActivateSoundsTab}>
            <ContextMenuWrapTab tabId="sound">
                <SoundsIcon />
                <FormattedMessage
                    defaultMessage="Sounds"
                    description="Button to get to the sounds panel"
                    id="gui.gui.soundsTab"
                />
            </ContextMenuWrapTab>
        </Tab>);
    const variablesTab = (<Tab className={classNames(tabClassNames.tab, tabOrder.includes('variable') ? null : styles.tabDisabled)} onClick={onActivateVariablesTab}>
            <ContextMenuWrapTab tabId="variable">
                <VariablesIcon />
                <FormattedMessage
                    defaultMessage="Variables"
                    description="Button to get to the variables panel"
                    id="gui.gui.variablesTab"
                />
            </ContextMenuWrapTab>
        </Tab>);
    const filesTab = (<Tab className={classNames(tabClassNames.tab, tabOrder.includes('file') ? null : styles.tabDisabled)} onClick={onActivateFilesTab}>
            <ContextMenuWrapTab tabId="file">
                <FilesIcon />
                <FormattedMessage
                    defaultMessage="Files"
                    description="Button to get to the files panel"
                    id="gui.gui.filesTab"
                />
            </ContextMenuWrapTab>
        </Tab>);

    const tabPairs = {
        code: codeTab,
        costume: costumesTab,
        sound: soundsTab,
        variable: variablesTab,
        // file: filesTab,
    };

    // For now, rearranging tabs is not supported
    const organizedTabs = Object.values(tabPairs);
    // const organizedTabs = (() => {
    //     const enabledTabs = [];
    //     // Either add in rearranged order
    //     // for (const tabId of tabOrder) {
    //     //     enabledTabs.push(tabPairs[tabId] || codeTab)
    //     // }
    //     // or we can add tabs in order of table inclusion
    //     // for (const key in tabPairs) {
    //     //     const tab = tabPairs[key];
    //     //     if (tabOrder.includes(key)) {
    //     //         enabledTabs.push(tab);
    //     //     }
    //     // }

    //     return enabledTabs;
    // })();
    const addTabButtonDisabled = tabOrder.length >= Object.keys(tabPairs).length;

    const addTabToEditor = (tabId) => {
        const tabOrder = getTabOrder();
        tabOrder.push(tabId);
        localStorage.setItem('pm:taborder', JSON.stringify(tabOrder));

        const tabKeys = Object.keys(tabPairs);
        const tabIndex = tabKeys.indexOf(tabId);
        if (tabIndex === -1) {
            return onActivateTab(0);
        }

        onActivateTab(tabIndex);
    };
    const removeTabFromEditor = (tabId) => {
        setTimeout(() => { // sometimes clicking delete will switch to the deleted tab
            const tabOrder = getTabOrder();
            const idx = tabOrder.indexOf(tabId);
            if (idx === -1) return;
    
            tabOrder.splice(idx, 1);
            localStorage.setItem('pm:taborder', JSON.stringify(tabOrder));

            if (tabId !== 'code') {
                return onActivateTab(0);
            }

            const tabKeys = Object.keys(tabPairs);
            const firstTab = tabOrder[0];
            const firstTabIdx = tabKeys.indexOf(firstTab);
            
            if (firstTabIdx !== -1) {
                onActivateTab(firstTabIdx);
            }
        });
    };

    const minWidth = layout.fullSizeMinWidth + Math.max(0, customStageSize.width - layout.referenceWidth);
    return (<MediaQuery minWidth={minWidth}>{isFullSize => {
        const stageSize = resolveStageSize(stageSizeMode, isFullSize);

        const alwaysEnabledModals = (
            <React.Fragment>
                <TWSecurityManager />
                <TWRestorePointManager />
                {usernameModalVisible && <TWUsernameModal />}
                {settingsModalVisible && <TWSettingsModal />}
                {customExtensionModalVisible && <TWCustomExtensionModal />}
                {fontsModalVisible && <TWFontsModal />}
                <PMExtensionModals vm={vm} />
            </React.Fragment>
        );

        return isPlayerOnly ? (
            <React.Fragment>
                {/* TW: When the window is fullscreen, use an element to display the background color */}
                {/* The default color for transparency is inconsistent between browsers and there isn't an existing */}
                {/* element for us to style that fills the entire screen. */}
                {isWindowFullScreen ? (
                    <div
                        className={styles.fullscreenBackground}
                        style={{
                            backgroundColor: fullscreenBackgroundColor
                        }}
                    />
                ) : null}
                <StageWrapper
                    isFullScreen={isFullScreen}
                    isEmbedded={isEmbedded}
                    isRendererSupported={isRendererSupported()}
                    isRtl={isRtl}
                    loading={loading}
                    stageSize={STAGE_SIZE_MODES.large}
                    vm={vm}
                >
                    {alertsVisible ? (
                        <Alerts className={styles.alertsContainer} />
                    ) : null}
                </StageWrapper>
                {alwaysEnabledModals}
            </React.Fragment>
        ) : (
            <Box
                className={styles.pageWrapper}
                dir={isRtl ? 'rtl' : 'ltr'}
                {...componentProps}
            >
                {alwaysEnabledModals}
                {telemetryModalVisible ? (
                    <TelemetryModal
                        isRtl={isRtl}
                        isTelemetryEnabled={isTelemetryEnabled}
                        onCancel={onTelemetryModalCancel}
                        onOptIn={onTelemetryModalOptIn}
                        onOptOut={onTelemetryModalOptOut}
                        onRequestClose={onRequestCloseTelemetryModal}
                        onShowPrivacyPolicy={onShowPrivacyPolicy}
                    />
                ) : null}
                {loading ? (
                    <Loader isFullScreen />
                ) : null}
                {isCreating ? (
                    <Loader
                        isFullScreen
                        messageId={isPlayground ? "gui.loader.playground" : "gui.loader.creating"}
                    />
                ) : null}
                {isBrowserSupported() ? null : (
                    <BrowserModal isRtl={isRtl} />
                )}
                {tipsLibraryVisible ? (
                    <TipsLibrary />
                ) : null}
                {cardsVisible ? (
                    <Cards />
                ) : null}
                {alertsVisible ? (
                    <Alerts className={styles.alertsContainer} />
                ) : null}
                {connectionModalVisible ? (
                    <ConnectionModal
                        vm={vm}
                    />
                ) : null}
                {costumeLibraryVisible ? (
                    <CostumeLibrary
                        vm={vm}
                        onRequestClose={onRequestCloseCostumeLibrary}
                    />
                ) : null}
                {backdropLibraryVisible ? (
                    <BackdropLibrary
                        vm={vm}
                        onRequestClose={onRequestCloseBackdropLibrary}
                    />
                ) : null}
                {(!isPlayground) ? (
                    <MenuBar
                        accountNavOpen={accountNavOpen}
                        authorId={authorId}
                        authorThumbnailUrl={authorThumbnailUrl}
                        authorUsername={authorUsername}
                        canChangeLanguage={canChangeLanguage}
                        canCreateCopy={canCreateCopy}
                        canCreateNew={canCreateNew}
                        canEditTitle={canEditTitle}
                        canManageFiles={canManageFiles}
                        canRemix={canRemix}
                        canSave={canSave}
                        canShare={canShare}
                        className={styles.menuBarPosition}
                        enableCommunity={enableCommunity}
                        isDirectoryPickerSupported={!!window.showDirectoryPicker}
                        isShared={isShared}
                        logo={logo}
                        renderLogin={renderLogin}
                        showComingSoon={showComingSoon}
                        onClickAbout={onClickAbout}
                        onClickAccountNav={onClickAccountNav}
                        onClickAddonSettings={onClickAddonSettings}
                        onClickNewWindow={onClickNewWindow}
                        onClickTheme={onClickTheme}
                        onClickPackager={onClickPackager}
                        onClickLogo={onClickLogo}
                        onCloseAccountNav={onCloseAccountNav}
                        onLogOut={onLogOut}
                        onOpenRegistration={onOpenRegistration}
                        onProjectTelemetryEvent={onProjectTelemetryEvent}
                        onSeeCommunity={onSeeCommunity}
                        onShare={onShare}
                        onStartSelectingFileUpload={onStartSelectingFileUpload}
                        onStartFolderUpload={onStartFolderUpload}
                        onToggleLoginOpen={onToggleLoginOpen}
                    />
                ) : null}
                <Box className={classNames(styles.bodyWrapper, isPlayground ? styles.bodyWrapperPlayground : null)}>
                    <Box className={styles.flexWrapper}>
                        <Box className={styles.editorWrapper}>
                            <Tabs
                                forceRenderTabPanel
                                className={tabClassNames.tabs}
                                selectedIndex={activeTabIndex}
                                selectedTabClassName={tabClassNames.tabSelected}
                                selectedTabPanelClassName={tabClassNames.tabPanelSelected}
                                onSelect={onActivateTab}
                            >
                                <TabList className={tabClassNames.tabList}>
                                    {organizedTabs}

                                    <ContextMenuTrigger
                                        disable={addTabButtonDisabled}
                                        holdToDisplay={0}
                                        id={`add-editor-tab-button`}
                                    >
                                        <button className={classNames(styles.addTabButton, addTabButtonDisabled ? styles.addTabButtonDisabled : null)}>
                                            <PlusIcon />
                                        </button>
                                    </ContextMenuTrigger>
                                    
                                    <ContextMenu id={`add-editor-tab-button`}>
                                        {!tabOrder.includes('code') && <MenuItem onClick={() => addTabToEditor('code')}>
                                            <div className={styles.tabAdditionItem}>
                                                <CodeIcon />
                                                <FormattedMessage
                                                    defaultMessage="Code"
                                                    description="Button to get to the code panel"
                                                    id="gui.gui.codeTab"
                                                />
                                            </div>
                                        </MenuItem>}
                                        {!tabOrder.includes('costume') && <MenuItem onClick={() => addTabToEditor('costume')}>
                                            <div className={styles.tabAdditionItem}>
                                                <CostumesIcon />
                                                <FormattedMessage
                                                    defaultMessage="Costumes"
                                                    description="Button to get to the costumes panel"
                                                    id="gui.gui.costumesTab"
                                                />
                                            </div>
                                        </MenuItem>}
                                        {!tabOrder.includes('sound') && <MenuItem onClick={() => addTabToEditor('sound')}>
                                            <div className={styles.tabAdditionItem}>
                                                <SoundsIcon />
                                                <FormattedMessage
                                                    defaultMessage="Sounds"
                                                    description="Button to get to the sounds panel"
                                                    id="gui.gui.soundsTab"
                                                />
                                            </div>
                                        </MenuItem>}
                                        {!tabOrder.includes('variable') && <MenuItem onClick={() => addTabToEditor('variable')}>
                                            <div className={styles.tabAdditionItem}>
                                                <VariablesIcon />
                                                <FormattedMessage
                                                    defaultMessage="Variables"
                                                    description="Button to get to the variables panel"
                                                    id="gui.gui.variablesTab"
                                                />
                                            </div>
                                        </MenuItem>}
                                        {/* {!tabOrder.includes('file') && <MenuItem onClick={() => addTabToEditor('file')}>
                                            <div className={styles.tabAdditionItem}>
                                                <FilesIcon />
                                                <FormattedMessage
                                                    defaultMessage="Files"
                                                    description="Button to get to the files panel"
                                                    id="gui.gui.filesTab"
                                                />
                                            </div>
                                        </MenuItem>} */}
                                    </ContextMenu>

                                    <div id="sa_addons_after_add_tab_anchor" />
                                </TabList>
                                <TabPanel className={tabClassNames.tabPanel}>
                                    <Box className={styles.blocksWrapper}>
                                        <Blocks
                                            canUseCloud={canUseCloud}
                                            grow={1}
                                            isVisible={blocksTabVisible}
                                            options={{
                                                media: `${basePath}static/blocks-media/`
                                            }}
                                            stageSize={stageSize}
                                            vm={vm}
                                        />
                                    </Box>
                                    <Box className={styles.extensionButtonContainer}>
                                        <button
                                            className={styles.extensionButton}
                                            title={intl.formatMessage(messages.addExtension)}
                                            onClick={onExtensionButtonClick}
                                        >
                                            <AddExtensionIcon className={styles.extensionButtonIcon} />
                                        </button>
                                    </Box>
                                    <Box className={styles.watermark}>
                                        <Watermark />
                                    </Box>
                                </TabPanel>
                                <TabPanel className={tabClassNames.tabPanel}>
                                    {costumesTabVisible ? <CostumeTab
                                        vm={vm}
                                        isDark={isDark}
                                    /> : null}
                                </TabPanel>
                                <TabPanel className={tabClassNames.tabPanel}>
                                    {soundsTabVisible ? <SoundTab vm={vm} /> : null}
                                </TabPanel>
                                <TabPanel className={tabClassNames.tabPanel}>
                                    {variablesTabVisible ? <VariablesTab vm={vm} /> : null}
                                </TabPanel>
                            </Tabs>
                            {backpackVisible ? (
                                <Backpack host={backpackHost} />
                            ) : null}
                        </Box>

                        <Box className={classNames(styles.stageAndTargetWrapper, styles[stageSize])}>
                            <StageWrapper
                                isFullScreen={isFullScreen}
                                isRendererSupported={isRendererSupported()}
                                isRtl={isRtl}
                                stageSize={stageSize}
                                vm={vm}
                            />
                            <Box className={styles.targetWrapper}>
                                <TargetPane
                                    stageSize={stageSize}
                                    vm={vm}
                                />
                            </Box>
                        </Box>
                    </Box>
                </Box>
                <DragLayer />
            </Box>
        );
    }}</MediaQuery>);
};

GUIComponent.propTypes = {
    accountNavOpen: PropTypes.bool,
    activeTabIndex: PropTypes.number,
    authorId: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), // can be false
    authorThumbnailUrl: PropTypes.string,
    authorUsername: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), // can be false
    backdropLibraryVisible: PropTypes.bool,
    backpackHost: PropTypes.string,
    backpackVisible: PropTypes.bool,
    basePath: PropTypes.string,
    blocksTabVisible: PropTypes.bool,
    canChangeLanguage: PropTypes.bool,
    canCreateCopy: PropTypes.bool,
    canCreateNew: PropTypes.bool,
    canEditTitle: PropTypes.bool,
    canManageFiles: PropTypes.bool,
    canRemix: PropTypes.bool,
    canSave: PropTypes.bool,
    canShare: PropTypes.bool,
    canUseCloud: PropTypes.bool,
    cardsVisible: PropTypes.bool,
    children: PropTypes.node,
    costumeLibraryVisible: PropTypes.bool,
    costumesTabVisible: PropTypes.bool,
    customStageSize: PropTypes.shape({
        width: PropTypes.number,
        height: PropTypes.number
    }),
    enableCommunity: PropTypes.bool,
    intl: intlShape.isRequired,
    isCreating: PropTypes.bool,
    isDark: PropTypes.bool,
    isEmbedded: PropTypes.bool,
    isFullScreen: PropTypes.bool,
    isPlayerOnly: PropTypes.bool,
    isRtl: PropTypes.bool,
    isShared: PropTypes.bool,
    isWindowFullScreen: PropTypes.bool,
    loading: PropTypes.bool,
    logo: PropTypes.string,
    onActivateCostumesTab: PropTypes.func,
    onActivateSoundsTab: PropTypes.func,
    onActivateVariablesTab: PropTypes.func,
    onActivateFilesTab: PropTypes.func,
    onActivateTab: PropTypes.func,
    onClickAccountNav: PropTypes.func,
    onClickAddonSettings: PropTypes.func,
    onClickNewWindow: PropTypes.func,
    onClickTheme: PropTypes.func,
    onClickPackager: PropTypes.func,
    onClickLogo: PropTypes.func,
    onCloseAccountNav: PropTypes.func,
    onExtensionButtonClick: PropTypes.func,
    onLogOut: PropTypes.func,
    onOpenRegistration: PropTypes.func,
    onRequestCloseBackdropLibrary: PropTypes.func,
    onRequestCloseCostumeLibrary: PropTypes.func,
    onRequestCloseTelemetryModal: PropTypes.func,
    onSeeCommunity: PropTypes.func,
    onShare: PropTypes.func,
    onShowPrivacyPolicy: PropTypes.func,
    onStartSelectingFileUpload: PropTypes.func,
    onStartFolderUpload: PropTypes.func,
    onTabSelect: PropTypes.func,
    onTelemetryModalCancel: PropTypes.func,
    onTelemetryModalOptIn: PropTypes.func,
    onTelemetryModalOptOut: PropTypes.func,
    onToggleLoginOpen: PropTypes.func,
    renderLogin: PropTypes.func,
    showComingSoon: PropTypes.bool,
    soundsTabVisible: PropTypes.bool,
    variablesTabVisible: PropTypes.bool,
    filesTabVisible: PropTypes.bool,
    stageSizeMode: PropTypes.oneOf(Object.keys(STAGE_SIZE_MODES)),
    targetIsStage: PropTypes.bool,
    telemetryModalVisible: PropTypes.bool,
    tipsLibraryVisible: PropTypes.bool,
    usernameModalVisible: PropTypes.bool,
    settingsModalVisible: PropTypes.bool,
    customExtensionModalVisible: PropTypes.bool,
    fontsModalVisible: PropTypes.bool,
    vm: PropTypes.instanceOf(VM).isRequired
};
GUIComponent.defaultProps = {
    backpackHost: null,
    backpackVisible: false,
    basePath: './',
    canChangeLanguage: true,
    canCreateNew: false,
    canEditTitle: false,
    canManageFiles: true,
    canRemix: false,
    canSave: false,
    canCreateCopy: false,
    canShare: false,
    canUseCloud: false,
    enableCommunity: false,
    isCreating: false,
    isShared: false,
    loading: false,
    showComingSoon: false,
    stageSizeMode: STAGE_SIZE_MODES.large
};

const mapStateToProps = state => ({
    customStageSize: state.scratchGui.customStageSize,
    isWindowFullScreen: state.scratchGui.tw.isWindowFullScreen,
    // This is the button's mode, as opposed to the actual current state
    stageSizeMode: state.scratchGui.stageSize.stageSize
});

export default injectIntl(connect(
    mapStateToProps
)(GUIComponent));
