import { State } from "./state";
import { loadGraphJson } from "../../datasets";
import ForceGraph from "force-graph";
import * as Interactions from "./interactions";
import { setSpace, SPACE } from "../../config";
import { Graph } from "./structures/graph/graph";

export let state: any = undefined;
export let graph: Graph = undefined;
export let renderer: any;

window.onload = function () {
    // Only execute, if corresponding dom is present
    if (document.getElementById("ks-editor") === null) {
        return;
    }

    document.onkeydown = (e) => state.onKeyDown(e);
    document.onkeyup = (e) => state.onKeyUp(e);

    Interactions.initInteractions();

    loadSpace(SPACE);
};

export function loadSpace(spaceId: string) {
    if (state !== undefined && spaceId === SPACE) {
        return;
    }
    setSpace(spaceId);

    return loadGraphJson(SPACE).then((graphConfig) => {
        state = new State();
        graph = Graph.parse(graphConfig);
        load();

        // graph.restartSimulation();
    });
}

function extractPositions(event: any) {
    return {
        graph: renderer.screen2GraphCoords(event.layerX, event.layerY),
        window: { x: event.clientX, y: event.clientY },
    };
}

function load() {
    const graphContainer = document.getElementById("2d-graph");
    const width = graphContainer.offsetWidth;

    renderer = ForceGraph()(graphContainer)
        .height(600)
        .width(width)
        .graphData(graph.data)
        .nodeLabel("label")
        .linkColor((link) => state.linkColor(link))
        .nodeColor((node) => state.nodeColor(node))
        .onNodeClick((node) => state.onNodeClick(node))
        .onNodeDragEnd((node, translate) =>
            state.onNodeDragEnd(node, translate)
        )
        .autoPauseRedraw(false) // keep redrawing after engine has stopped
        .linkWidth((link) => state.linkWidth(link))
        .linkDirectionalParticles(state.linkDirectionalParticles())
        .linkDirectionalParticleWidth((link) =>
            state.linkDirectionalParticleWidth(link)
        )
        .onBackgroundClick((event) =>
            state.onBackgroundClick(event, extractPositions(event))
        )
        .nodeCanvasObjectMode((node) => state.nodeCanvasObjectMode(node))
        .nodeCanvasObject((node, ctx, globalScale) =>
            state.nodeCanvasObject(node, ctx, globalScale)
        )
        .linkCanvasObjectMode((link) => state.linkCanvasObjectMode(link))
        .linkCanvasObject((link, ctx, globalScale) =>
            state.linkCanvasObject(link, ctx, globalScale)
        )
        .onLinkClick((link) => state.onLinkClick(link));

    graph.onChangeCallbacks.push((data) => {
        renderer.graphData(data);
    });
}