package org.cirdles.topsoil.app.util.dialog;

import javafx.application.Platform;
import javafx.collections.MapChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.cirdles.topsoil.app.MainWindow;
import org.cirdles.topsoil.app.plot.variable.Variable;
import org.cirdles.topsoil.app.plot.variable.Variables;
import org.cirdles.topsoil.app.table.TopsoilDataColumn;
import org.cirdles.topsoil.app.table.TopsoilTableController;
import org.cirdles.topsoil.app.util.dialog.controller.VariableColumnChooser;

import java.util.List;
import java.util.Map;

/**
 * @author Jake Marotta
 */
public class VariableChooserDialog extends Dialog<Map<Variable<Number>, TopsoilDataColumn>> {

    private VariableChooserDialog(List<TopsoilDataColumn> columns,
                                  List<Variable<Number>> variables,
                                  Map<Variable<Number>, TopsoilDataColumn> selections,
                                  List<Variable<Number>> required) {
        super();

        Stage stage = (Stage) this.getDialogPane().getScene().getWindow();
        stage.getIcons().add(MainWindow.getWindowIcon());
        stage.initOwner(MainWindow.getPrimaryStage());
        stage.setTitle("Variable Chooser");
        stage.setResizable(true);
        this.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);

        Label messageLabel = new Label("Choose which variables to associate with each column.");
        messageLabel.setPadding(new Insets(10.0, 10.0, 10.0, 10.0));
        VariableColumnChooser chooser = new VariableColumnChooser(columns, variables, selections, required);

        VBox container = new VBox(messageLabel, chooser);
        container.setAlignment(Pos.TOP_CENTER);

        // Disable OK button if not all required variables are assigned.
        this.getDialogPane().lookupButton(ButtonType.OK).setDisable(true);
        chooser.selectionsProperty().addListener((MapChangeListener<? super Variable<Number>, ? super TopsoilDataColumn>) c -> {
            Boolean shouldDisableOK = false;
            if (!(required == null)) {
                for (Variable<Number> v : required) {
                    if (!chooser.selectionsProperty().containsKey(v)) {
                        shouldDisableOK = true;
                        break;
                    }
                }
            }
            this.getDialogPane().lookupButton(ButtonType.OK).setDisable(shouldDisableOK);
        });
        this.getDialogPane().setContent(container);

        // The Scene doesn't seem to be completely done laying out its Nodes by the time this event is fired. Since
        // Platform.runLater() isn't being used extensively elsewhere, this works fine. If that changes, this may
        // have to be changed, as well.
        this.setOnShown(event -> Platform.runLater(() ->  {
            chooser.callAfterVisible();
            if (stage.getWidth() > 800.0) {
                stage.setWidth(800.0);
            }
            if (stage.getHeight() > 600.0) {
                stage.setHeight(600.0);
            }
        }));

        this.setResultConverter(result -> {
            if (result == ButtonType.OK) {
                return chooser.getSelections();
            } else {
                return null;
            }
        });
    }

    public static Map<Variable<Number>, TopsoilDataColumn> showDialog(TopsoilTableController tableController,
                                                                      List<Variable<Number>> requiredVariables) {

        List<TopsoilDataColumn> columns = tableController.getTable().getDataColumns();
        List<Variable<Number>> variables = Variables.VARIABLE_LIST;
        Map<Variable<Number>, TopsoilDataColumn> currentSelections = tableController.getTable().getVariableAssignments();

        return new VariableChooserDialog(columns, variables, currentSelections, requiredVariables).showAndWait().orElse(null);
    }
}

@@ -2056,28 +2056,55 @@
 .setDisable(
-true
+isOkDisabled(required, chooser)
 );%0A        c
@@ -2227,351 +2227,8 @@
 %3E %7B%0A
-            Boolean shouldDisableOK = false;%0A            if (!(required == null)) %7B%0A                for (Variable%3CNumber%3E v : required) %7B%0A                    if (!chooser.selectionsProperty().containsKey(v)) %7B%0A                        shouldDisableOK = true;%0A                        break;%0A                    %7D%0A                %7D%0A            %7D%0A
     
@@ -2299,23 +2299,39 @@
 ble(
-should
+isOk
 Disable
-OK
+d(required, chooser)
 );%0A 
@@ -3827,11 +3827,513 @@
 );%0A    %7D
+%0A%0A    //Set disabled = true when required variables are not assigned%0A    private boolean isOkDisabled(List%3CVariable%3CNumber%3E%3E required, VariableColumnChooser chooser) %7B%0A        boolean areAssigned = false;%0A%0A        if (!(required == null)) %7B%0A            for (Variable%3CNumber%3E v : required) %7B%0A                if (!chooser.selectionsProperty().containsKey(v)) %7B%0A                    areAssigned = true;%0A                    break;%0A                %7D%0A            %7D%0A        %7D%0A%0A        return areAssigned;%0A    %7D
 %0A%7D%0A

Enable OK button by default in variable assignment window