/*
* Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC
* All rights reserved.
*
* The source code of this document is proprietary work, and is not licensed for
* distribution. For information about licensing, contact Sam Harwell at:
* sam@tunnelvisionlabs.com
*/
package org.antlr.netbeans.editor.text.impl;
import org.antlr.netbeans.editor.text.DocumentChange;
import org.antlr.netbeans.editor.text.DocumentVersion;
import org.antlr.netbeans.editor.text.NormalizedDocumentChangeCollection;
import org.antlr.netbeans.editor.text.TrackingFidelity;
import org.antlr.netbeans.editor.text.TrackingPosition;
import org.netbeans.api.annotations.common.NonNull;
import org.openide.util.Parameters;
/**
*
* @author Sam Harwell
*/
public class NbForwardTrackingPosition extends NbTrackingPosition {
public NbForwardTrackingPosition(@NonNull NbDocumentVersion textVersion, int position, @NonNull TrackingPosition.Bias bias) {
super(textVersion, position, bias);
}
@Override
public TrackingFidelity getTrackingFidelity() {
return TrackingFidelity.Forward;
}
@Override
public int getOffset(DocumentVersion version, DocumentVersion cachedVersion, int cachedPosition) {
Parameters.notNull("version", version);
if (version.equals(this.getTextVersion())) {
return getPosition();
}
if (version.equals(cachedVersion)) {
return cachedPosition;
}
if (!version.getVersionedDocument().equals(this.getVersionedDocument())) {
throw new IllegalArgumentException();
}
DocumentVersion sourceVersion;
int sourcePosition;
if (version.getVersionNumber() > cachedVersion.getVersionNumber()) {
sourceVersion = cachedVersion;
sourcePosition = cachedPosition;
} else if (version.getVersionNumber() > getTextVersion().getVersionNumber()) {
sourceVersion = getTextVersion();
sourcePosition = getPosition();
} else {
throw new UnsupportedOperationException("This tracking point has forward fidelity.");
}
boolean positive = getBias() == TrackingPosition.Bias.Forward;
for (DocumentVersion currentVersion = sourceVersion; currentVersion != null && currentVersion.getVersionNumber() < version.getVersionNumber(); currentVersion = currentVersion.getNext()) {
NormalizedDocumentChangeCollection changes = currentVersion.getChanges();
DocumentChange relevantChange = null;
for (DocumentChange change : changes) {
boolean relevant = sourcePosition >= change.getOldOffset();
if (relevant) {
relevantChange = change;
} else {
break;
}
}
if (relevantChange != null) {
if (sourcePosition >= relevantChange.getOldOffset() && sourcePosition <= relevantChange.getOldEnd()) {
sourcePosition = relevantChange.getNewOffset();
if (positive) {
sourcePosition += relevantChange.getNewLength();
}
} else {
sourcePosition += relevantChange.getNewOffset() - relevantChange.getOldOffset();
sourcePosition += relevantChange.getDelta();
}
}
}
return sourcePosition;
}
@Override
public String toString() {
return String.format("V%d %s@%s", getTextVersion().getVersionNumber(), getBias().toString(), getPosition());
}
}