package be.iminds.ilabt.jfed.experimenter_gui.timeline.view.dialogs;

import be.iminds.ilabt.jfed.experimenter_gui.timeline.controller.TimelineController;
import be.iminds.ilabt.jfed.experimenter_gui.timeline.view.TimeTextField;
import be.iminds.ilabt.jfed.experimenter_gui.util.ui.UIUtils;
import be.iminds.ilabt.jfed.rspec.model.controller.ExperimentCommand;
import be.iminds.ilabt.jfed.rspec.model.controller.Timestamp;
import be.iminds.ilabt.jfed.ui.javafx.FXMLUtil;
import be.iminds.ilabt.jfed.ui.javafx.GlyphUtils;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Window;
import org.controlsfx.glyphfont.FontAwesome;
import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator;
import org.controlsfx.validation.decoration.GraphicValidationDecoration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

public class CommandPropertiesDialog extends GridPane {

    private static final Logger LOG = LoggerFactory.getLogger(CommandPropertiesDialog.class);

    private final TimelineController controller;
    private final ExperimentCommand command;
    @FXML
    private TextField commandTextField;
    @FXML
    private TimeTextField startTextField;
    @FXML
    private Button okButton;
    @FXML
    private TextField tagTextField;


    private final Dialog<ButtonType> dialog;

    private CommandPropertiesDialog(Window parent, TimelineController controller, final ExperimentCommand command) {
        this.controller = controller;
        this.command = command;

        //initialize the Scene
        FXMLUtil.injectFXML(this);

        tagTextField.setText(command.getTag());
        commandTextField.setText(command.getCommand());
        startTextField.setTime(command.getStartingTime().toString());

        //initialize dialog
        dialog = new Dialog<>();
        dialog.initOwner(parent);
        dialog.setTitle(String.format("Properties of %s", command.getTag()));
        dialog.setHeaderText(dialog.getTitle());
        dialog.setGraphic(GlyphUtils.createDialogGlyph(FontAwesome.Glyph.PENCIL, Color.BLACK));
        dialog.getDialogPane().setContent(UIUtils.wrapWithDecorationPane(this));
        dialog.getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL);

        dialog.resultProperty().addListener(observable -> {
            if(dialog.getResult() == ButtonType.OK)
                onOKAction();
        });

        //initialize validation support
        ValidationSupport validationSupport = new ValidationSupport();
        validationSupport.registerValidator(tagTextField, Validator.createEmptyValidator("Tag is a required field!"));
        validationSupport.registerValidator(commandTextField, Validator.createEmptyValidator("Command is a required field!"));
        validationSupport.setValidationDecorator(new GraphicValidationDecoration());


        Node okButton  = dialog.getDialogPane().lookupButton(ButtonType.OK);
        okButton.disableProperty().bind(validationSupport.invalidProperty());
    }

    private void onOKAction() {
        Timestamp newDuration;
        if (!Objects.equals(command.getCommand(), commandTextField.getText())) {
            newDuration = new Timestamp(0);
        } else {
            newDuration = command.getDuration();
        }

        controller.updateCommand(command,
                new ExperimentCommand(tagTextField.getText(),
                        command.getNodeUniqueID(),
                        command.getBarrierSegmentOrderNumber(),
                        commandTextField.getText(),
                        new Timestamp(startTextField.toMillis()), newDuration));
    }

    public static void showSimplePropertiesDialog(Window parent, TimelineController controller, final ExperimentCommand command) {
        final CommandPropertiesDialog npd = new CommandPropertiesDialog(parent, controller, command);
        npd.showDialog();
    }

    private void showDialog() {
        dialog.show();
    }
}
