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

import be.iminds.ilabt.jfed.experimenter_gui.gts_editor.actions.GTSEditorActionsFactory;
import be.iminds.ilabt.jfed.experimenter_gui.gts_editor.views.GTSViewsFactory;
import be.iminds.ilabt.jfed.experimenter_gui.ui.GTSEditorTabHost;
import be.iminds.ilabt.jfed.gts.model.impl.FXGtsType;
import be.iminds.ilabt.jfed.lowlevel.TestbedInfoSource;


import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * User: twalcari
 * Date: 12/8/2014
 * Time: 15:58
 */
@Singleton
public class GTSEditorTabFactory {

    private final GTSEditorTabHost gtsEditorTabHost;

    private final TestbedInfoSource testbedInfoSource;
    private final GTSViewsFactory gtsViewsFactory;
    private final GTSEditorActionsFactory gtsEditorActionsFactory;


    @Inject
    public GTSEditorTabFactory(GTSEditorTabHost gtsEditorTabHost, TestbedInfoSource testbedInfoSource,
                               GTSViewsFactory gtsViewsFactory, GTSEditorActionsFactory gtsEditorActionsFactory) {
        this.gtsEditorTabHost = gtsEditorTabHost;
        this.testbedInfoSource = testbedInfoSource;
        this.gtsViewsFactory = gtsViewsFactory;
        this.gtsEditorActionsFactory = gtsEditorActionsFactory;
    }


    public GTSEditorTab createExperimentEditorTab(EditableGtsDsl editableGtsDsl) {
        if(editableGtsDsl.isEmpty()){
            editableGtsDsl.setModel(new FXGtsType(editableGtsDsl.getName()));
        }

        return new GTSEditorTab(editableGtsDsl, gtsViewsFactory, gtsEditorActionsFactory);
    }

    /**
     * @return A new unique experiment definition name
     */
    private String getNextNewGtsDslName() {
        String baseName = "UntitledGts";

        if (!experimentDefinitionNameExists(baseName))
            return baseName;

        int counter = 1;
        String name = baseName + counter;
        while (experimentDefinitionNameExists(name)) {
            counter++;
            name = baseName + counter;
        }
        return name;
    }


    /**
     * Tests whether a given experiment definition is already open in the GUI
     */
    private boolean experimentDefinitionNameExists(String name) {
        return gtsEditorTabHost.getGTSEditorTabs()
                .stream()
                .map(GTSEditorTab::getGtsEditor)
                .map(GTSEditor::getEditableGtsDsl)
                .map(EditableGtsDsl::getName)
                .anyMatch(name::equals);
    }

}
