package jetbrains.mps.lang.editor.diagram.runtime.jetpad.palette.impl;

/*Generated by MPS */

import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.jetpad.projectional.view.ViewTrait;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.nodeEditor.cells.jetpad.DiagramCell;
import jetbrains.mps.openapi.editor.cells.SubstituteAction;
import jetbrains.mps.smodel.action.NodeSubstituteActionWrapper;
import org.jetbrains.annotations.Nullable;
import jetbrains.jetpad.projectional.view.ViewTraitBuilder;
import jetbrains.jetpad.projectional.view.ViewEvents;
import jetbrains.jetpad.projectional.view.ViewEventHandler;
import jetbrains.jetpad.event.MouseEvent;
import jetbrains.jetpad.projectional.view.View;
import jetbrains.mps.nodeEditor.cells.jetpad.JetpadUtils;
import jetbrains.mps.editor.runtime.commands.EditorCommand;

public class PaletteConnectorCreationAction extends AbstractPaletteCreationAction {
  private _FunctionTypes._return_P4_E0<? extends Boolean, ? super SNode, ? super Object, ? super SNode, ? super Object> myCanCreateConnectorCallback;
  private _FunctionTypes._void_P5_E0<? super SNode, ? super SNode, ? super Object, ? super SNode, ? super Object> mySetConnectorCallBack;
  private ViewTrait myTrait;
  private EditorContext myEditorContext;
  public PaletteConnectorCreationAction(DiagramCell diagramCell, SubstituteAction action, final _FunctionTypes._return_P4_E0<? extends Boolean, ? super SNode, ? super Object, ? super SNode, ? super Object> canCreateConnector, final _FunctionTypes._void_P5_E0<? super SNode, ? super SNode, ? super Object, ? super SNode, ? super Object> setConnectorCallback, EditorContext editorContext) {
    super(diagramCell, action);
    myCanCreateConnectorCallback = canCreateConnector;
    mySetConnectorCallBack = setConnectorCallback;
    myEditorContext = myDiagramCell.getContext();
  }

  protected SubstituteAction createSubstituteAction(SubstituteAction action) {
    return new NodeSubstituteActionWrapper(action) {
      @Override
      public SNode substitute(@Nullable EditorContext context, String string) {
        SNode result = super.substitute(context, string);
        DiagramCell.ConnectionInfo connectionInfo = myDiagramCell.getConnectionInfo();
        mySetConnectorCallBack.invoke(result, connectionInfo.getFromNode(), connectionInfo.getFromId(), connectionInfo.getToNode(), connectionInfo.getToId());
        return result;

      }

      @Override
      public boolean canSubstitute(String string) {
        if (!(super.canSubstitute(string))) {
          return false;
        }
        DiagramCell.ConnectionInfo connectionInfo = myDiagramCell.getConnectionInfo();
        return connectionInfo.isValid() && myCanCreateConnectorCallback.invoke(connectionInfo.getFromNode(), connectionInfo.getFromId(), connectionInfo.getToNode(), connectionInfo.getToId());
      }
    };
  }
  protected ViewTrait getTrait() {
    if (myTrait == null) {
      myTrait = new ViewTraitBuilder().on(ViewEvents.MOUSE_DRAGGED, new ViewEventHandler<MouseEvent>() {
        @Override
        public void handle(View view, MouseEvent event) {
          if (!(myDiagramCell.hasConnectionDragFeedback())) {
            View sourceView = view.viewAt(event.location());
            if (sourceView == null || !(check_y3ke3n_a0a1a0a0a0b0a0a0a0a0h(sourceView.prop(JetpadUtils.CONNECTION_SOURCE).get()))) {
              return;
            }
            myDiagramCell.showConnectionDragFeedback(sourceView);
          }
          myDiagramCell.updateConnectionDragFeedback(event.location());
        }
      }).on(ViewEvents.MOUSE_RELEASED, new ViewEventHandler<MouseEvent>() {
        @Override
        public void handle(View view, MouseEvent event) {
          if (!(myDiagramCell.hasConnectionDragFeedback())) {
            return;
          }
          myDiagramCell.hideConnectionDragFeedback();

          final boolean[] result = new boolean[]{false};
          myEditorContext.getRepository().getModelAccess().runReadAction(new Runnable() {
            public void run() {
              result[0] = mySubstituteAction.canSubstitute("");
            }
          });
          if (!(result[0])) {
            return;
          }
          myEditorContext.getRepository().getModelAccess().executeCommand(new EditorCommand(myEditorContext) {
            protected void doExecute() {
              mySubstituteAction.substitute(myEditorContext, "");
            }
          });
          event.consume();

        }
      }).build();
    }
    return myTrait;
  }


  private static boolean check_y3ke3n_a0a1a0a0a0b0a0a0a0a0h(Boolean checkedDotOperand) {
    if (null != checkedDotOperand) {
      return checkedDotOperand.booleanValue();
    }
    return false;
  }
}
