var state;
var graph;
var graphObj;

window.onload = function () {
    fetch(JSON_CONFIG)
        .then((r) => {
            return r.json();
        })
        .then((graphConfig) => {
            state = new State();
            graph = new Graph(graphConfig);
            load();

            // Deactivate physics after a short delay
            setTimeout(() => {
                graph.stopPhysics();
                graph.storeCurrentData("Physics stopped");
            }, STOP_PHYSICS_DELAY);
        });
};

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

function downloadJson() {
    // TODO: Clean up
    // source: https://stackoverflow.com/a/42883108/7376120
    var jsonBlob = new Blob([JSON.stringify(getOnlygraph.data())], {
        type: "application/json;charset=utf-8",
    });
    var link = window.URL.createObjectURL(jsonBlob);
    window.location = link;
}

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

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

    graphObj = ForceGraph()(graphContainer)
        .height(600)
        .width(width)
        .graphData(graph.data)
        .nodeLabel(NODE_LABEL)
        .nodeAutoColorBy(NODE_GROUP)
        .onNodeClick((node) => state.onNodeClick(node))
        .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) => state.nodeCanvasObject(node, ctx))
        .onLinkClick((link) => state.onLinkClick(link));

    graph.onChangeCallbacks.push((data) => {
        graphObj.cooldownTicks(0);
        graphObj.graphData(data);
    });
}