package jetbrains.mps.ide.embeddableEditor;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import javax.swing.JPanel;
import com.intellij.openapi.actionSystem.DataProvider;
import jetbrains.mps.project.Project;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.ide.editor.MPSFileNodeEditor;
import java.awt.BorderLayout;
import org.jetbrains.annotations.NotNull;
import java.awt.Color;
import jetbrains.mps.ide.editor.NodeEditor;
import jetbrains.mps.openapi.editor.Editor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import jetbrains.mps.workbench.MPSDataKeys;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.smodel.tempmodel.TemporaryModels;
import jetbrains.mps.smodel.tempmodel.TempModuleOptions;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.nodefs.NodeVirtualFileSystem;
import javax.swing.JComponent;

@GeneratedClass(node = "r:00000000-0000-4000-0000-011c895904a6(jetbrains.mps.ide.embeddableEditor)/1757086175614073066", model = "r:00000000-0000-4000-0000-011c895904a6(jetbrains.mps.ide.embeddableEditor)")
public class EmbeddableEditor extends JPanel implements DataProvider {
  private final Project project;
  private final SRepository repository;
  private final boolean editable;

  private SModel temporaryModel;

  private SNode node;
  private MPSFileNodeEditor nodeEditor;

  public EmbeddableEditor(Project project, boolean editable) {
    // todo: merge with UIEditorComponent ?
    super(new BorderLayout());
    this.project = project;
    this.repository = project.getRepository();
    this.editable = editable;
  }

  public void editNode(@NotNull final SNode node) {
    MPSFileNodeEditor oldEditor = nodeEditor;

    this.node = node;
    nodeEditor = createEditorForNode(node);
    removeAll();
    add(nodeEditor.getComponent(), BorderLayout.CENTER);
    if (oldEditor != null) {
      oldEditor.dispose();
    }
  }

  public void selectNode(SNode node) {
    nodeEditor.getNodeEditor().showNode(node, true);
  }

  public SNode getNode() {
    return node;
  }

  public void setBackground(Color color) {
    if (nodeEditor != null && nodeEditor.getNodeEditor() instanceof NodeEditor) {
      ((NodeEditor) nodeEditor.getNodeEditor()).getCurrentEditorComponent().setBackground(color);
    }
  }

  public Editor getEditor() {
    return nodeEditor.getNodeEditor();
  }

  @Nullable
  @Override
  public Object getData(@NonNls String dataId) {
    if (dataId.equals(MPSDataKeys.FILE_EDITOR.getName())) {
      return nodeEditor;
    }
    return null;
  }

  private MPSFileNodeEditor createEditorForNode(SNode node) {
    if (SNodeOperations.getModel(node) == null) {
      // node is not in repository
      if (!(editable)) {
        if (temporaryModel == null) {
          temporaryModel = TemporaryModels.getInstance().createReadOnly(TempModuleOptions.forDefaultModule());
        }
        SModelOperations.addRootNode(temporaryModel, node);
        TemporaryModels.getInstance().addMissingImports(temporaryModel);
      } else {
        throw new IllegalStateException("For nodes not from repository edit mode is disabled");
      }
    }
    return new MPSFileNodeEditor((MPSProject) project, NodeVirtualFileSystem.getInstance().getFileFor(repository, node));
  }

  public void disposeEditor() {
    if (temporaryModel != null) {
      repository.getModelAccess().runWriteAction(() -> TemporaryModels.getInstance().dispose(temporaryModel));
    }
    if (nodeEditor != null) {
      nodeEditor.dispose();
    }
  }

  public JComponent getPreferredFocusedComponent() {
    return nodeEditor.getPreferredFocusedComponent();
  }
}
