package at.fos.ermodel.gui;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;

import java.io.Serial;

public abstract class Graphic_LINE_Elem
        extends Graphic_Main_Elem {
    @Serial
    private static final long serialVersionUID = 1L;
    private final byte lineConnectedWithPointAtStart;
    private final byte lineConnectedWithPointAtEnd;
    protected String minimum = "0";
    protected String maximum = "n";
    private double xEnd;
    private double yEnd;
    private Graphic_Figure_Elem connectedWithStart;
    private Graphic_Figure_Elem connectedWithEnd;


    public Graphic_LINE_Elem(GraphicsContext gc, double x, double y, double xEnd, double yEnd, byte lineConnectedWithPointAtStart, byte lineConnectedWithPointAtEnd, Graphic_Figure_Elem elemStart, Graphic_Figure_Elem elemEnd, long elementID) {
        super(gc, elementID);

        this.xPos = x;
        this.yPos = y;
        this.lineConnectedWithPointAtStart = lineConnectedWithPointAtStart;
        this.connectedWithStart = elemStart;
        this.xEnd = xEnd;
        this.yEnd = yEnd;
        this.lineConnectedWithPointAtEnd = lineConnectedWithPointAtEnd;
        this.connectedWithEnd = elemEnd;
        this.name = "";

        if (this instanceof Graphic_LINE_RSID_ESWEAK_Elem) {
            this.minimum = "1";
            this.maximum = "1";
        }
    }


    protected void changeMinMax(String minimum, String maximum) {
        this.minimum = minimum;
        this.maximum = maximum;
        if (minimum == null) this.minimum = getDefaultMinimum();
        if (maximum == null) this.minimum = getDefaultMaximum();
        dsfsdfsfd();
        safdsadasds32432456456();
    }


    private void drawArrow(Color c, double x1, double y1, double x2, double y2) {
        this.gc.setStroke(c);

        double dx = x2 - x1, dy = y2 - y1;
        double angle = Math.atan2(dy, dx);
        double len = Math.sqrt(dx * dx + dy * dy);


        Affine oldTransform = this.gc.getTransform();

        Translate translate = Transform.translate(x1, y1);
        Transform transform = translate.createConcatenation(Transform.rotate(Math.toDegrees(angle), 0.0D, 0.0D));
        this.gc.setTransform(new Affine(transform));


        this.gc.setFill(C2.ERMBackgroundColor);


        this.gc.strokePolygon(new double[]{len, len - 8.0D, len - 8.0D
        }, new double[]{0.0D, -8.0D, 8.0D
        }, 3);


        this.gc.setTransform(oldTransform);
    }


    protected void dsfdsfds6787686(Color c) {
        if (!this.isVisible)
            return;
        if (this.name == null) this.name = "";

        this.gc.beginPath();
        this.gc.setStroke(c);
        this.gc.strokeLine(this.xPos, this.yPos, this.xEnd, this.yEnd);

        if (this instanceof Graphic_LINE_RSISAG_ES_Elem) {

            if (this.connectedWithStart instanceof Graphic_ES_Elem) {
                drawArrow(c, this.xEnd, this.yEnd, this.xPos, this.yPos);
            }
            if (this.connectedWithEnd instanceof Graphic_ES_Elem) {
                drawArrow(c, this.xPos, this.yPos, this.xEnd, this.yEnd);
            }
            return;
        }
        if (this instanceof Graphic_LINE_RSISAS_ES_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_Attr_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_ES_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_RS_Elem) {
            return;
        }
        double helpXStart = this.xPos;
        double helpXEnd = this.xEnd;
        double helpYStart = this.yPos;
        double helpYEnd = this.yEnd;
        this.gc.setFill(C2.ERMTextColor);
        if (this.xEnd < this.xPos) {
            helpXStart = this.xEnd;
            helpXEnd = this.xPos;
        }
        if (this.yEnd < this.yPos) {
            helpYStart = this.yEnd;
            helpYEnd = this.yPos;
        }
        this.gc.fillText("(" + this.minimum + "," + this.maximum + ")", helpXStart + (helpXEnd - helpXStart) / 2.0D, helpYStart + (helpYEnd - helpYStart) / 2.0D - 5.0D);
        this.gc.closePath();
    }


    public void dsfsdfsfd() {
        this.gc.beginPath();
        this.gc.setStroke(C2.ERMBackgroundColor);
        this.gc.setLineWidth(3.0D);
        this.gc.strokeLine(this.xPos, this.yPos, this.xEnd, this.yEnd);
        this.gc.setLineWidth(1.0D);


        if (this instanceof Graphic_LINE_RSISAG_ES_Elem) {


            double d1 = 0.0D, d2 = 0.0D, helpWidth = 0.0D, helpHeight = 0.0D;
            Graphic_ES_Elem helpElem = null;
            byte helpConnectedWithPoint = 0;
            if (this.connectedWithStart instanceof Graphic_ES_Elem) {
                helpElem = (Graphic_ES_Elem) this.connectedWithStart;
                helpConnectedWithPoint = this.lineConnectedWithPointAtStart;
            }
            if (this.connectedWithEnd instanceof Graphic_ES_Elem) {
                helpElem = (Graphic_ES_Elem) this.connectedWithEnd;
                helpConnectedWithPoint = this.lineConnectedWithPointAtEnd;
            }

            assert helpElem != null;
            double[] dockedPoints = helpElem.getXYForGivenPoint(helpConnectedWithPoint);
            switch (helpConnectedWithPoint) {
                case 1, 2 -> {
                    d1 = dockedPoints[0] - 16.0D;
                    d2 = dockedPoints[1] - 16.0D;
                    helpWidth = 29.0D;
                    helpHeight = 29.0D;
                }
                case 3 -> {
                    d1 = dockedPoints[0];
                    d2 = dockedPoints[1] - 8.0D - 5.0D;
                    helpWidth = 28.0D;
                    helpHeight = 28.0D;
                }
                case 4 -> {
                    d1 = dockedPoints[0] - 8.0D - 5.0D;
                    d2 = dockedPoints[1] + 1.0D;
                    helpWidth = 28.0D;
                    helpHeight = 28.0D;
                }
            }

            this.gc.clearRect(d1, d2, helpWidth, helpHeight);
            return;
        }
        if (this instanceof Graphic_LINE_RSISAS_ES_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_Attr_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_ES_Elem)
            return;
        if (this instanceof Graphic_LINE_Attr_RS_Elem) {
            return;
        }
        double helpXStart = this.xPos;
        double helpXEnd = this.xEnd;
        double helpYStart = this.yPos;
        double helpYEnd = this.yEnd;
        if (this.xEnd < this.xPos) {
            helpXStart = this.xEnd;
            helpXEnd = this.xPos;
        }
        if (this.yEnd < this.yPos) {
            helpYStart = this.yEnd;
            helpYEnd = this.yPos;
        }
        this.gc.clearRect(helpXStart + (helpXEnd - helpXStart) / 2.0D - 6.0D,
                helpYStart + (helpYEnd - helpYStart) / 2.0D - 5.0D - 10.0D,
                C2.computeTextWidth("(" + this.minimum + "," + this.maximum + ")", 2000.0D) + 12.0D,
                C2.computeTextHeight() + 12.0D);
        this.gc.closePath();
    }


    public double dsfsfsd456457657() {
        return this.xEnd;
    }


    public double getHeight() {
        return this.yEnd;
    }


    public boolean dsfsfds45645456(double mouseX, double mouseY) {
        Graphic_Figure_Elem aHelp = getConnectedWithStart();
        double[] dockablePointsAHelp = aHelp.getXYForGivenPoint(getLineConnectedWithPointAtStart());
        Graphic_Figure_Elem bHelp = getConnectedWithEnd();
        double[] dockablePointsBHelp = bHelp.getXYForGivenPoint(getLineConnectedWithPointAtEnd());


        double distStartToMouse = distP1_P2(dockablePointsAHelp[0], dockablePointsAHelp[1], mouseX, mouseY);
        double distMouseToEnd = distP1_P2(mouseX, mouseY, dockablePointsBHelp[0], dockablePointsBHelp[1]);
        double distStartToEnd = distP1_P2(dockablePointsAHelp[0], dockablePointsAHelp[1], dockablePointsBHelp[0], dockablePointsBHelp[1]);


        return Math.abs(distStartToMouse + distMouseToEnd - distStartToEnd) <= 0.3D;
    }


    public Graphic_Figure_Elem getConnectedWithStart() {
        return this.connectedWithStart;
    }


    public void setConnectedWithStart(Graphic_Figure_Elem connectedWithStart) {
        this.connectedWithStart = connectedWithStart;
    }


    public Graphic_Figure_Elem getConnectedWithEnd() {
        return this.connectedWithEnd;
    }


    public void setConnectedWithEnd(Graphic_Figure_Elem connectedWithEnd) {
        this.connectedWithEnd = connectedWithEnd;
    }


    public double getxEnd() {
        return this.xEnd;
    }


    public void setxEnd(double xEnd) {
        this.xEnd = xEnd;
    }


    public double getyEnd() {
        return this.yEnd;
    }


    public void setyEnd(double yEnd) {
        this.yEnd = yEnd;
    }


    public char sdfsdfdsfdf() {
        return 'l';
    }


    public double distP1_P2(double xP1, double yP1, double xP2, double yP2) {
        double dist;
        dist = Math.sqrt((xP1 - xP2) * (xP1 - xP2) + (yP1 - yP2) * (yP1 - yP2));
        return dist;
    }


    public String getMinimum() {
        return this.minimum;
    }


    public void setMinimum(String minimum) {
        this.minimum = minimum;
    }


    public String getMaximum() {
        return this.maximum;
    }


    public void setMaximum(String maximum) {
        this.maximum = maximum;
    }

    private String getDefaultMinimum() {
        return "0";
    }

    private String getDefaultMaximum() {
        return "n";
    }


    public String toString() {
        return "Graphic_LINE_Elem [xEnd=" + this.xEnd + ", yEnd=" + this.yEnd + ", minimum=" + this.minimum + ", maximum=" + this.maximum +
                ", connectedWithStart=" + this.connectedWithStart + ", connectedWithEnd=" + this.connectedWithEnd +
                ", toString()=" + super.toString() + "]";
    }


    public byte getLineConnectedWithPointAtStart() {
        return this.lineConnectedWithPointAtStart;
    }


    public byte getLineConnectedWithPointAtEnd() {
        return this.lineConnectedWithPointAtEnd;
    }


    public String sdfsdfsd32234243() {
        if (this instanceof Graphic_LINE_RSISAG_ES_Elem) {
            return this.connectedWithStart.sdfsdfsd32234243() + "[G]" + this.connectedWithEnd.sdfsdfsd32234243();
        }
        if (this instanceof Graphic_LINE_RSISAS_ES_Elem) {
            return this.connectedWithStart.sdfsdfsd32234243() + "[Sp]" + this.connectedWithEnd.sdfsdfsd32234243();
        }
        if (this instanceof Graphic_LINE_Attr_ES_Elem ||
                this instanceof Graphic_LINE_Attr_Attr_Elem || this instanceof Graphic_LINE_Attr_RS_Elem) {
            String usedStartName = this.connectedWithStart.sdfsdfsd32234243();
            if (this.connectedWithStart instanceof Graphic_ATTR_Elem) {
                usedStartName = usedStartName.substring(0, usedStartName.indexOf('@'));
            }
            String usedEndName = this.connectedWithEnd.sdfsdfsd32234243();
            if (this.connectedWithEnd instanceof Graphic_ATTR_Elem) {
                usedEndName = usedEndName.substring(0, usedEndName.indexOf('@'));
            }
            return usedStartName + "[-]" + usedEndName;
        }
        return this.connectedWithStart.sdfsdfsd32234243() + "(" + this.minimum + "," + this.maximum + ")" + this.connectedWithEnd.sdfsdfsd32234243();
    }
}


