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

import be.iminds.ilabt.jfed.experimenter_gui.timeline.controller.TimelineController;
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.experimenter_gui.slice.DetailsTabHost;
import be.iminds.ilabt.jfed.experimenter_gui.util.ImageUtil;
import be.iminds.ilabt.jfed.rspec.model.controller.ExperimentCommand;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecNode;
import javafx.scene.control.Tab;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author Cedric
 */
public class ControllerOutput implements TimelineComponent {
    private final List<NodeOutputTab> nodeTabs = new ArrayList<>();
    private final List<CommandOutputTab> commandTabs = new ArrayList<>();
    private final GeneralOutputTab generalTab;
    private final TimelineController controller;

    private final DetailsTabHost detailsTabHost;
    private final ImageUtil imageUtil;

    public ControllerOutput(DetailsTabHost detailsTabHost, TimelineController controller, ImageUtil imageUtil) {
        this.detailsTabHost = detailsTabHost;
        this.controller = controller;
        this.imageUtil = imageUtil;

        generalTab = new GeneralOutputTab();
        detailsTabHost.addDetailsTab(generalTab);

    }

    @Override
    public void update(UpdateEvent event, Object o) {
        generalTab.update(event, o);

        if (event == UpdateEvent.SHOW_COMMAND_OUTPUT) {
            ExperimentCommand c = (ExperimentCommand) o;
            for (Tab t : commandTabs) {
                if (Objects.equals(t.getId(), "" + c.getID())) {
                    if (!detailsTabHost.containsDetailsTab(t)) {
                        detailsTabHost.addDetailsTab(t);
                    }

                    detailsTabHost.selectDetailsTab(t);
                    return;
                }
            }
        } else if (event == UpdateEvent.SHOW_NODE_OUTPUT) {
            FXRspecNode n = (FXRspecNode) o;
            for (Tab t : nodeTabs) {
                if (Objects.equals(t.getText(), n.getUniqueId())) {
                    if (!detailsTabHost.containsDetailsTab(t)) {
                        detailsTabHost.addDetailsTab(t);
                    }

                    detailsTabHost.selectDetailsTab(t);
                    return;
                }
            }
        } else if (event == UpdateEvent.ADD_NODE) {
            FXRspecNode n = (FXRspecNode) o;
            NodeOutputTab t = new NodeOutputTab(n, imageUtil);
            nodeTabs.add(t);
        } else if (event == UpdateEvent.ADD_COMMAND) {
            ExperimentCommand c = (ExperimentCommand) o;
            CommandOutputTab t = new CommandOutputTab(c);
            t.setId("" + c.getID());
            commandTabs.add(t);

            for (Tab tb : nodeTabs) {
                if (Objects.equals(tb.getText(), c.getNodeUniqueID())) {
                    ((TimelineComponent) tb).update(event, o);
                    break;
                }
            }
        } else if (event == UpdateEvent.INSTANT_COMMAND) {
            ExperimentCommand c = (ExperimentCommand) o;
            InstantCommandOutputTab t = new InstantCommandOutputTab(controller, c);
            t.setId("" + c.getID());
            detailsTabHost.addDetailsTab(t);
        } else if (event == UpdateEvent.UNREGISTER) {
            generalTab.update(event, o);

            commandTabs.forEach(CommandOutputTab::unregister);
            nodeTabs.forEach(NodeOutputTab::unregister);
        }

    }

}
