// Path: src/main/java/de/jfschaefer/layeredgraphlayout/layout/EdgeSegment.java
// public class EdgeSegment {
//     public final Point start;
//     public final Point control1;
//     public final Point control2;
//     public final Point end;
//     public final boolean bezier;   //true if cubic bezier curve, false if linear
// 
//     public EdgeSegment(Point start, Point end) {
//         this.start = start;
//         this.control1 = null;
//         this.control2 = null;
//         this.end = end;
//         bezier = false;
//     }
// 
//     public EdgeSegment(Point start, Point control1, Point control2, Point end) {
//         this.start = start;
//         this.control1 = control1;
//         this.control2 = control2;
//         this.end = end;
//         bezier = true;
//     }
// 
//     public EdgeSegment addVector(Vector v) {
//         if (bezier) {
//             return new EdgeSegment(start.addVector(v), control1.addVector(v), control2.addVector(v), end.addVector(v));
//         } else {
//             return new EdgeSegment(start.addVector(v), end.addVector(v));
//         }
//     }
// 
//     public boolean isBezier() {
//         return bezier;
//     }
// 
//     public Point getStart() {
//         return start;
//     }
// 
//     public Point getControl1() {
//         return control1;
//     }
// 
//     public Point getControl2() {
//         return control2;
//     }
// 
//     public Point getEnd() {
//         return end;
//     }
// 
//     public EdgeSegment reversed() {
//         if (bezier) {
//             return new EdgeSegment(end, control2, control1, start);
//         } else {
//             return new EdgeSegment(end, start);
//         }
//     }
// 
//     public Point getAt(double fraction) {
//         if (bezier) {
//             Vector p0 = Point.ORIGIN.vectorTo(start);
//             Vector p1 = Point.ORIGIN.vectorTo(control1);
//             Vector p2 = Point.ORIGIN.vectorTo(control2);
//             Vector p3 = Point.ORIGIN.vectorTo(end);
//             return Point.ORIGIN.addVector(p0.scaled((1-fraction)*(1-fraction)*(1-fraction)))
//                     .addVector(p1.scaled(3*(1-fraction)*(1-fraction)*fraction))
//                     .addVector(p2.scaled(3*(1-fraction)*fraction*fraction))
//                     .addVector(p3.scaled(fraction*fraction*fraction));
//         } else {
//             return start.addVector(start.vectorTo(end).scaled(fraction));
//         }
//     }
// 
//     public Vector getDerivativeAt(double fraction) {
//         if (bezier) {
//             Vector a = start.vectorTo(control1);
//             Vector b = control1.vectorTo(control2);
//             Vector c = control2.vectorTo(end);
// 
//             return a.scaled(3*(1-fraction)*(1-fraction))
//                         .add(b.scaled(6*(1-fraction)*fraction))
//                         .add(c.scaled(3*fraction*fraction));
//         } else {
//             return start.vectorTo(end);
//         }
//     }
// }
// 
// Path: src/main/java/de/jfschaefer/layeredgraphlayout/layout/LayoutConfig.java
// public class LayoutConfig {
//     protected boolean bezier = true;
//     protected boolean arrowheads = true;
//     protected double controlPointDistance = 0.25d;
//     protected double graphPadding = 16d;
// 
//     public void setBezier(boolean bezier) {
//         this.bezier = bezier;
//     }
// 
//     public boolean getBezier() {
//         return bezier;
//     }
// 
//     public void setArrowheads(boolean arrowheads) {
//         this.arrowheads = arrowheads;
//     }
// 
//     public boolean getArrowheads() {
//         return arrowheads;
//     }
// 
//     public void setControlPointDistance(double value) {
//         controlPointDistance = value;
//     }
// 
//     public double getControlPointDistance() {
//         return controlPointDistance;
//     }
// 
//     public double getGraphPadding() {
//         return graphPadding;
//     }
// 
//     public void setGraphPadding(double padding) {
//         graphPadding = padding;
//     }
// }


import de.jfschaefer.layeredgraphlayout.layout.EdgeSegment;
import de.jfschaefer.layeredgraphlayout.layout.LayoutConfig;
import javafx.scene.Node;
import java.util.*;
package de.jfschaefer.layeredgraphlayout.visualizationfx;




/**
 * Created by jfschaefer on 7/31/15.
 */

public abstract class GraphFXEdgeFactory<E> {
    protected final LayoutConfig layoutConfig;

    public GraphFXEdgeFactory(LayoutConfig config) {
        layoutConfig = config;
    }

// Path: src/main/java/de/jfschaefer/layeredgraphlayout/layout/EdgeSegment.java
// public class EdgeSegment {
//     public final Point start;
//     public final Point control1;
//     public final Point control2;
//     public final Point end;
//     public final boolean bezier;   //true if cubic bezier curve, false if linear
// 
//     public EdgeSegment(Point start, Point end) {
//         this.start = start;
//         this.control1 = null;
//         this.control2 = null;
//         this.end = end;
//         bezier = false;
//     }
// 
//     public EdgeSegment(Point start, Point control1, Point control2, Point end) {
//         this.start = start;
//         this.control1 = control1;
//         this.control2 = control2;
//         this.end = end;
//         bezier = true;
//     }
// 
//     public EdgeSegment addVector(Vector v) {
//         if (bezier) {
//             return new EdgeSegment(start.addVector(v), control1.addVector(v), control2.addVector(v), end.addVector(v));
//         } else {
//             return new EdgeSegment(start.addVector(v), end.addVector(v));
//         }
//     }
// 
//     public boolean isBezier() {
//         return bezier;
//     }
// 
//     public Point getStart() {
//         return start;
//     }
// 
//     public Point getControl1() {
//         return control1;
//     }
// 
//     public Point getControl2() {
//         return control2;
//     }
// 
//     public Point getEnd() {
//         return end;
//     }
// 
//     public EdgeSegment reversed() {
//         if (bezier) {
//             return new EdgeSegment(end, control2, control1, start);
//         } else {
//             return new EdgeSegment(end, start);
//         }
//     }
// 
//     public Point getAt(double fraction) {
//         if (bezier) {
//             Vector p0 = Point.ORIGIN.vectorTo(start);
//             Vector p1 = Point.ORIGIN.vectorTo(control1);
//             Vector p2 = Point.ORIGIN.vectorTo(control2);
//             Vector p3 = Point.ORIGIN.vectorTo(end);
//             return Point.ORIGIN.addVector(p0.scaled((1-fraction)*(1-fraction)*(1-fraction)))
//                     .addVector(p1.scaled(3*(1-fraction)*(1-fraction)*fraction))
//                     .addVector(p2.scaled(3*(1-fraction)*fraction*fraction))
//                     .addVector(p3.scaled(fraction*fraction*fraction));
//         } else {
//             return start.addVector(start.vectorTo(end).scaled(fraction));
//         }
//     }
// 
//     public Vector getDerivativeAt(double fraction) {
//         if (bezier) {
//             Vector a = start.vectorTo(control1);
//             Vector b = control1.vectorTo(control2);
//             Vector c = control2.vectorTo(end);
// 
//             return a.scaled(3*(1-fraction)*(1-fraction))
//                         .add(b.scaled(6*(1-fraction)*fraction))
//                         .add(c.scaled(3*fraction*fraction));
//         } else {
//             return start.vectorTo(end);
//         }
//     }
// }
// 
// Path: src/main/java/de/jfschaefer/layeredgraphlayout/layout/LayoutConfig.java
// public class LayoutConfig {
//     protected boolean bezier = true;
//     protected boolean arrowheads = true;
//     protected double controlPointDistance = 0.25d;
//     protected double graphPadding = 16d;
// 
//     public void setBezier(boolean bezier) {
//         this.bezier = bezier;
//     }
// 
//     public boolean getBezier() {
//         return bezier;
//     }
// 
//     public void setArrowheads(boolean arrowheads) {
//         this.arrowheads = arrowheads;
//     }
// 
//     public boolean getArrowheads() {
//         return arrowheads;
//     }
// 
//     public void setControlPointDistance(double value) {
//         controlPointDistance = value;
//     }
// 
//     public double getControlPointDistance() {
//         return controlPointDistance;
//     }
// 
//     public double getGraphPadding() {
//         return graphPadding;
//     }
// 
//     public void setGraphPadding(double padding) {
//         graphPadding = padding;
//     }
// }


// Path: src/main/java/de/jfschaefer/layeredgraphlayout/visualizationfx/GraphFXEdgeFactory.java
import de.jfschaefer.layeredgraphlayout.layout.EdgeSegment;
import de.jfschaefer.layeredgraphlayout.layout.LayoutConfig;
import javafx.scene.Node;
import java.util.*;

package de.jfschaefer.layeredgraphlayout.visualizationfx;




/**
 * Created by jfschaefer on 7/31/15.
 */

public abstract class GraphFXEdgeFactory<E> {
    protected final LayoutConfig layoutConfig;

    public GraphFXEdgeFactory(LayoutConfig config) {
        layoutConfig = config;
    }

    public abstract Node getEdgeVisualization(E edge, ArrayList<EdgeSegment> segments);