// According to the event's position, change the focus to the first
  // hitting cropping rectangle.
  private void recomputeFocus(MotionEvent event) {

    for (int i = 0; i < mHighlightViews.size(); i++) {
      HighlightView hv = mHighlightViews.get(i);
      hv.setFocus(false);
      hv.invalidate();
    }

    for (int i = 0; i < mHighlightViews.size(); i++) {
      HighlightView hv = mHighlightViews.get(i);
      int edge = hv.getHit(event.getX(), event.getY());
      if (edge != HighlightView.GROW_NONE) {
        if (!hv.hasFocus()) {
          hv.setFocus(true);
          hv.invalidate();
        }
        break;
      }
    }
    invalidate();
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {

    CropImage cropImage = (CropImage) mContext;
    if (cropImage.mSaving) {
      return false;
    }

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        if (cropImage.mWaitingToPick) {
          recomputeFocus(event);
        } else {
          for (int i = 0; i < mHighlightViews.size(); i++) {
            HighlightView hv = mHighlightViews.get(i);
            int edge = hv.getHit(event.getX(), event.getY());
            if (edge != HighlightView.GROW_NONE) {
              mMotionEdge = edge;
              mMotionHighlightView = hv;
              mLastX = event.getX();
              mLastY = event.getY();
              mMotionHighlightView.setMode(
                  (edge == HighlightView.MOVE)
                      ? HighlightView.ModifyMode.Move
                      : HighlightView.ModifyMode.Grow);
              break;
            }
          }
        }
        break;
      case MotionEvent.ACTION_UP:
        if (cropImage.mWaitingToPick) {
          for (int i = 0; i < mHighlightViews.size(); i++) {
            HighlightView hv = mHighlightViews.get(i);
            if (hv.hasFocus()) {
              cropImage.mCrop = hv;
              for (int j = 0; j < mHighlightViews.size(); j++) {
                if (j == i) {
                  continue;
                }
                mHighlightViews.get(j).setHidden(true);
              }
              centerBasedOnHighlightView(hv);
              ((CropImage) mContext).mWaitingToPick = false;
              return true;
            }
          }
        } else if (mMotionHighlightView != null) {
          centerBasedOnHighlightView(mMotionHighlightView);
          mMotionHighlightView.setMode(HighlightView.ModifyMode.None);
        }
        mMotionHighlightView = null;
        break;
      case MotionEvent.ACTION_MOVE:
        if (cropImage.mWaitingToPick) {
          recomputeFocus(event);
        } else if (mMotionHighlightView != null) {
          mMotionHighlightView.handleMotion(
              mMotionEdge, event.getX() - mLastX, event.getY() - mLastY);
          mLastX = event.getX();
          mLastY = event.getY();

          if (true) {
            // This section of code is optional. It has some user
            // benefit in that moving the crop rectangle against
            // the edge of the screen causes scrolling but it means
            // that the crop rectangle is no longer fixed under
            // the user's finger.
            ensureVisible(mMotionHighlightView);
          }
        }
        break;
    }

    switch (event.getAction()) {
      case MotionEvent.ACTION_UP:
        center(true, true);
        break;
      case MotionEvent.ACTION_MOVE:
        // if we're not zoomed then there's no point in even allowing
        // the user to move the image around.  This call to center puts
        // it back to the normalized location (with false meaning don't
        // animate).
        if (getScale() == 1F) {
          center(true, true);
        }
        break;
    }

    return true;
  }