/**
   * Generates a random trackball event. This consists of a sequence of small moves, followed by an
   * optional single click.
   *
   * <p>TODO: Longpress. TODO: Meta state TODO: Parameterize the % clicked 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
   */
  private void generateTrackballEvent(Random random) {
    Display display = WindowManagerImpl.getDefault().getDefaultDisplay();

    boolean drop = false;
    int count = random.nextInt(10);
    MonkeyMotionEvent e;
    for (int i = 0; i < 10; ++i) {
      // generate a small random step
      int dX = random.nextInt(10) - 5;
      int dY = random.nextInt(10) - 5;

      e =
          new MonkeyMotionEvent(
              MonkeyEvent.EVENT_TYPE_TRACKBALL, -1, MotionEvent.ACTION_MOVE, dX, dY, 0);
      e.setIntermediateNote(i > 0);
      mQ.addLast(e);
    }

    // 10% of trackball moves end with a click
    if (0 == random.nextInt(10)) {
      long downAt = SystemClock.uptimeMillis();

      e =
          new MonkeyMotionEvent(
              MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, MotionEvent.ACTION_DOWN, 0, 0, 0);
      e.setIntermediateNote(true);
      mQ.addLast(e);

      e =
          new MonkeyMotionEvent(
              MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, MotionEvent.ACTION_UP, 0, 0, 0);
      e.setIntermediateNote(false);
      mQ.addLast(e);
    }
  }
  /**
   * 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 motionEvent If false, touch/release. If true, touch/move/release.
   */
  private void generateMotionEvent(Random random, boolean motionEvent) {

    Display display = WindowManagerImpl.getDefault().getDefaultDisplay();

    float x = Math.abs(random.nextInt() % display.getWidth());
    float y = Math.abs(random.nextInt() % display.getHeight());
    long downAt = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();
    if (downAt == -1) {
      downAt = eventTime;
    }

    MonkeyMotionEvent e =
        new MonkeyMotionEvent(
            MonkeyEvent.EVENT_TYPE_POINTER, downAt, MotionEvent.ACTION_DOWN, x, y, 0);
    e.setIntermediateNote(false);
    mQ.addLast(e);

    // sometimes we'll move during the touch
    if (motionEvent) {
      int count = random.nextInt(10);
      for (int i = 0; i < count; i++) {
        // generate some slop in the up event
        x = (x + (random.nextInt() % 10)) % display.getWidth();
        y = (y + (random.nextInt() % 10)) % display.getHeight();

        e =
            new MonkeyMotionEvent(
                MonkeyEvent.EVENT_TYPE_POINTER, downAt, MotionEvent.ACTION_MOVE, x, y, 0);
        e.setIntermediateNote(true);
        mQ.addLast(e);
      }
    }

    // TODO generate some slop in the up event
    e =
        new MonkeyMotionEvent(
            MonkeyEvent.EVENT_TYPE_POINTER, downAt, MotionEvent.ACTION_UP, x, y, 0);
    e.setIntermediateNote(false);
    mQ.addLast(e);
  }