package jetbrains.mps.ide.devkit.actions;

/*Generated by MPS */

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.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import java.util.Queue;
import jetbrains.mps.internal.collections.runtime.QueueSequence;
import java.util.LinkedList;
import jetbrains.mps.lang.structure.behavior.AbstractConceptDeclaration__BehaviorDescriptor;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModuleOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.ide.actions.MPSCommonDataKeys;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.ide.editor.MPSEditorDataKeys;
import jetbrains.mps.project.MPSProject;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.language.LanguageAspectDescriptor;
import jetbrains.mps.smodel.language.LanguageAspectSupport;
import jetbrains.mps.smodel.language.CreateAspectContext;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import jetbrains.mps.kernel.language.ConceptAspectsHelper;
import jetbrains.mps.lang.editor.behavior.AbstractComponent__BehaviorDescriptor;
import java.util.Objects;
import jetbrains.mps.lang.editor.behavior.ConceptEditorDeclaration__BehaviorDescriptor;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SProperty;

public class CreateDefaultEditor_Action extends BaseAction {
  private static final Icon ICON = null;

  public CreateDefaultEditor_Action() {
    super("Generate Default Editor (Expression-like)", "", 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 conceptDeclaration = SNodeOperations.as(((SNode) MapSequence.fromMap(_params).get("selectedNode")), CONCEPTS.ConceptDeclaration$gH);
    if (conceptDeclaration == null || SPropertyOperations.getBoolean(conceptDeclaration, PROPS.abstract$ibpT) || SPropertyOperations.getString(conceptDeclaration, PROPS.name$MnvL) == null) {
      return false;
    }

    Queue<SNode> toCheck = QueueSequence.fromQueue(new LinkedList<SNode>());
    QueueSequence.fromQueue(toCheck).addLastElement(conceptDeclaration);
    while (QueueSequence.fromQueue(toCheck).isNotEmpty()) {
      SNode acd = QueueSequence.fromQueue(toCheck).removeFirstElement();
      Iterable<SNode> aspects = AbstractConceptDeclaration__BehaviorDescriptor.findConceptAspects_id4G9PD8$NvPM.invoke(acd, SModuleOperations.getAspect(SNodeOperations.getModel(acd).getModule(), "editor"));
      if (!(SConceptOperations.isExactly(SNodeOperations.asSConcept(acd), CONCEPTS.BaseConcept$gP)) && Sequence.fromIterable(SNodeOperations.ofConcept(aspects, CONCEPTS.ConceptEditorDeclaration$BH)).isNotEmpty()) {
        return false;
      }
      QueueSequence.fromQueue(toCheck).addSequence(ListSequence.fromList(AbstractConceptDeclaration__BehaviorDescriptor.getImmediateSuperconcepts_idhMuxyK2.invoke(acd)));
    }
    return true;
  }
  @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 node = event.getData(MPSCommonDataKeys.NODE);
      MapSequence.fromMap(_params).put("selectedNode", node);
      if (node == null) {
        return false;
      }
    }
    {
      EditorContext p = event.getData(MPSEditorDataKeys.EDITOR_CONTEXT);
      MapSequence.fromMap(_params).put("editorContext", p);
      if (p == null) {
        return false;
      }
    }
    {
      MPSProject p = event.getData(MPSCommonDataKeys.MPS_PROJECT);
      MapSequence.fromMap(_params).put("project", p);
      if (p == null) {
        return false;
      }
    }
    return true;
  }
  @Override
  public void doExecute(@NotNull final AnActionEvent event, final Map<String, Object> _params) {
    SNode conceptDeclaration = SNodeOperations.as(((SNode) MapSequence.fromMap(_params).get("selectedNode")), CONCEPTS.ConceptDeclaration$gH);
    SModule module = SNodeOperations.getModel(conceptDeclaration).getModule();
    SModel editorAspect = SModuleOperations.getAspect(module, "editor");
    if (editorAspect == null) {
      // FIXME desperately need aspectIdentity(ref) operation to avoid hard-coded values
      LanguageAspectDescriptor ad = LanguageAspectSupport.getAspectDescriptorById("editor");
      CreateAspectContext cac = CreateAspectContext.create(module, ((MPSProject) MapSequence.fromMap(_params).get("project")).getPlatform(), null);
      if (ad != null && ad.canCreate(cac)) {
        ad.create(cac);
        editorAspect = SModuleOperations.getAspect(module, "editor");
      }
    }
    if (editorAspect == null) {
      return;
    }
    SNode editorDeclaration = SNodeFactoryOperations.createNewRootNode(editorAspect, CONCEPTS.ConceptEditorDeclaration$BH, null);
    ConceptAspectsHelper.attachNewConceptAspect(conceptDeclaration, editorDeclaration, editorAspect);
    assert AbstractComponent__BehaviorDescriptor.getConceptDeclaration_id67EYkym$wx3.invoke(editorDeclaration) != null;
    assert Objects.equals(AbstractComponent__BehaviorDescriptor.getConceptDeclaration_id67EYkym$wx3.invoke(editorDeclaration), conceptDeclaration);
    ConceptEditorDeclaration__BehaviorDescriptor.createDefaultEditor_id2$SWsiCt8Y$.invoke(editorDeclaration, ((boolean) false));
    if (((EditorContext) MapSequence.fromMap(_params).get("editorContext")).getEditorPanelManager() != null) {
      ((EditorContext) MapSequence.fromMap(_params).get("editorContext")).getEditorPanelManager().openEditor(editorDeclaration);
    } else {
      ((EditorContext) MapSequence.fromMap(_params).get("editorContext")).getEditorComponent().update();
    }
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept ConceptDeclaration$gH = MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0xf979ba0450L, "jetbrains.mps.lang.structure.structure.ConceptDeclaration");
    /*package*/ static final SConcept BaseConcept$gP = MetaAdapterFactory.getConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, "jetbrains.mps.lang.core.structure.BaseConcept");
    /*package*/ static final SConcept ConceptEditorDeclaration$BH = MetaAdapterFactory.getConcept(0x18bc659203a64e29L, 0xa83a7ff23bde13baL, 0xf9845363abL, "jetbrains.mps.lang.editor.structure.ConceptEditorDeclaration");
  }

  private static final class PROPS {
    /*package*/ static final SProperty abstract$ibpT = MetaAdapterFactory.getProperty(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x1103553c5ffL, 0x403a32c5772c7ec2L, "abstract");
    /*package*/ static final SProperty name$MnvL = MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name");
  }
}
