/*******************************************************************************
* Copyright (c) 2015 David Green.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Green - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.wikitext.commonmark.internal.inlines;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.mylyn.wikitext.commonmark.internal.Line;
import org.eclipse.mylyn.wikitext.commonmark.internal.TextSegment;
public class Cursor {
private final TextSegment segment;
private final String text;
private int textOffset;
public Cursor(TextSegment segment) {
this.segment = checkNotNull(segment);
this.text = segment.getText();
this.textOffset = 0;
}
/**
* Provides the offset of the current cursor position relative to the document.
*
* @return the current cursor position offset
*/
public int getOffset() {
return getOffset(textOffset);
}
/**
* Provides the offset of the given cursor position relative to the document.
*
* @param cursorOffset
* the position relative to the cursor
* @return the current cursor position offset
*/
public int getOffset(int cursorOffset) {
return segment.offsetOf(cursorOffset);
}
public int toCursorOffset(int documentOffset) {
return segment.toTextOffset(documentOffset);
}
public char getChar() {
return text.charAt(textOffset);
}
/**
* Provides the character at the cursor's 0-based offset, where the given offset is not affected by the position of
* the cursor.
*
* @param offset
* the absolute offset of the character relative to this cursor
* @return the character
*/
public char getChar(int offset) {
return text.charAt(offset);
}
public boolean hasChar() {
return textOffset < text.length();
}
/**
* Provides the string at the cursor's 0-based offset, where the given offset is not affected by the position of the
* cursor.
*
* @param offset
* the absolute offset of the character relative to this cursor
* @param endIndex
* the end index of the string to provide, exclusive
* @return the string
*/
public String getText(int offset, int endIndex) {
return text.substring(offset, endIndex);
}
public char getPrevious() {
return getPrevious(1);
}
public boolean hasPrevious() {
return hasPrevious(1);
}
public boolean hasPrevious(int offset) {
return textOffset - offset >= 0;
}
public char getPrevious(int offset) {
int charOffset = textOffset - offset;
checkArgument(charOffset >= 0);
return text.charAt(charOffset);
}
public char getNext() {
return getNext(1);
}
public char getNext(int offset) {
checkArgument(offset >= 0);
return text.charAt(textOffset + offset);
}
public String getTextAtOffset() {
return text.substring(textOffset, text.length());
}
public String getTextAtOffset(int length) {
checkArgument(length > 0);
return text.substring(textOffset, textOffset + length);
}
public boolean hasNext() {
return hasNext(1);
}
public boolean hasNext(int offset) {
checkArgument(offset > 0);
return textOffset + offset < text.length();
}
public Matcher matcher(Pattern pattern) {
return matcher(0, pattern);
}
public Matcher matcher(int offset, Pattern pattern) {
checkArgument(offset >= 0 && (offset + textOffset < text.length()));
checkNotNull(pattern);
Matcher matcher = pattern.matcher(text);
matcher.region(textOffset + offset, text.length());
return matcher;
}
public void advance() {
if (textOffset < text.length()) {
++textOffset;
}
}
public void advance(int count) {
checkArgument(count >= 0);
for (int x = 0; x < count; ++x) {
advance();
}
}
public void rewind(int count) {
checkArgument(count >= 0);
for (int x = 0; x < count; ++x) {
rewind();
}
}
public void rewind() {
if (textOffset > 0) {
--textOffset;
}
}
public Line getLineAtOffset() {
return segment.getLineAtOffset(textOffset);
}
}