/**
   * Generates a random motion event. This method counts a down, move, and up as multiple events.
   *
   * <p>TODO: Test & fix the selectors when non-zero percentages TODO: Longpress. TODO: Fling. TODO:
   * Meta state TODO: More useful than the random walk here would be to pick a single random
   * direction and distance, and divvy it up into a random number of segments. (This would serve to
   * generate fling gestures, which are important).
   *
   * @param random Random number source for positioning
   * @param gesture The gesture to perform.
   */
  private void generatePointerEvent(Random random, int gesture) {
    Display display = WindowManagerImpl.getDefault().getDefaultDisplay();

    PointF p1 = randomPoint(random, display);
    PointF v1 = randomVector(random);

    long downAt = SystemClock.uptimeMillis();

    mQ.addLast(
        new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
            .setDownTime(downAt)
            .addPointer(0, p1.x, p1.y)
            .setIntermediateNote(false));

    // sometimes we'll move during the touch
    if (gesture == GESTURE_DRAG) {
      int count = random.nextInt(10);
      for (int i = 0; i < count; i++) {
        randomWalk(random, display, p1, v1);

        mQ.addLast(
            new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
                .setDownTime(downAt)
                .addPointer(0, p1.x, p1.y)
                .setIntermediateNote(true));
      }
    } else if (gesture == GESTURE_PINCH_OR_ZOOM) {
      PointF p2 = randomPoint(random, display);
      PointF v2 = randomVector(random);

      randomWalk(random, display, p1, v1);
      mQ.addLast(
          new MonkeyTouchEvent(
                  MotionEvent.ACTION_POINTER_DOWN | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
              .setDownTime(downAt)
              .addPointer(0, p1.x, p1.y)
              .addPointer(1, p2.x, p2.y)
              .setIntermediateNote(true));

      int count = random.nextInt(10);
      for (int i = 0; i < count; i++) {
        randomWalk(random, display, p1, v1);
        randomWalk(random, display, p2, v2);

        mQ.addLast(
            new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
                .setDownTime(downAt)
                .addPointer(0, p1.x, p1.y)
                .addPointer(1, p2.x, p2.y)
                .setIntermediateNote(true));
      }

      randomWalk(random, display, p1, v1);
      randomWalk(random, display, p2, v2);
      mQ.addLast(
          new MonkeyTouchEvent(
                  MotionEvent.ACTION_POINTER_UP | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
              .setDownTime(downAt)
              .addPointer(0, p1.x, p1.y)
              .addPointer(1, p2.x, p2.y)
              .setIntermediateNote(true));
    }

    randomWalk(random, display, p1, v1);
    mQ.addLast(
        new MonkeyTouchEvent(MotionEvent.ACTION_UP)
            .setDownTime(downAt)
            .addPointer(0, p1.x, p1.y)
            .setIntermediateNote(false));
  }