package jetbrains.mps.ide.platform.refactoring;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.model.SModelReference;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.module.SModuleReference;
import jetbrains.mps.smodel.LanguageAspect;
import jetbrains.mps.smodel.Language;
import org.jetbrains.mps.openapi.module.SModule;

@GeneratedClass(node = "r:986938bb-bdb1-4307-b062-e4647a4db0f9(jetbrains.mps.ide.platform.refactoring)/1929018697514833165", model = "r:986938bb-bdb1-4307-b062-e4647a4db0f9(jetbrains.mps.ide.platform.refactoring)")
public interface NodeLocation {
  boolean canInsert(SRepository repository, SNode nodeToMove);
  void insertNode(SRepository repository, SNode nodeToMove);
  boolean isRoot();
  class NodeLocationChild implements NodeLocation {
    private SNodeReference parent;
    private SContainmentLink role;
    public NodeLocationChild(SNode parent, SContainmentLink role) {
      this(parent);
      this.role = role;
    }
    public NodeLocationChild(SNode parent) {
      this.parent = parent.getReference();
    }
    public void setRole(SContainmentLink role) {
      this.role = role;
    }
    public boolean isRoot() {
      return false;
    }
    public SNodeReference getNode() {
      return parent;
    }
    public SContainmentLink getRole() {
      return role;
    }
    public boolean canInsert(SRepository repository, SNode nodeToMove) {
      SNode node = parent.resolve(repository);
      return role != null && node != null && node.getModel() != null && !(node.getModel().isReadOnly()) && node.getConcept().getContainmentLinks().contains(role) && SConceptOperations.isSubConceptOf(SNodeOperations.asSConcept(SNodeOperations.getConcept(nodeToMove)), SNodeOperations.asSConcept(role.getTargetConcept()));
    }
    public void insertNode(SRepository repository, SNode nodeToMove) {
      parent.resolve(repository).addChild(role, nodeToMove);
    }
  }
  class NodeLocationRoot implements NodeLocation {
    private SModelReference myModel;
    public NodeLocationRoot(SModel model) {
      this.myModel = model.getReference();
    }
    public boolean canInsert(SRepository repository, SNode nodeToMove) {
      SModel modelResolved = myModel.resolve(repository);
      return modelResolved != null && !(modelResolved.isReadOnly()) && ((SConcept) SNodeOperations.getConcept(nodeToMove)).isRootable();
    }
    public boolean isRoot() {
      return true;
    }
    public void insertNode(SRepository repository, SNode nodeToMove) {
      myModel.resolve(repository).addRootNode(nodeToMove);
    }
  }
  class NodeLocationRootWithAspectModelCreation implements NodeLocation {
    private SModuleReference myLanguage;
    private LanguageAspect myAspect;
    public NodeLocationRootWithAspectModelCreation(Language languageModule, LanguageAspect aspect) {
      myLanguage = languageModule.getModuleReference();
      myAspect = aspect;
    }
    public boolean canInsert(SRepository repository, SNode nodeToMove) {
      SModule languageResolved = myLanguage.resolve(repository);
      return languageResolved instanceof Language && !(((Language) languageResolved).isReadOnly()) && ((SConcept) SNodeOperations.getConcept(nodeToMove)).isRootable();
    }
    public boolean isRoot() {
      return true;
    }
    public void insertNode(SRepository repository, SNode nodeToMove) {
      SModel model = myAspect.getOrCreate(((Language) myLanguage.resolve(repository)));
      model.addRootNode(nodeToMove);
    }
  }
}
