@Override
  public void onFingerMoveAfterLongPress(int x, int y) {
    final SelectionCursor.Which cursor = getSelectionCursorInMovement();
    if (cursor != null) {
      moveSelectionCursorTo(cursor, x, y);
      return;
    }

    ZLTextRegion region = getOutlinedRegion();
    if (region != null) {
      ZLTextRegion.Soul soul = region.getSoul();
      if (soul instanceof ZLTextHyperlinkRegionSoul || soul instanceof ZLTextWordRegionSoul) {
        if (myReader.MiscOptions.WordTappingAction.getValue()
            != MiscOptions.WordTappingActionEnum.doNothing) {
          region = findRegion(x, y, maxSelectionDistance(), ZLTextRegion.AnyRegionFilter);
          if (region != null) {
            soul = region.getSoul();
            if (soul instanceof ZLTextHyperlinkRegionSoul || soul instanceof ZLTextWordRegionSoul) {
              outlineRegion(region);
              myReader.getViewWidget().reset();
              myReader.getViewWidget().repaint();
            }
          }
        }
      }
    }
  }
  @Override
  public void onFingerReleaseAfterLongPress(int x, int y) {
    final SelectionCursor.Which cursor = getSelectionCursorInMovement();
    if (cursor != null) {
      releaseSelectionCursor();
      return;
    }

    final ZLTextRegion region = getOutlinedRegion();
    if (region != null) {
      final ZLTextRegion.Soul soul = region.getSoul();

      boolean doRunAction = false;
      if (soul instanceof ZLTextWordRegionSoul) {
        doRunAction =
            myReader.MiscOptions.WordTappingAction.getValue()
                == MiscOptions.WordTappingActionEnum.openDictionary;
      } else if (soul instanceof ZLTextImageRegionSoul) {
        doRunAction =
            myReader.ImageOptions.TapAction.getValue() == ImageOptions.TapActionEnum.openImageView;
      }

      if (doRunAction) {
        myReader.runAction(ActionCode.PROCESS_HYPERLINK);
      }
    }
  }
  @Override
  public void onFingerSingleTap(int x, int y) {
    final ZLTextRegion hyperlinkRegion =
        findRegion(x, y, maxSelectionDistance(), ZLTextRegion.HyperlinkFilter);
    if (hyperlinkRegion != null) {
      outlineRegion(hyperlinkRegion);
      myReader.getViewWidget().reset();
      myReader.getViewWidget().repaint();
      myReader.runAction(ActionCode.PROCESS_HYPERLINK);
      return;
    }

    final ZLTextRegion bookRegion = findRegion(x, y, 0, ZLTextRegion.ExtensionFilter);
    if (bookRegion != null) {
      myReader.runAction(ActionCode.DISPLAY_BOOK_POPUP, bookRegion);
      return;
    }

    final ZLTextRegion videoRegion = findRegion(x, y, 0, ZLTextRegion.VideoFilter);
    if (videoRegion != null) {
      outlineRegion(videoRegion);
      myReader.getViewWidget().reset();
      myReader.getViewWidget().repaint();
      myReader.runAction(ActionCode.OPEN_VIDEO, (ZLTextVideoRegionSoul) videoRegion.getSoul());
      return;
    }

    final ZLTextHighlighting highlighting = findHighlighting(x, y, maxSelectionDistance());
    if (highlighting instanceof BookmarkHighlighting) {
      myReader.runAction(
          ActionCode.SELECTION_BOOKMARK, ((BookmarkHighlighting) highlighting).Bookmark);
      return;
    }

    if (myReader.isActionEnabled(ActionCode.HIDE_TOAST)) {
      myReader.runAction(ActionCode.HIDE_TOAST);
      return;
    }

    onFingerSingleTapLastResort(x, y);
  }
  @Override
  public boolean onFingerLongPress(int x, int y) {
    myReader.runAction(ActionCode.HIDE_TOAST);

    final ZLTextRegion region =
        findRegion(x, y, maxSelectionDistance(), ZLTextRegion.AnyRegionFilter);
    if (region != null) {
      final ZLTextRegion.Soul soul = region.getSoul();
      boolean doSelectRegion = false;
      if (soul instanceof ZLTextWordRegionSoul) {
        switch (myReader.MiscOptions.WordTappingAction.getValue()) {
          case startSelecting:
            myReader.runAction(ActionCode.SELECTION_HIDE_PANEL);
            initSelection(x, y);
            final SelectionCursor.Which cursor = findSelectionCursor(x, y);
            if (cursor != null) {
              moveSelectionCursorTo(cursor, x, y);
            }
            return true;
          case selectSingleWord:
          case openDictionary:
            doSelectRegion = true;
            break;
        }
      } else if (soul instanceof ZLTextImageRegionSoul) {
        doSelectRegion =
            myReader.ImageOptions.TapAction.getValue() != ImageOptions.TapActionEnum.doNothing;
      } else if (soul instanceof ZLTextHyperlinkRegionSoul) {
        doSelectRegion = true;
      }

      if (doSelectRegion) {
        outlineRegion(region);
        myReader.getViewWidget().reset();
        myReader.getViewWidget().repaint();
        return true;
      }
    }
    return false;
  }