package be.iminds.ilabt.jfed.experimenter_gui.canvas;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.css.PseudoClass;
import javafx.scene.CacheHint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;

/**
 * This class visualises a new canvas link in the making.
 * It is visualised by a line that starts from the supposed origin of  the link,
 * and ends with a circle when the target is unknown
 * <p>
 * User: twalcari
 * Date: 11/8/13
 * Time: 5:47 PM
 */
public class NewCanvasLink {
    private static final PseudoClass INVALID_PSEUDO_CLASS = PseudoClass.getPseudoClass("invalid");

    private final ExperimentCanvas experimentCanvas;

    private final Line line;
    private final Circle circle;
    private final BooleanProperty visible = new SimpleBooleanProperty(false);
    private final BooleanProperty valid = new SimpleBooleanProperty(true);

    private NewLinkTarget origin;
    private NewLinkTarget target;


    public NewCanvasLink(ExperimentCanvas experimentCanvas) {
        this.experimentCanvas = experimentCanvas;

        line = new Line();
        line.getStyleClass().add("new-canvas-link-line");
        line.setCache(true);
        line.setCacheHint(CacheHint.SPEED);
        line.visibleProperty().bind(visible);

        experimentCanvas.getCanvas().getChildren().add(0, line);

        circle = new Circle();
        circle.setRadius(3.5);
        circle.getStyleClass().add("new-canvas-link-end");
        circle.setCache(true);
        circle.setCacheHint(CacheHint.SPEED);
        circle.visibleProperty().bind(visible);

        experimentCanvas.getCanvas().getChildren().add(0, circle);

        //hidden by default
        setVisible(false);

        valid.addListener(observable -> {
            line.pseudoClassStateChanged(INVALID_PSEUDO_CLASS, !valid.get());
            circle.pseudoClassStateChanged(INVALID_PSEUDO_CLASS, !valid.get());
        });

    }

    public boolean isVisible() {
        return visible.get();
    }

    public void setVisible(boolean visible) {
        this.visible.set(visible);
    }

    public BooleanProperty visibleProperty() {
        return visible;
    }

    public NewLinkTarget getOrigin() {
        return origin;
    }

    public NewLinkTarget getTarget() {
        return target;
    }

    public void setOrigin(NewLinkTarget newOrigin) {
        this.origin = newOrigin;

        line.setStartX(newOrigin.getCenterPosition().getX());
        line.setStartY(newOrigin.getCenterPosition().getY());
    }

    public void setTarget(NewLinkTarget newTarget) {
        this.target = newTarget;

        setNewEnd(newTarget.getCenterPosition().getX(), newTarget.getCenterPosition().getY());
    }

    public void clear() {
        this.origin = null;
        this.target = null;
    }

    public void setNewEnd(double x, double y) {
        line.setEndX(x);
        line.setEndY(y);

        circle.setCenterX(x);
        circle.setCenterY(y);
    }

    /**
     * @return true if an origin and target are specified.
     */
    public boolean isLinkComplete() {
        return origin != null && target != null;
    }

    public boolean getValid() {
        return valid.get();
    }

    public BooleanProperty validProperty() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid.set(valid);
    }
}
