/**
   * Defaults to typical marquee behaviour when the marquee palette button is selected. Otherwise,
   * if there is nothing under the mouse upon a mouse press a new net element will be added. If
   * there is a vertex or condition under the mouse this method will not be invoked , relying
   * instead on the default behaviour of {@link BasicMarqueeHandler}, which is typically to begin a
   * select/drag operation on the element. If there is a valid outgoing flow under the mouse, this
   * is a trigger to begin drawing a flow relation.
   */
  public void mousePressed(MouseEvent event) {
    if (SwingUtilities.isRightMouseButton(event)
        || paletteBar.getState() == Palette.SelectionState.MARQUEE) {
      super.mousePressed(event);
      return;
    }

    State oldState = state;
    switch (oldState) {
      case ABOVE_VERTEX:
        {
          state = State.DRAGGING_VERTEX;
          break;
        }
      case ABOVE_OUTGOING_PORT:
        {
          state = State.DRAWING_FLOW_RELATION;
          getNet().setCursor(CursorFactory.getCustomCursor(CursorFactory.HIDDEN));
          break;
        }
      case ABOVE_CANVAS:
        {
          Point2D snapPoint = getNearestSnapPoint(event.getPoint());
          state = State.ABOVE_VERTEX;
          switch (paletteBar.getState()) {
            case CONDITION:
              {
                NetCellFactory.insertCondition(getNet(), snapPoint);
                break;
              }
            case ATOMIC_TASK:
              {
                NetCellFactory.insertAtomicTask(getNet(), snapPoint);
                break;
              }
            case MULTIPLE_ATOMIC_TASK:
              {
                NetCellFactory.insertMultipleAtomicTask(getNet(), snapPoint);
                break;
              }
            case COMPOSITE_TASK:
              {
                NetCellFactory.insertCompositeTask(getNet(), snapPoint);
                break;
              }
            case MULTIPLE_COMPOSITE_TASK:
              {
                NetCellFactory.insertMultipleCompositeTask(getNet(), snapPoint);
                break;
              }
          }
          break;
        }
    }
    doStateTransitionProcessing(event.getPoint(), oldState, state);
  }
  /**
   * Defaults to typical marquee behaviour unless a flow relation is being drawn. In that case, each
   * drag event will redraw a line from the mouse cursor to the source port. If there is a valid
   * incoming port under the mouse, this will also be highlighted to identify that a valid flow may
   * be drawn upon a mouse release event.
   */
  public void mouseDragged(MouseEvent event) {
    if (paletteBar.getState() == Palette.SelectionState.MARQUEE) {
      super.mouseDragged(event);
      return;
    }

    if (state == State.DRAWING_FLOW_RELATION) {
      if (sourcePort != null) {
        setCurrentPoint(getNet().snap(event.getPoint()));
        paintPotentialFlow();
        PortView portUnderMouse = getPortViewAt(event.getPoint());
        if (portUnderMouse != null
            && portUnderMouse != sourcePort
            && connectionAllowable(sourcePort, portUnderMouse)
            && acceptsIncomingFlows(portUnderMouse)) {
          if (portUnderMouse != targetPort) {
            targetPort = portUnderMouse;
            getOverlay().setTarget(net.toScreen(targetPort.getBounds()));
          }
        }
        if (portUnderMouse == null) {
          targetPort = null;
          getOverlay().setTarget(null);
        }
      }
      event.consume();
    }
  }
  /**
   * Defaults to typical marquee behaviour unless a flow relation is being drawn. In this case, the
   * mouse release event checks to see if there is a valid incoming port under the mouse. If so, a
   * flow relation will be established between the source and target ports, otherwise the flow is
   * ignrored.
   */
  public void mouseReleased(MouseEvent event) {
    if (paletteBar.getState() == Palette.SelectionState.MARQUEE) {
      super.mouseReleased(event);
      return;
    }

    if (state == State.DRAWING_FLOW_RELATION) {
      connectElementsOrIgnoreFlow();
      determineStateFromPoint(event.getPoint());
    }
    setCursorFromPalette();
    event.consume();
  }
  /**
   * Defaults to typical marquee behaviour if the PaletteBar is in Marquee mode, Otherwise, the
   * state of this marquee is determined through what lies underneath the mouse.
   *
   * @param event the mouse event
   */
  public void mouseMoved(MouseEvent event) {
    if (paletteBar.getState() == Palette.SelectionState.MARQUEE) {
      super.mouseMoved(event);
      return;
    }

    State oldState = state;
    state = determineStateFromPoint(event.getPoint());
    if (state == State.ABOVE_CANVAS) {
      setCursorFromPalette();
    }
    doStateTransitionProcessing(event.getPoint(), oldState, state);
    event.consume();
  }
 private int getCursorFromPaletteState() {
   switch (paletteBar.getState()) {
     case MARQUEE:
       return CursorFactory.SELECTION;
     case CONDITION:
       return CursorFactory.CONDITION;
     case ATOMIC_TASK:
       return CursorFactory.ATOMIC_TASK;
     case COMPOSITE_TASK:
       return CursorFactory.COMPOSITE_TASK;
     case MULTIPLE_ATOMIC_TASK:
       return CursorFactory.MULTIPLE_ATOMIC_TASK;
     case MULTIPLE_COMPOSITE_TASK:
       return CursorFactory.MULTIPLE_COMPOSITE_TASK;
   }
   return -1;
 }
 /**
  * Determines whether the default marquee behaviour is sufficient, or whether our own response to
  * mouse events are more appropriate. Specifically, we rely on the functionality of {@link
  * BasicMarqueeHandler} in the following scenarios:
  *
  * <ul>
  *   <li>When the PaletteBar is in Marquee mode
  *   <li>When the PaletteBar is not in Marquee mode, but the mouse is hovering above a Vertex,
  *   <li>When the PaletteBar is not in Marquee mode, but the mouse if hovering above a flow
  *       relation.
  *   <li>For the last two, if the mouse hovers above these elements, we want the default drag
  *       behaviour of {@link BasicMarqueeHandler} to be used on them. What remains in this class
  *       is the drawing of flows between net elements.
  */
 public boolean isForceMarqueeEvent(MouseEvent event) {
   Palette.SelectionState paletteState = paletteBar.getState();
   return paletteState != Palette.SelectionState.MARQUEE
       && !(state == State.ABOVE_VERTEX || state == State.ABOVE_FLOW_RELATION);
 }
 private void matchCursorTo(int cursorType) {
   getNet().setCursor(CursorFactory.getCustomCursor(cursorType));
   paletteBar.refreshSelected();
 }