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

import be.iminds.ilabt.jfed.experimenter_gui.editor.ToolboxItem;
import javafx.beans.property.*;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * User: twalcari
 * Date: 10/18/13
 * Time: 5:16 PM
 */
public class CanvasNode extends BorderPane {
    private static final Logger LOG = LoggerFactory.getLogger(CanvasNode.class);

    private final ImageView typeImageView;
    private final Label nameLabel;
    private final StackPane testbedPane;
    private final ImageView testbedImageView;
    private final Tooltip tooltip;

    protected final StringProperty tooltipText;
    protected final StringProperty text;
    protected final ObjectProperty<Image> image;
    protected final ObjectProperty<Color> color = new SimpleObjectProperty<>(Color.TRANSPARENT);
    protected final ObjectProperty<Image> logo;

    private final BooleanProperty selected = new SimpleBooleanProperty(false);

    public CanvasNode(){
        this.typeImageView = new ImageView();
        typeImageView.setFitWidth(25);
        typeImageView.setFitHeight(25);
        typeImageView.setPreserveRatio(true);
        typeImageView.getStyleClass().add("canvas-node-image");
        this.image = typeImageView.imageProperty();

        this.nameLabel = new Label();
        this.text = nameLabel.textProperty();

        this.testbedPane = new StackPane();
        testbedPane.setPrefWidth(30);

        //this.color = testbedPane.fillProperty();
        this.color.addListener(observable -> testbedPane.setStyle(String.format("-fx-background-color: linear-gradient(from 0%% 0%% to 100%% 0%%, transparent 0%%, rgb(%s,%s,%s)  100%%)",
                CanvasNode.this.color.get().getRed() * 255, CanvasNode.this.color.get().getGreen() * 255, CanvasNode.this.color.get().getBlue() * 255)));

        testbedPane.getStyleClass().add("canvas-node-shape");
        BorderPane.setAlignment(testbedPane, Pos.CENTER);

        testbedImageView = new ImageView();
        testbedImageView.setFitHeight(25);
        testbedImageView.setFitWidth(25);
        testbedPane.getChildren().add(testbedImageView);
        this.logo = testbedImageView.imageProperty();


        this.tooltip = new Tooltip();
        tooltipText = tooltip.textProperty();
        Tooltip.install(testbedPane, tooltip);

        getStylesheets().add(CanvasNode.class.getResource("canvas.css").toExternalForm());
        getStyleClass().add("canvas-node");
        nameLabel.getStyleClass().add("canvas-node-text");

        setMinSize(100, 30);

        setLeft(typeImageView);
        setCenter(nameLabel);
        setRight(testbedPane);

        selected.addListener((observable) -> setFocused(selected.get()));
    }

    public CanvasNode(String text, Image image) {
        this();

        setText(text);
        setImage(image);
    }

    public CanvasNode(CanvasNode item) {
        this(item.nameLabel.getText(), item.getTypeImageView().getImage());
    }

    public CanvasNode(ToolboxItem item) {
        this(item.getText(), item.getImageView().getImage());
    }

    public ImageView getTypeImageView() {
        return typeImageView;
    }

    public String getText() {
        return text.get();
    }

    public StringProperty textProperty() {
        return text;
    }

    public Image getImage() {
        return image.get();
    }

    public ObjectProperty<Image> imageProperty() {
        return image;
    }

    public void setText(String text) {
        this.text.set(text);
    }

    public void setImage(Image image) {
        this.image.set(image);
    }

    public Bounds getCanvasBounds() {
        return ExperimentCanvas.calculateBoundsInCanvas(this);
    }

    public boolean getSelected() {
        return selected.get();
    }

    public BooleanProperty selectedProperty() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected.set(selected);
    }
}
