package jetbrains.mps.kotlin.editor;

/*Generated by MPS */

import jetbrains.mps.editor.runtime.cells.KeyMapImpl;
import jetbrains.mps.openapi.editor.cells.KeyMapAction;
import jetbrains.mps.editor.runtime.cells.KeyMapActionImpl;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.List;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.openapi.editor.cells.EditorCell_Label;
import jetbrains.mps.editor.runtime.selection.SelectionUtil;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.openapi.editor.selection.SelectionManager;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SProperty;

public class StringLiteral_InsertExpression extends KeyMapImpl {
  public StringLiteral_InsertExpression() {
    this.setApplicableToEveryModel(false);
    KeyMapAction action;
    action = new StringLiteral_InsertExpression_Action0();
    this.putAction("any", "$", action);
  }
  public static class StringLiteral_InsertExpression_Action0 extends KeyMapActionImpl {
    public StringLiteral_InsertExpression_Action0() {
      this.setShownInPopupMenu(false);
    }
    public boolean isMenuAlwaysShown() {
      return false;
    }
    public boolean canExecute(final EditorContext editorContext) {
      EditorCell contextCell = editorContext.getContextCell();
      if ((contextCell == null)) {
        return false;
      }
      SNode contextNode = contextCell.getSNode();
      if (contextNode == null) {
        return false;
      }
      if (!(SNodeOperations.isInstanceOf(contextNode, CONCEPTS.StringLiteralRaw$ar))) {
        return false;
      }
      return true;
    }
    public void execute(final EditorContext editorContext) {
      EditorCell contextCell = editorContext.getContextCell();
      this.execute_internal(editorContext, contextCell.getSNode(), this.getSelectedNodes(editorContext));
    }
    private void execute_internal(final EditorContext editorContext, final SNode node, final List<SNode> selectedNodes) {
      SNode expr = SNodeFactoryOperations.createNewNode(CONCEPTS.StringExpressionEvaluation$dm, null);

      if (isEmptyString(SPropertyOperations.getString(node, PROPS.content$3$6V))) {
        SNodeOperations.replaceWithAnother(node, expr);
      } else {
        // Try to get selection precisely
        EditorCell selectedCell = editorContext.getSelectedCell();
        // TODO assert selected == content cell?
        if (selectedCell instanceof EditorCell_Label) {
          int selectionEnd = ((EditorCell_Label) selectedCell).getSelectionEnd();
          String textBefore = SPropertyOperations.getString(node, PROPS.content$3$6V).substring(0, selectionEnd);

          // Allow insertion of \$
          if (textBefore.endsWith("\\")) {
            SPropertyOperations.assign(node, PROPS.content$3$6V, textBefore + "$" + SPropertyOperations.getString(node, PROPS.content$3$6V).substring(selectionEnd));
            SelectionUtil.selectLabelCellAnSetCaret(editorContext, node, "textContent", selectionEnd + 1);
            return;
          }

          if ((textBefore == null || textBefore.length() == 0)) {
            SNodeOperations.insertPrevSiblingChild(node, expr);
          } else {
            // Add as next sibling and clean text
            SNodeOperations.insertNextSiblingChild(node, expr);
            String textAfter = SPropertyOperations.getString(node, PROPS.content$3$6V).substring(selectionEnd);
            SPropertyOperations.assign(node, PROPS.content$3$6V, textBefore);

            // Create new node with remaining text
            if ((textAfter != null && textAfter.length() > 0)) {
              SNode nodeAfter = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x11400bb790af28ddL, "jetbrains.mps.kotlin.structure.StringLiteralRaw"));
              SPropertyOperations.assign(nodeAfter, PROPS.content$3$6V, textAfter);
              SNodeOperations.insertNextSiblingChild(expr, nodeAfter);
            }
          }
        } else {
          SNodeOperations.insertNextSiblingChild(node, expr);
        }
      }

      SelectionUtil.selectCell(editorContext, expr, SelectionManager.FIRST_EDITABLE_CELL);
    }
    public String getKeyStroke() {
      return " $";
    }
    private static boolean isEmptyString(String str) {
      return str == null || str.isEmpty();
    }
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept StringLiteralRaw$ar = MetaAdapterFactory.getConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x11400bb790af28ddL, "jetbrains.mps.kotlin.structure.StringLiteralRaw");
    /*package*/ static final SConcept StringExpressionEvaluation$dm = MetaAdapterFactory.getConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af3a3L, "jetbrains.mps.kotlin.structure.StringExpressionEvaluation");
  }

  private static final class PROPS {
    /*package*/ static final SProperty content$3$6V = MetaAdapterFactory.getProperty(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x11400bb790af28ddL, 0x11400bb790af28deL, "content");
  }
}
