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.ribbon_tabs.GTSRawEditorRibbonTab;
import be.iminds.ilabt.jfed.experimenter_gui.gts_editor.ribbon_tabs.GTSTopologyEditorRibbonTab;
import be.iminds.ilabt.jfed.experimenter_gui.gts_editor.views.GTSViewsFactory;
import be.iminds.ilabt.jfed.experimenter_gui.tabs.AskOnCloseRequest;
import be.iminds.ilabt.jfed.experimenter_gui.tabs.RibbonEnabled;
import be.iminds.ilabt.jfed.experimenter_gui.tabs.StatusEnabled;
import be.iminds.ilabt.jfed.experimenter_gui.ui.ribbon.RibbonTab;
import be.iminds.ilabt.jfed.ui.javafx.GlyphUtils;
import be.iminds.ilabt.jfed.ui.javafx.dialogs.JFDialogs;
import javafx.beans.value.ObservableStringValue;
import javafx.scene.control.*;
import org.controlsfx.glyphfont.FontAwesome;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * User: twalcari
 * Date: 5/18/2015
 * Time: 10:10
 */
public class GTSEditorTab extends Tab implements RibbonEnabled, StatusEnabled, AskOnCloseRequest {
    private final static List<RibbonTab> ribbonTabs;

    private static final GTSTopologyEditorRibbonTab topologyEditorRibbonTab;
    private static final GTSRawEditorRibbonTab rawEditorRibbonTab;

    private final EditableGtsDsl editableGtsDsl;
    private final GTSEditor gtsEditor;


    static {
        ribbonTabs = new ArrayList<>();

        rawEditorRibbonTab = new GTSRawEditorRibbonTab();
        topologyEditorRibbonTab = new GTSTopologyEditorRibbonTab(rawEditorRibbonTab);

        ribbonTabs.add(topologyEditorRibbonTab);
        ribbonTabs.add(rawEditorRibbonTab);


    }

    GTSEditorTab(EditableGtsDsl editableGtsDsl, GTSViewsFactory gtsViewsFactory, GTSEditorActionsFactory gtsEditorActionsFactory) {
        this.editableGtsDsl = editableGtsDsl;

        textProperty().bind(editableGtsDsl.nameProperty());

        getStyleClass().add("tab-gts-design");
        setGraphic(GlyphUtils.createGlyph(FontAwesome.Glyph.CLOUD));

        ContextMenu contextMenu = new ContextMenu();
        MenuItem changeNameMenuItem = new MenuItem("Change name", GlyphUtils.createGlyph(FontAwesome.Glyph.PENCIL));
        changeNameMenuItem.setOnAction(actionEvent -> showEditNameDialog());
        contextMenu.getItems().add(changeNameMenuItem);
        setContextMenu(contextMenu);


        this.gtsEditor = new GTSEditor(editableGtsDsl, gtsViewsFactory, gtsEditorActionsFactory);
        setContent(gtsEditor);
    }

    private void showEditNameDialog() {
        String name = null;

        while (name == null) {
            name = JFDialogs.create()
                    .owner(this.getGtsEditor())
                    .message("Enter a new name:")
                    .masthead("Change GTS DSL name")
                    .title("Change GTS DSL name")
                    .showTextInput(editableGtsDsl.getName()).orElse(null);

            if (name == null) {
                return; //user cancelled
            }
            name = name.trim();

            if (!editableGtsDsl.verifyName(name)) {
                JFDialogs.create()
                        .message("The given name is not a valid for GTS. Please choose a name using the following characters: [A-Za-z0-9_]")
                        .showError();

                name = null;
            }
        }

        editableGtsDsl.setName(name);
    }


    public List<? extends RibbonTab> getRibbonTabs() {
        return ribbonTabs;
    }

    public RibbonTab getInitialTabToActivate() {
        switch (gtsEditor.getCurrentEditorViewType()) {
            case CANVAS:
                return topologyEditorRibbonTab;
            case RAW:
                return rawEditorRibbonTab;
            default:
                throw new RuntimeException("Unexpected type: " + gtsEditor.getCurrentEditorViewType());
        }
    }

    public ObservableStringValue statusProperty() {
        return gtsEditor.statusProperty();
    }

    public GTSEditor getGtsEditor() {
        return gtsEditor;
    }

    @Override
    public boolean onTabCloseRequest() {
        if (gtsEditor.getEditableGtsDsl().isDirty()) {

            Alert saveAlert = new Alert(Alert.AlertType.CONFIRMATION);
            saveAlert.setTitle("Unsaved changes");
            saveAlert.setHeaderText("Unsaved changes");
            saveAlert.setContentText("Do you want to save changes you made to " +
                    gtsEditor.getEditableGtsDsl().getName() + "?");

            ButtonType saveButtonType = new ButtonType("Save", ButtonBar.ButtonData.YES);
            ButtonType dontSaveButtonType = new ButtonType("Don't save", ButtonBar.ButtonData.NO);
            saveAlert.getButtonTypes().setAll(saveButtonType, dontSaveButtonType, ButtonType.CANCEL);

            Optional<ButtonType> result = saveAlert.showAndWait();

            if (!result.isPresent() || result.get() == ButtonType.CANCEL) {
                return false;
            } else if (result.get() == saveButtonType) {
                gtsEditor.save();
                return true;
            } else {
                // user pressed dontSaveButtonType. The user doesn't want to save it's changes..
                gtsEditor.revert();
                return true;
            }
        } else return true;
    }
}
