package be.iminds.ilabt.jfed.experimenter_gui.ui.ribbon;

import javafx.beans.property.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import org.controlsfx.glyphfont.Glyph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * User: twalcari
 * Date: 11/6/13
 * Time: 9:48 AM
 */
public class RibbonButton extends BorderPane implements Runnable {
    private static final Logger LOG = LoggerFactory.getLogger(RibbonButton.class);

    private static final double BIG_ICON_SIZE = 24;

    private final ObjectProperty<KeyCombination> accelerator = new SimpleObjectProperty<>();
    private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>();
    private final StringProperty text = new SimpleStringProperty();
    private final ObjectProperty<EventHandler<ActionEvent>> onAction = new SimpleObjectProperty<>();
    private final BooleanProperty acceleratorOnlyWhenVisible = new SimpleBooleanProperty();
    private final VBox textContainer = new VBox();
    private final Label line1Label = new Label();

    protected final HBox secondLineContainer = new HBox();

    private final Label line2Label = new Label();
    {
        getStyleClass().add("ribbon-button");
        line1Label.getStyleClass().add("ribbon-button-text");
        line2Label.getStyleClass().add("ribbon-button-text");

        secondLineContainer.setAlignment(Pos.CENTER);
        secondLineContainer.getChildren().add(line2Label);

        textContainer.getStyleClass().add("ribbon-button-textcontainer");
        textContainer.getChildren().addAll(line1Label, secondLineContainer);

        setBottom(textContainer);

        text.addListener(observable -> {
            String newText = text.get();
            if (newText != null) {
                String[] lines = newText.split("\n");


                line1Label.setText(lines.length > 0 ? lines[0] : "");
                line2Label.setText(lines.length > 1 ? lines[1] : "");


            } else {
                line1Label.setText("");
                line2Label.setText("");
            }
        });

        graphic.addListener(observable -> {
            if (graphic.get() != null) {
                graphic.get().getStyleClass().add("ribbon-button-graphic");
                //               graphic.get().setStyle("-fx-font-size: 24pt;");
                if (graphic.get() instanceof Glyph)

                    ((Glyph) graphic.get()).setFontSize(24);

            }
            setCenter(graphic.get());
        });

        setOnMouseClicked(mouseEvent -> {
            if (onAction.get() != null) {
                onAction.get().handle(new ActionEvent());
            }
        });
    }

    public RibbonButton() {
    }

    public RibbonButton(String s) {
        setText(s);
    }
    public RibbonButton(String s, Node node) {
        setText(s);
        setGraphic(node);
    }

    public EventHandler<ActionEvent> getOnAction() {
        return onAction.get();
    }

    public void setOnAction(EventHandler<ActionEvent> onAction) {
        this.onAction.set(onAction);
    }

    /**
     * This boolean says whether the associated accelerator should only be added to the scene when the RibbonTab, in which the button sits, is visible.
     *
     * If true, the accelerator should only be added to the scene while the ribbontab is visible
     * If false, the accelerator should always be registered, as long as the ribbontab is available in the ribbon
     * @return
     */
    public boolean getAcceleratorOnlyWhenVisible() {
        return acceleratorOnlyWhenVisible.get();
    }

    public void setAcceleratorOnlyWhenVisible(boolean acceleratorOnlyWhenVisible) {
        this.acceleratorOnlyWhenVisible.set(acceleratorOnlyWhenVisible);
    }

    public BooleanProperty acceleratorOnlyWhenVisibleProperty() {
        return acceleratorOnlyWhenVisible;
    }

    public KeyCombination getAccelerator() {
        return accelerator.get();
    }

    public void setAccelerator(KeyCombination accelerator) {
        this.accelerator.set(accelerator);
    }

    public ObjectProperty<KeyCombination> acceleratorProperty() {
        return accelerator;
    }

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

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

    public StringProperty textProperty() {
        return text;
    }

    public Node getGraphic() {
        return graphic.get();
    }

    public void setGraphic(Node graphic) {
        this.graphic.set(graphic);
    }

    public ObjectProperty<Node> graphicProperty() {
        return graphic;
    }

    public boolean isSmall() {
        return false;
    }

    public void setSmall(boolean value) {
    }

    @Override
    public void run() {
        if (onAction.get() != null)
            onAction.get().handle(new ActionEvent());
    }
}
