import Tool from "./tool";
import { graph, state, renderer } from "../editor";
import * as Graph from "../graph";
import jquery from "jquery";
import ToolMenu from "./menus/toolmenu";

/**
 * Only one instance of this should exist, since box-delete has to work on a global scale.
 */
 var deleteToolInstance = undefined; // Used for box delete
export default class DeleteTool extends Tool {
    constructor(key) {
        super("Delete", "delete", key, new ToolMenu());
        this.setupBoxSelect();
        this.isActive = false;

        if (deleteToolInstance === undefined) {
            deleteToolInstance = this;
        }
    }

    onToolActivate() {
        this.isActive = true;
    }

    onToolDeactivate(nextTool) {
        this.isActive = false;
    }

    onBoxSelect(left, bottom, top, right) {
        // Filter out selected nodes
        const hitNodes = [];
        const tl = renderer.screen2GraphCoords(left, top);
        const br = renderer.screen2GraphCoords(right, bottom);
        graph.data[Graph.GRAPH_NODES].forEach((node) => {
            if (
                tl.x < node.x &&
                node.x < br.x &&
                br.y > node.y &&
                node.y > tl.y
            ) {
                hitNodes.push(node);
            }
        });

        // Delete selected items after confirmation
        console.log("DELETE");
        console.log(hitNodes);
    }

    onNodeClick(node) {
        graph.deleteNode(node[Graph.NODE_ID]);
        
        if (state.selectedItem == node) {
            state.setSelectedItem(undefined);
        }
    }

    onLinkClick(link) {
        graph.deleteLink(
            link[Graph.LINK_SOURCE][Graph.NODE_ID],
            link[Graph.LINK_TARGET][Graph.NODE_ID]
        );
        
        if (state.selectedItem == link) {
            state.setSelectedItem(undefined);
        }
    }

    setupBoxSelect() {
        window.addEventListener("load", () => {
            // Source: https://github.com/vasturiano/force-graph/issues/151#issuecomment-735850938

            // forceGraph element is the element provided to the Force Graph Library
            jquery("#2d-graph").on(
                "pointerdown",
                this.boxSelectOnPointerDown
            );
            jquery("#2d-graph").on(
                "pointermove",
                this.boxSelectOnPointerMove
            );
            jquery("#2d-graph").on(
                "pointerup",
                this.boxSelectOnPointerUp
            );
        });
    }

    boxSelectOnPointerDown(e) {
        // Only do anything if delete tool is also active
        if (deleteToolInstance === undefined || deleteToolInstance.isActive == false) {
            return;
        }

        if (!e.shiftKey) {
            return;
        }

        e.preventDefault();
        this.boxSelect = document.createElement("div");
        this.boxSelect.id = "box-select";
        this.boxSelect.style.left = e.offsetX.toString() + "px";
        this.boxSelect.style.top = e.offsetY.toString() + "px";
        this.boxSelectStart = {
            x: e.offsetX,
            y: e.offsetY,
        };
        // app element is the element just above the forceGraph element.
        jquery("#box-select-layer").append(this.boxSelect);
    }

    boxSelectOnPointerMove(e) {
        if (!this.boxSelect) {
            return;
        }

        if (!e.shiftKey) {
            this.boxSelect.remove();
            return;
        }

        e.preventDefault();
        if (e.offsetX < this.boxSelectStart.x) {
            this.boxSelect.style.left = e.offsetX.toString() + "px";
            this.boxSelect.style.width =
                (this.boxSelectStart.x - e.offsetX).toString() + "px";
        } else {
            this.boxSelect.style.left = this.boxSelectStart.x.toString() + "px";
            this.boxSelect.style.width =
                (e.offsetX - this.boxSelectStart.x).toString() + "px";
        }
        if (e.offsetY < this.boxSelectStart.y) {
            this.boxSelect.style.top = e.offsetY.toString() + "px";
            this.boxSelect.style.height =
                (this.boxSelectStart.y - e.offsetY).toString() + "px";
        } else {
            this.boxSelect.style.top = this.boxSelectStart.y.toString() + "px";
            this.boxSelect.style.height =
                (e.offsetY - this.boxSelectStart.y).toString() + "px";
        }
    }

    boxSelectOnPointerUp(e) {
        if (!this.boxSelect) {
            return;
        }

        if (!e.shiftKey) {
            this.boxSelect.remove();
            return;
        }

        e.preventDefault();
        let left, bottom, top, right;
        if (e.offsetX < this.boxSelectStart.x) {
            left = e.offsetX;
            right = this.boxSelectStart.x;
        } else {
            left = this.boxSelectStart.x;
            right = e.offsetX;
        }
        if (e.offsetY < this.boxSelectStart.y) {
            top = e.offsetY;
            bottom = this.boxSelectStart.y;
        } else {
            top = this.boxSelectStart.y;
            bottom = e.offsetY;
        }
        this.boxSelect.remove();
        deleteToolInstance.onBoxSelect(left, bottom, top, right);
    }
}