* @param type the @{link AnchorType} of the anchor, or null to capture any type.
* @param next true if the search is forwards, false for backwards
* @return the adjacent anchor, or null if no such anchor is found
*/
private Anchor getAdjacentAnchor(Anchor anchor, AnchorType type, boolean next) {
Line currentLine = anchor.getLine();
AnchorList list = getAnchors(currentLine);
// Special case for the same line
int insertionIndex = list.findInsertionIndex(anchor);
int lowerBound = next ? 0 : 1;
int upperBound = next ? list.size() - 2 : list.size() - 1;
if (insertionIndex >= lowerBound && insertionIndex <= upperBound) {
Anchor anchorInList = list.get(insertionIndex);
if (anchor == anchorInList) {
// We found the anchor in the list, and we have a neighbor to return
Anchor candidateAnchor;
if (next) {
candidateAnchor = list.get(insertionIndex + 1);
} else {
candidateAnchor = list.get(insertionIndex - 1);
}
// Enforce the type
if (type != null && !candidateAnchor.getType().equals(type)) {
return getAdjacentAnchor(candidateAnchor, type, next);
} else {
return candidateAnchor;
}
}
// Otherwise, the anchor must be on another line
}
currentLine = next ? currentLine.getNextLine() : currentLine.getPreviousLine();
while (currentLine != null) {
list = getAnchorsOrNull(currentLine);
if (list != null && list.size() > 0) {
Anchor candidateAnchor;
if (next) {
candidateAnchor = list.get(0);
} else {
candidateAnchor = list.get(list.size() - 1);
}
// Enforce the type
if (type != null && !candidateAnchor.getType().equals(type)) {
return getAdjacentAnchor(candidateAnchor, type, next);
} else {
return candidateAnchor;
}
}
currentLine = next ? currentLine.getNextLine() : currentLine.getPreviousLine();
}
return null;
}