package _VisualDVM.GlobalData.RunConfiguration;
import Common.CommonConstants;
import Common.Utils.Utils_;
import Common.Visual.UI_;
import _VisualDVM.Current;
import Common.Visual.DataSetControlForm;
import Common.Visual.Windows.Dialog.DBObjectDialog;
import Common.Database.Objects.DBObject;
import Common.Database.Tables.FKBehaviour;
import Common.Database.Tables.FKCurrentObjectBehaviuor;
import Common.Database.Tables.FKDataBehaviour;
import Common.Database.Tables.iDBTable;
import _VisualDVM.Global;
import _VisualDVM.GlobalData.Compiler.Compiler;
import _VisualDVM.GlobalData.Compiler.CompilerType;
import _VisualDVM.GlobalData.DVMParameter.DVMParameter;
import _VisualDVM.GlobalData.EnvironmentValue.EnvironmentValue;
import _VisualDVM.GlobalData.GlobalDatabase;
import _VisualDVM.GlobalData.RunConfiguration.UI.MatrixBar;
import _VisualDVM.GlobalData.RunConfiguration.UI.RunConfigurationFields;
import _VisualDVM.GlobalData.Tasks.RunTask.RunTask;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedHashMap;
public class RunConfigurationsDBTable extends iDBTable<RunConfiguration> {
    public RunConfigurationsDBTable() {
        super(RunConfiguration.class);
    }
    @Override
    public String getSingleDescription() {
        return "конфигурация запуска";
    }
    @Override
    public String getPluralDescription() {
        return "конфигурации запуска";
    }
    @Override
    public DBObjectDialog<RunConfiguration, RunConfigurationFields> getDialog() {
        return new DBObjectDialog<RunConfiguration, RunConfigurationFields>(RunConfigurationFields.class) {
            @Override
            public void fillFields() {
                for (Compiler compiler : (Global.mainModule.getDb()).compilers.Data.values()) {
                    if (compiler.isVisible() && compiler.type.equals(CompilerType.dvm))
                        fields.cbLauncherCall.addItem(compiler);
                }
                UI_.TrySelect_s(fields.cbLauncherCall, Result.LauncherCall);
                UI_.TrySelect(fields.cbLaunchOptions, Result.LauncherOptions);
                fields.tfArgs.setText(Result.args);
                fields.cbLauncherCall.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (fields.cbLauncherCall.getSelectedItem() instanceof Compiler) {
                            UI_.TrySelect(fields.cbLaunchOptions, "run");
                        }
                    }
                });
                fields.cbCube.setSelected(Result.isCube());
                //------------------------------------------->>>
                fields.sMaxDim.setModel(new SpinnerNumberModel(
                        Result.dim,
                        0, RunConfiguration.maxProc, 1));
                fields.minMatrixPanel.add(fields.minMatrixBar = new MatrixBar(Result.minMatrix));
                fields.maxMatrixPanel.add(fields.maxMatrixBar = new MatrixBar(Result.maxMatrix));
                //------------------------------------------->>>
                if (!edit)
                    fields.sMaxDim.setValue(Global.mainModule.getProject().maxdim);
            }
            @Override
            public void ProcessResult() {
                Result.machine_id = Global.mainModule.getMachine().id;
                Result.LauncherCall = fields.cbLauncherCall.getSelectedItem().toString();
                Result.LauncherOptions = (String) fields.cbLaunchOptions.getSelectedItem();
                if (fields.cbLauncherCall.getSelectedItem() instanceof Compiler) {
                    Result.compiler_id = ((Compiler) (fields.cbLauncherCall.getSelectedItem())).id;
                } else Result.compiler_id = CommonConstants.Nan;
                //-
                Result.dim = (int) fields.sMaxDim.getValue();
                Result.minMatrix = fields.minMatrixBar.pack(Result.dim);
                Result.maxMatrix = fields.maxMatrixBar.pack(Result.dim);
                //-
                Result.args = fields.tfArgs.getText();
                Result.cube = fields.cbCube.isSelected() ? 1 : 0;
            }
            @Override
            public void validateFields() {
                String launcher_call = fields.cbLauncherCall.getSelectedItem().toString();
                String launcher_options = (String) fields.cbLaunchOptions.getSelectedItem();
                if (launcher_call.isEmpty() && !launcher_options.isEmpty())
                    Log.Writeln_("Непустые опции запуска допускаются только для DVM системы или MPI");
                if (fields.cbLauncherCall.getSelectedItem() instanceof Compiler) {
                    Compiler compiler = (Compiler) (fields.cbLauncherCall.getSelectedItem());
                    switch (compiler.type) {
                        case dvm:
                        case mpi:
                            int dim_ = (int) fields.sMaxDim.getValue();
                            RunConfiguration.validateMatrixes(
                                    fields.minMatrixBar.pack(dim_),
                                    fields.maxMatrixBar.pack(dim_),
                                    dim_,
                                    fields.cbCube.isSelected(),
                                    Log
                            );
                            break;
                    }
                }
            }
        };
    }
    @Override
    public LinkedHashMap<Class<? extends DBObject>, FKBehaviour> getFKDependencies() {
        LinkedHashMap<Class<? extends DBObject>, FKBehaviour> res = new LinkedHashMap<>();
        res.put(RunTask.class, new FKBehaviour(FKDataBehaviour.DELETE, FKCurrentObjectBehaviuor.ACTIVE));
        res.put(EnvironmentValue.class, new FKBehaviour(FKDataBehaviour.DELETE, FKCurrentObjectBehaviuor.ACTIVE));
        res.put(DVMParameter.class, new FKBehaviour(FKDataBehaviour.DELETE, FKCurrentObjectBehaviuor.ACTIVE));
        return res;
    }
    @Override
    protected DataSetControlForm createUI() {
        return new DataSetControlForm(this) {
            @Override
            protected void AdditionalInitColumns() {
                columns.get(0).setVisible(false);
            }

        };
    }
    @Override
    public String[] getUIColumnNames() {
        return new String[]{
                "Команда",
                "Опции",
                "Разм.",
                "Куб",
                "Min",
                "Max",
                "Аргументы"
        };
    }
    @Override
    public Object getFieldAt(RunConfiguration object, int columnIndex) {
        switch (columnIndex) {
            case 1:
                return object.LauncherCall;
            case 2:
                return object.LauncherOptions;
            case 3:
                return object.dim;
            case 4:
                return object.printCube();
            case 5:
                return object.minMatrix;
            case 6:
                return object.maxMatrix;
            case 7:
                return object.args;
            default:
                return null;
        }
    }
    @Override
    public Current CurrentName() {
        return Current.RunConfiguration;
    }
    public void Patch() throws Exception {
        for (RunConfiguration c : Data.values()) {
            c.Patch();
            getDb().Update(c);
        }
    }
}
