/**
  * Is the given position near an already selected figure?
  *
  * @param x x-coordinate of point to check
  * @param y y-coordinate of point to check
  * @return whether the checked point is near an already selected figure.
  */
 private boolean isNearSelected(int x, int y) {
   boolean result = false;
   for (Figure f : view.getModel().getFigures()) {
     if (view.getSelection().contains(f) && f.contains(x, y)) {
       result = true;
       break;
     }
   }
   return result;
 }
  @Override
  public void mouseUp(int i, int j, MouseEvent e) {
    if (currentHandle != null) {
      currentHandle.stopInteraction(i, j, e, view);
      currentHandle = null;
      return;
    }

    if (selMode) {
      selMode = false;
      view.setSelectionRubberBand(null);
      view.repaint();
    }

    if (e.isShiftDown() && e.getX() == originalX && e.getY() == originalY) {
      for (Figure f : view.getModel().getFigures()) {
        if (f.contains(originalX, originalY)) {
          if (view.getSelection().contains(f) && f != lastSelectedFigure) {
            view.removeFromSelection(f);
          }
          view.repaint();
          break;
        }
      }
    }
  }
  @Override
  public void mouseDown(int constrainedX, int constrainedY, MouseEvent e) {
    originalX = e.getX();
    originalY = e.getY();
    tempX = constrainedX;
    tempY = constrainedY;

    // 0. check, whether a handle is selected
    lastSelectedFigure = null;
    currentHandle = view.getHandle(originalX, originalY, e);
    if (currentHandle != null) {
      currentHandle.startInteraction(constrainedX, constrainedY, e, view);
      return;
    }

    // 1. check, whether mouse position is near by an already
    //    selected figure; in this case keep selection
    if (!isNearSelected(originalX, originalY)) {

      // 2. if click is outside of existing selection then
      //    deselect all figures - except if shift is down
      //    (modifier used to extend selection)
      if (!e.isShiftDown()) {
        view.clearSelection();
      }

      // 3. look for new figures (which are not already
      //    selected) and select them. Only one figure.
      List<Figure> figures = new LinkedList<Figure>();
      for (Figure f : view.getModel().getFigures()) {
        figures.add(0, f);
      }
      for (Figure f : figures) {
        if (f.contains(originalX, originalY) && !view.getSelection().contains(f)) {
          view.addToSelection(f);
          lastSelectedFigure = f;
          break;
        }
      }

      // 4. if dragging mouse for spanning a selection, remember starting position (sx0, sy0) and
      // initialize
      //    current position (sx1, sy1).
      if (lastSelectedFigure == null && !e.isShiftDown()) {
        sx0 = originalX;
        sy0 = originalY;
        sx1 = originalX;
        sy1 = originalY;
        selMode = true;
      }
    }
    view.repaint();
  }
  @Override
  public void mouseDrag(int i, int j, java.awt.event.MouseEvent e) {
    if (currentHandle != null) {
      currentHandle.dragInteraction(i, j, e, view);
      return;
    }

    if (selMode) {
      sx1 = e.getX();
      sy1 = e.getY();
      Set<Figure> sel = new HashSet<Figure>();
      Rectangle selRectangle =
          new Rectangle(min(sx0, sx1), min(sy0, sy1), abs(sx1 - sx0), abs(sy1 - sy0));

      for (Figure f : view.getModel().getFigures()) {
        if (contains(selRectangle, f.getBounds())) {
          sel.add(f);
        }
      }
      view.setSelectionRubberBand(selRectangle);
      view.clearSelection();
      for (Figure f : sel) {
        view.addToSelection(f);
      }
      view.repaint();
      return;
    }

    int k = i - tempX;
    int l = j - tempY;

    for (Figure f : view.getSelection()) {
      f.move(k, l);
      view.getModel().getDrawCommandHandler().addCommand(new MoveCommand(f, k, l));
    }

    tempX = i;
    tempY = j;
    view.repaint();
  }