import * as React from "react";
import {SimpleGrid, Text, Title, Stack, Center, Group, Space, Image} from "@mantine/core";

import {PrimitiveRegistry} from "../onion/primitive_delta";
import {mockUuid} from "../onion/test_helpers";

import {newVersionedModel, VersionedModelState} from "./versioned_model";
import {newManualRenderer, ManualRendererProps} from "./manual_renderer";
import {makeInfoHoverCardIcon} from "./help_icons";
import {Actionblock, Resultblock} from "./blocks";
import editor from './assets/editor.svg';

export const demo_Editor_description =
    <>
        <Title order={4}>
            Rountangle Editor
        </Title>
        <Text>
            Next to this text you can see three columns <strong>Rountangle Editor</strong>, <strong>Deltas</strong>,
            and <strong>State Graph</strong>. In the Rountangle Editor, you can create (unnamed) rountangles by
            right-clicking on the grey area (see also the small info in the upper right corner
            of each canvas). You can move these rountangle around and resize them.
        </Text>
        <Text>
            In this demo, the editable state graph of the "Primitive Delta"-demo is replaced by a Rountangle Editor.
            Again, any action in the Rountangle Editor results in a set of deltas (shown at the center) that are applied to the (empty) state graph (on the right).
            Note that this state graph is no longer (directly) editable. The current model state is visualized in the Rountangle Editor from which the user interaction originated.
        </Text>
        <Text>
            In technical terms, the Rountangle Editor is a <em>projectional editor</em> for the state graph (on the right).
        </Text>
        <Image src={editor}/>
        <Actionblock>
            1. Create a rountangle by right-clicking the grey area in the left column!
        </Actionblock>
        <Resultblock>
            In the center column, one composite delta (or L1 delta) "createRountangle" was created.
        </Resultblock>
        <Resultblock>
            In the second tab "Deltas (L0)" of the center column, you can see the primitive deltas a "createRountangle" composite delta consists of.
        </Resultblock>
        <Resultblock>
            The result of an application of all primitive deltas to an empty initial state is shown in the third column "State Graph".
        </Resultblock>
        <Resultblock>
            The ID<sub>CS</sub> in each rountangle indicates the node ID of the state graph that is responsible for the rendering of this rountangle.
        </Resultblock>
        <Actionblock>
            2. Move your created rountangle!
        </Actionblock>
        <Resultblock>
            For each movement a new "moveRountangle" composite delta is created that depends on the previous one.
        </Resultblock>
        <Resultblock>
            On the level of primitive deltas (L0), you can observe that only the "x" and "y" edges are updated (UPD).
        </Resultblock>
        <Resultblock>
            On the State Graph, only the "x" and "y" edges are updated to point to other values.
        </Resultblock>
        <Actionblock>
            3. Switch to the "History" tab in the "Deltas" column and trigger some "Undo" operations (below the Rountangle Editor)!
        </Actionblock>
        <Resultblock>
            The currently active version has a bold border. All versions are kept.
        </Resultblock>
        <Resultblock>
            In the "Delta (L1)" and "Delta (L0)" tabs, the deltas corresponding to the current version are also highlighted.
        </Resultblock>
        <Space h="5px"/>
        <Text>
            Feel free to play around with the editor and watch the changes in the other views.
        </Text>
    </>;

export function getDemoEditor() {
    const generateUUID = mockUuid();
    const primitiveRegistry = new PrimitiveRegistry();

    const commonStuff = {generateUUID, primitiveRegistry};

    const cs = newVersionedModel({readonly: true, ...commonStuff});

    const {getModalManualRenderer} = newManualRenderer(commonStuff);

    // returns functional react component
    return function () {
        const [csState, setCsState] = React.useState<VersionedModelState>(cs.initialState);

        const [manualRendererState, setManualRendererState] = React.useState<null | ManualRendererProps>(null);

        const csReducer = cs.getReducer(setCsState);

        const csComponents = cs.getReactComponents(csState, {
            onUserEdit: (deltas, description) => {
                const newVersion = csReducer.createAndGotoNewVersion(deltas, description);
            },
            onUndoClicked: csReducer.undo,
            onRedoClicked: csReducer.redo,
            onVersionClicked: csReducer.gotoVersion,
        });

        const deltaTabs = ["dependencyL1", "dependencyL0", "history"];

        const undoButtonHelpText = "Use the Undo/Redo buttons or the History panel to navigate to any version.";

        return (<div style={{minWidth: 1300}}>
            {getModalManualRenderer(manualRendererState)}

            <SimpleGrid cols={3}>
                <div>
                    <Group position="apart">
                        <Title order={4}>Rountangle Editor</Title>
                    </Group>
                    <Space h="48px"/>
                    <Stack>
                        {csComponents.rountangleEditor}
                        <Center>
                            {csComponents.undoRedoButtons}
                            <Space w="sm"/>
                            {makeInfoHoverCardIcon(undoButtonHelpText)}
                        </Center>
                    </Stack>
                </div>
                <div>
                    <Group position="center">
                        <Title order={4}>Deltas</Title>
                    </Group>
                    <Space h="sm"/>
                    {csComponents.makeTabs("dependencyL1", deltaTabs)}
                </div>
                <div>
                    <Title order={4}>State Graph</Title>
                    <Space h="48px"/>
                    {csComponents.graphStateComponent}
                </div>
            </SimpleGrid>
        </div>);
    }
}
