import { Node, InputConnector, OutputConnector, Connection, NodeEditor } from "../index";

/**
 * A connector is the circle, and the corresponding input field in the node.
 * All inputs and outputs of the node are extending this class.
 */
export class Connector{
    
    /**
     * Node wich has this connector
     */
    protected node: Node;

    /**
     * Element in the dom wich represents this connector visually
     */
    protected element: HTMLElement;

    /**
     * Type of the connector. it defines the color of the input as well.
     */
    protected type: string|null;

    /**
     * The technical name of the input
     */
    protected key: string;
    protected color: string;
    
    /**
     * Creates a new connector
     * @param node Node to connect
     * @param key Name of the input
     * @param data Extra doto for the input
     */
    constructor(node: Node, key: string, data: Record<string, any>){
        this.key = key;
        this.type = data.type || data;
        this.node = node;
        this.color = NodeEditor.createColorFromString(data.type ?? data);
    }
    
    /**
     * Returns the color of the connector in a hex string.
     */
    public getColor(): string{
        return this.color;
    }

    /**
     * Returns the type of the connector.
     */
    public getType(): string{
        return this.type;
    }
    
    /**
     * Returns the node wich has this connector.
     */
    public getNode(): Node{
        return this.node;
    }

    /** 
     * Returns the key of the connector which is the name of the input.
     */
    public getKey(): string{
        return this.key;
    }
         
    /**
     * Handles the mouse up event, 
     * if somehting is released while hovering over this.
     * @param event Mouse event
     */
    protected handleMouseUp(event: MouseEvent){
        let activeConnection = this.getNode().getEditor().getActiveConnection();
        if(!activeConnection){
            return;
        }
        if(this instanceof OutputConnector && activeConnection.getTarget()){
            if(activeConnection.getTarget().getNode() !== this.getNode()){
                activeConnection.setSource(this);
                activeConnection.update();
                this.getNode().getEditor().setActiveConnection(null);
            }
        }
        if(this instanceof InputConnector && activeConnection.getSource()){
            if(activeConnection.getSource().getNode() !== this.getNode()){
                activeConnection.setTarget(this);
                activeConnection.update();
                this.getNode().getEditor().setActiveConnection(null);
            }
        }
    }

    /**
     * Add a connection, which visually represented as a line.
     * @param conncetion The connection to join.
     */
    public addConnection(conncetion: Connection){ }

    /**
     * Removes a connection, which visually represented as a line.
     * @param conncetion The connection to remove.
     */
    public removeConnection(connection: Connection){ }

    /**
     * Removes self from the dom, and removes all connections as well.
     */
    public remove(){ }

    /**
     * Returns the test data for this connector only.
     */
    public getTestData(){ }

    /**
     * Updates the end of the Connection, visually the end of the line.
     */
    public update(){ }
}