static Pair<Point, Short> chooseBestHintPosition(Editor editor,
                                                   VisualPosition pos,
                                                   LightweightHint hint,
                                                   LookupImpl activeLookup,
                                                   short preferredPosition,
                                                   boolean showLookupHint) {
    if (ApplicationManager.getApplication().isUnitTestMode() ||
        ApplicationManager.getApplication().isHeadlessEnvironment()) {
      return new Pair<>(new Point(), HintManager.DEFAULT);
    }

    HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
    Dimension hintSize = hint.getComponent().getPreferredSize();
    JComponent editorComponent = editor.getComponent();
    JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();

    Point p1;
    Point p2;
    if (showLookupHint) {
      p1 = hintManager.getHintPosition(hint, editor, HintManager.UNDER);
      p2 = hintManager.getHintPosition(hint, editor, HintManager.ABOVE);
    }
    else {
      p1 = HintManagerImpl.getHintPosition(hint, editor, pos, HintManager.UNDER);
      p2 = HintManagerImpl.getHintPosition(hint, editor, pos, HintManager.ABOVE);
    }

    boolean isRealPopup = hint.isRealPopup();

    boolean p1Ok, p2Ok;


    if (!showLookupHint && activeLookup != null && activeLookup.isShown()) {
      Rectangle lookupBounds = activeLookup.getBounds();

      p1Ok = p1.y + hintSize.height + 50 < layeredPane.getHeight() && !isHintIntersectWithLookup(p1, hintSize, lookupBounds, isRealPopup, HintManager.UNDER);
      p2Ok = p2.y - hintSize.height - 70 >= 0 && !isHintIntersectWithLookup(p2, hintSize, lookupBounds, isRealPopup, HintManager.ABOVE);

      if (activeLookup.isPositionedAboveCaret()) {
        if (!p1Ok) {
          var abovePoint = new Point(lookupBounds.x, lookupBounds.y - hintSize.height - 10);
          SwingUtilities.convertPointToScreen(abovePoint, layeredPane);
          abovePoint.move(lookupBounds.x, lookupBounds.y - hintSize.height - 10);
          hint.setForceShowAsPopup(true);
          return new Pair<>(abovePoint, HintManager.DEFAULT);
        }
      }
      else {
        if (!p2Ok) {
          var underPoint = new Point(lookupBounds.x, lookupBounds.y + lookupBounds.height + 10);
          SwingUtilities.convertPointToScreen(underPoint, layeredPane);
          var screenRectangle = new Rectangle(underPoint, hintSize);
          if (isFitTheScreen(screenRectangle)) {
            // calculate if hint can be shown under lookup
            underPoint.move(lookupBounds.x, lookupBounds.y + lookupBounds.height + 10);
            hint.setForceShowAsPopup(true);
            return new Pair<>(underPoint, HintManager.DEFAULT);
          }
          else {
            hint.setForceShowAsPopup(true);
            var abovePoint = new Point(p2.x - hintSize.width / 2, p2.y - hintSize.height);
            return new Pair<>(abovePoint, HintManager.ABOVE);
          }
        }
      }
    }
    else {
      p1Ok = p1.y + hintSize.height < layeredPane.getHeight();
      p2Ok = p2.y >= 0;
    }

    if (isRealPopup) {
      hint.setForceShowAsPopup(false);
    }


    if (!showLookupHint) {
      if (preferredPosition != HintManager.DEFAULT) {
        if (preferredPosition == HintManager.ABOVE) {
          if (p2Ok) return new Pair<>(p2, HintManager.ABOVE);
        }
        else if (preferredPosition == HintManager.UNDER) {
          if (p1Ok) return new Pair<>(p1, HintManager.UNDER);
        }
      }
    }
    if (p1Ok) return new Pair<>(p1, HintManager.UNDER);
    if (p2Ok) return new Pair<>(p2, HintManager.ABOVE);

    int underSpace = layeredPane.getHeight() - p1.y;
    int aboveSpace = p2.y;
    return aboveSpace > underSpace ? new Pair<>(new Point(p2.x, 0), HintManager.UNDER) : new Pair<>(p1,
                                                                                                    HintManager.ABOVE);
  }
static Pair<Point, Short> chooseBestHintPosition(Editor editor,
                                                   VisualPosition pos,
                                                   LightweightHint hint,
                                                   LookupImpl activeLookup,
                                                   short preferredPosition,
                                                   boolean showLookupHint)