package jetbrains.mps.lang.generator.pluginSolution.plugin;

/*Generated by MPS */

import com.intellij.openapi.ui.DialogWrapper;
import jetbrains.mps.openapi.editor.EditorContext;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.List;
import javax.swing.JComboBox;
import jetbrains.mps.project.MPSProject;
import javax.swing.JPanel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import org.jetbrains.annotations.Nullable;
import javax.swing.JComponent;
import java.awt.Insets;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.IAttributeDescriptor;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SReferenceLink;

public class AttachMappingLabelDialog extends DialogWrapper {
  protected EditorContext myEditorContext;
  private SNode myTemplateNode;
  private List<String> myExistingLabels;
  private String myResultLabelName = "";
  private JComboBox myNameCombo;
  public AttachMappingLabelDialog(SNode templateNode, List<String> existingLabels, EditorContext editorContext, MPSProject mpsProject) {
    super(mpsProject.getProject());
    setTitle("Attach Mapping Label");
    this.myExistingLabels = existingLabels;
    this.myEditorContext = editorContext;
    this.myTemplateNode = templateNode;
    init();
  }
  private JPanel createNamePanel() {
    JPanel namePanel = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    namePanel.add(new JLabel("Mapping label: "), c);
    c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 1;
    c.gridx = 1;
    myNameCombo = new JComboBox(ListSequence.fromList(this.myExistingLabels).toGenericArray(String.class));
    myNameCombo.setEditable(true);
    namePanel.add(myNameCombo, c);
    if (ListSequence.fromList(this.myExistingLabels).isNotEmpty()) {
      String selectedItem = ListSequence.fromList(this.myExistingLabels).first();
      myNameCombo.setSelectedItem(selectedItem);
      setResultLabelName(selectedItem);
      JTextField textField = ((JTextField) myNameCombo.getEditor().getEditorComponent());
      textField.setSelectionStart(0);
      textField.setSelectionEnd(selectedItem.length());
    }
    // myNameCombo.setSelectedItem above triggers actionPerformed event, attach listener once combo is initialized
    myNameCombo.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent p0) {
        AttachMappingLabelDialog.this.setResultLabelName((String) myNameCombo.getSelectedItem());
        AttachMappingLabelDialog.this.getOKAction().actionPerformed(p0);
      }
    });
    return namePanel;
  }
  @Nullable
  @Override
  protected JComponent createCenterPanel() {
    setOKButtonText("Attach label");
    //  
    JPanel panel = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.insets = new Insets(3, 3, 3, 3);
    c.gridx = 0;
    c.gridy = 0;
    c.weightx = 1;
    c.weighty = 0;
    panel.add(createNamePanel(), c);
    return panel;
  }
  @Override
  protected void doOKAction() {
    super.doOKAction();
    doAttachMappingLabel();
  }
  @Nullable
  @Override
  public JComponent getPreferredFocusedComponent() {
    return myNameCombo;
  }

  /*package*/ void setResultLabelName(String labelName) {
    myResultLabelName = labelName;
  }

  protected void doAttachMappingLabel() {
    myEditorContext.getRepository().getModelAccess().executeCommand(() -> {
      SNode mappingLabel = MappingLabelUtil.findOrCreateMappingLabelForName(AttachMappingLabelDialog.this.myTemplateNode, AttachMappingLabelDialog.this.myResultLabelName);
      SNode existingMacro = ListSequence.fromList(new IAttributeDescriptor.NodeAttribute(CONCEPTS.NodeMacro$qU).list(AttachMappingLabelDialog.this.myTemplateNode)).last();
      if (existingMacro != null) {
        SLinkOperations.setTarget(existingMacro, LINKS.mappingLabel$jbOO, mappingLabel);
        return;
      }
      SNode templateFragment = new IAttributeDescriptor.NodeAttribute(CONCEPTS.TemplateFragment$eq).get(AttachMappingLabelDialog.this.myTemplateNode);
      if (templateFragment != null) {
        SLinkOperations.setTarget(templateFragment, LINKS.labelDeclaration$ORJN, mappingLabel);
        return;
      }
      // create new Label macro
      SNode newMacro = SNodeFactoryOperations.addNewAttribute(AttachMappingLabelDialog.this.myTemplateNode, new IAttributeDescriptor.NodeAttribute(CONCEPTS.NodeMacro$qU), CONCEPTS.LabelMacro$Lz);
      SLinkOperations.setTarget(newMacro, LINKS.mappingLabel$jbOO, mappingLabel);
    });
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept NodeMacro$qU = MetaAdapterFactory.getConcept(0xb401a68083254110L, 0x8fd384331ff25befL, 0xfd47ed6742L, "jetbrains.mps.lang.generator.structure.NodeMacro");
    /*package*/ static final SConcept TemplateFragment$eq = MetaAdapterFactory.getConcept(0xb401a68083254110L, 0x8fd384331ff25befL, 0xff1b29b76cL, "jetbrains.mps.lang.generator.structure.TemplateFragment");
    /*package*/ static final SConcept LabelMacro$Lz = MetaAdapterFactory.getConcept(0xb401a68083254110L, 0x8fd384331ff25befL, 0x473cc5baf8a1e7a4L, "jetbrains.mps.lang.generator.structure.LabelMacro");
  }

  private static final class LINKS {
    /*package*/ static final SReferenceLink mappingLabel$jbOO = MetaAdapterFactory.getReferenceLink(0xb401a68083254110L, 0x8fd384331ff25befL, 0xfd47ed6742L, 0x1179bf24befL, "mappingLabel");
    /*package*/ static final SReferenceLink labelDeclaration$ORJN = MetaAdapterFactory.getReferenceLink(0xb401a68083254110L, 0x8fd384331ff25befL, 0xff1b29b76cL, 0x1179c366b2fL, "labelDeclaration");
  }
}
