package com.googlecode.lanterna.terminal.virtual;
import com.googlecode.lanterna.TextCharacter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
class TextBuffer {
private static final TextCharacter DOUBLE_WIDTH_CHAR_PADDING = new TextCharacter(' ');
private final LinkedList<List<TextCharacter>> lines;
TextBuffer() {
this.lines = new LinkedList<>();
newLine();
}
synchronized void newLine() {
lines.add(new ArrayList<>(200));
}
synchronized void removeTopLines(int numberOfLinesToRemove) {
for(int i = 0; i < numberOfLinesToRemove; i++) {
lines.removeFirst();
}
}
synchronized void clear() {
lines.clear();
newLine();
}
ListIterator<List<TextCharacter>> getLinesFrom(int rowNumber) {
return lines.listIterator(rowNumber);
}
synchronized int getLineCount() {
return lines.size();
}
synchronized int setCharacter(int lineNumber, int columnIndex, TextCharacter textCharacter) {
if(lineNumber < 0 || columnIndex < 0) {
throw new IllegalArgumentException("Illegal argument to TextBuffer.setCharacter(..), lineNumber = " +
lineNumber + ", columnIndex = " + columnIndex);
}
if(textCharacter == null) {
textCharacter = TextCharacter.DEFAULT_CHARACTER;
}
while(lineNumber >= lines.size()) {
newLine();
}
List<TextCharacter> line = lines.get(lineNumber);
while(line.size() <= columnIndex) {
line.add(TextCharacter.DEFAULT_CHARACTER);
}
int returnStyle = 0;
if(line.get(columnIndex).isDoubleWidth()) {
line.set(columnIndex + 1, line.get(columnIndex).withCharacter(' '));
returnStyle = 1;
}
else if(line.get(columnIndex) == DOUBLE_WIDTH_CHAR_PADDING) {
line.set(columnIndex - 1, TextCharacter.DEFAULT_CHARACTER);
returnStyle = 2;
}
line.set(columnIndex, textCharacter);
if(textCharacter.isDoubleWidth()) {
setCharacter(lineNumber, columnIndex + 1, DOUBLE_WIDTH_CHAR_PADDING);
}
return returnStyle;
}
synchronized TextCharacter getCharacter(int lineNumber, int columnIndex) {
if(lineNumber < 0 || columnIndex < 0) {
throw new IllegalArgumentException("Illegal argument to TextBuffer.getCharacter(..), lineNumber = " +
lineNumber + ", columnIndex = " + columnIndex);
}
if(lineNumber >= lines.size()) {
return TextCharacter.DEFAULT_CHARACTER;
}
List<TextCharacter> line = lines.get(lineNumber);
if(line.size() <= columnIndex) {
return TextCharacter.DEFAULT_CHARACTER;
}
TextCharacter textCharacter = line.get(columnIndex);
if(textCharacter == DOUBLE_WIDTH_CHAR_PADDING) {
return line.get(columnIndex - 1);
}
return textCharacter;
}
@Override
public String toString() {
StringBuilder bo = new StringBuilder();
for (List<TextCharacter> line : lines) {
StringBuilder b = new StringBuilder();
for (TextCharacter c : line) {
b.append(c.getCharacterString());
}
bo.append(b.toString().replaceFirst("\\s+$", ""));
bo.append('\n');
}
return bo.toString();
}
}