package jetbrains.mps.java.platform.actions;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import jetbrains.mps.workbench.action.BaseAction;
import javax.swing.Icon;
import jetbrains.mps.ide.editor.EditorActionAccess;
import com.intellij.openapi.actionSystem.AnActionEvent;
import java.util.Map;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.ide.actions.MPSCommonDataKeys;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.java.refactoring.InitializeFieldInConstructorRefactoring;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.ide.editor.MPSEditorDataKeys;
import jetbrains.mps.project.MPSProject;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodIdV2;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import java.util.List;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;

@GeneratedClass(node = "r:c6bc30d1-d0d1-44c6-ba7e-90e78619615e(jetbrains.mps.java.platform.actions)/7024895274320750543", model = "r:c6bc30d1-d0d1-44c6-ba7e-90e78619615e(jetbrains.mps.java.platform.actions)")
public class InitializeFieldInConstructor_Action extends BaseAction {
  private static final Icon ICON = null;

  public InitializeFieldInConstructor_Action() {
    super("Initialize in Constructor", "Initialize a field in a constructor", ICON);
    this.setIsAlwaysVisible(false);
    this.setActionAccess(EditorActionAccess.UNDO_EDITOR);
  }
  @Override
  public boolean isDumbAware() {
    return true;
  }
  @Override
  public boolean isApplicable(AnActionEvent event, final Map<String, Object> _params) {
    SNode n = event.getData(MPSCommonDataKeys.NODE);
    if (!(SNodeOperations.isInstanceOf(n, CONCEPTS.FieldDeclaration$ie))) {
      return false;
    }
    SNode field = SNodeOperations.as(event.getData(MPSCommonDataKeys.NODE), CONCEPTS.FieldDeclaration$ie);
    return new InitializeFieldInConstructorRefactoring().isApplicable(field);
  }
  @Override
  public void doUpdate(@NotNull AnActionEvent event, final Map<String, Object> _params) {
    this.setEnabledState(event.getPresentation(), this.isApplicable(event, _params));
  }
  @Override
  protected boolean collectActionData(AnActionEvent event, final Map<String, Object> _params) {
    if (!(super.collectActionData(event, _params))) {
      return false;
    }
    {
      SNode p = event.getData(MPSCommonDataKeys.NODE);
      if (p == null) {
        return false;
      }
    }
    {
      EditorContext p = event.getData(MPSEditorDataKeys.EDITOR_CONTEXT);
      if (p == null) {
        return false;
      }
    }
    {
      MPSProject p = event.getData(MPSCommonDataKeys.MPS_PROJECT);
      if (p == null) {
        return false;
      }
    }
    {
      SModel model = event.getData(MPSCommonDataKeys.CONTEXT_MODEL);
      if (model == null) {
        return false;
      }
    }
    return true;
  }
  @Override
  public void doExecute(@NotNull final AnActionEvent event, final Map<String, Object> _params) {
    SNode field = SNodeOperations.as(event.getData(MPSCommonDataKeys.NODE), CONCEPTS.FieldDeclaration$ie);

    SNode clazz = SNodeOperations.getNodeAncestor(field, CONCEPTS.ClassConcept$bK, false, false);
    if (clazz == null) {
      return;
    }

    final InitializeFieldInConstructorRefactoring refactoring = new InitializeFieldInConstructorRefactoring();
    refactoring.isApplicable(field);
    Iterable<SNode> constructors = Sequence.fromIterable(((Iterable<SNode>) BHReflection.invoke0(clazz, CONCEPTS.ClassConcept$bK, SMethodIdV2.create("constructors", 5292274854859503373L, 0x5745e3015c8914d3L)))).where((it) -> refactoring.doesNotContainFieldInitialization(it));

    SNodeReference[] selectedConstructors;
    SRepository repository = event.getData(MPSCommonDataKeys.CONTEXT_MODEL).getRepository();

    if (Sequence.fromIterable(constructors).isEmpty()) {
      SNode c = SNodeFactoryOperations.createNewNode(event.getData(MPSCommonDataKeys.CONTEXT_MODEL), CONCEPTS.ConstructorDeclaration$yG, null);
      BHReflection.invoke0(clazz, CONCEPTS.Classifier$Ix, SMethodIdV2.create("insertInBestPlace", 8332041383517793958L, 0x5745e3015c8914d3L), c);
      selectedConstructors = new SNodeReference[]{SNodeOperations.getPointer(c)};
    } else if (Sequence.fromIterable(constructors).count() == 1) {
      selectedConstructors = new SNodeReference[]{SNodeOperations.getPointer(Sequence.fromIterable(constructors).first())};
    } else {
      SNodeReference[] ctors = Sequence.fromIterable(constructors).select((it) -> SNodeOperations.getPointer(it)).toGenericArray(SNodeReference.class);
      SelectConstructorsDialog selectConstructorsDialog = new SelectConstructorsDialog(ctors, event.getData(MPSCommonDataKeys.MPS_PROJECT));
      selectConstructorsDialog.setTitle("Choose Constructors to Add Initialization to");
      selectConstructorsDialog.show();
      if (!(selectConstructorsDialog.isOK())) {
        return;
      }
      List<SNodeReference> selectedElements = selectConstructorsDialog.getSelectedElements();
      for (SNodeReference element : selectedElements) {

      }
      selectedConstructors = (selectedElements != null ? selectedElements.toArray(new SNodeReference[selectedElements.size()]) : new SNodeReference[0]);
    }

    refactoring.performRefactoring(field, selectedConstructors, repository);
    event.getData(MPSEditorDataKeys.EDITOR_CONTEXT).getEditorComponent().update();
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept FieldDeclaration$ie = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca68L, "jetbrains.mps.baseLanguage.structure.FieldDeclaration");
    /*package*/ static final SConcept ClassConcept$bK = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept");
    /*package*/ static final SConcept ConstructorDeclaration$yG = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b204L, "jetbrains.mps.baseLanguage.structure.ConstructorDeclaration");
    /*package*/ static final SConcept Classifier$Ix = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier");
  }
}
