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

import be.iminds.ilabt.jfed.experimenter_gui.timeline.view.TimelineComponent;
import be.iminds.ilabt.jfed.experimenter_gui.timeline.view.UpdateEvent;
import be.iminds.ilabt.jfed.rspec.model.controller.ExperimentCommand;
import be.iminds.ilabt.jfed.ui.javafx.GlyphUtils;
import javafx.beans.value.ChangeListener;
import javafx.scene.control.Tab;
import javafx.scene.control.TextArea;
import org.controlsfx.glyphfont.FontAwesome;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Cedric
 */
public class GeneralOutputTab extends Tab implements TimelineComponent {
    private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");

    private final TextArea output;
    private final Map<ExperimentCommand, ChangeListener<Boolean>> startedListeners = new HashMap<>();
    private final Map<ExperimentCommand, ChangeListener<Boolean>> finishedListeners = new HashMap<>();

    public GeneralOutputTab() {
        this.setText("Timeline log");
        setGraphic(GlyphUtils.createGlyph(FontAwesome.Glyph.EXPAND));
        setClosable(false);
        output = new TextArea();
        output.setPrefHeight(100);
        output.setEditable(false);
        setContent(output);
    }

    private String getTime() {
        return TIME_FORMAT.format(new Date());
    }

    @Override
    public void update(UpdateEvent event, Object o) {
        if (event == UpdateEvent.ADD_COMMAND) {
            final ExperimentCommand comm = (ExperimentCommand) o;
            ChangeListener<Boolean> startedListener = (ov, t, t1) -> {
                if (!comm.isSkipped() && comm.isStarted()) {
                    output.appendText(getTime() + "  " + comm.getNodeUniqueID() + ": " + comm.getTag() + " has started.\n");
                }
            };
            comm.getStartedProperty().addListener(startedListener);
            startedListeners.put(comm, startedListener);

            ChangeListener<Boolean> finishedListener = (ov, t, t1) -> {
                if (!comm.isSkipped() && comm.isFinished()) {
                    output.appendText(getTime() + "  " + comm.getNodeUniqueID() + ": " + comm.getTag() + " has finished.\n");
                }
            };
            comm.getFinishedProperty().addListener(finishedListener);
            finishedListeners.put(comm, finishedListener);
        } else  { if (event == UpdateEvent.UNREGISTER) {
            for (ExperimentCommand c : startedListeners.keySet()) {
                c.getStartedProperty().removeListener(startedListeners.get(c));
            }
            for (ExperimentCommand c : finishedListeners.keySet()) {
                c.getFinishedProperty().removeListener(finishedListeners.get(c));
            }
        } else {
            if (event == UpdateEvent.GENERAL_MESSAGE) {
                String msg = (String) o;
                output.appendText(getTime() + "  " +msg+ "\n");
            }
        }
        }
    }


}
