package org.mafagafogigante.dungeon.commands;
import org.mafagafogigante.dungeon.util.CircularList;
import org.mafagafogigante.dungeon.util.Utils;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
/**
* CommandHistory class that is used to keep track of all the commands issued by the player.
*/
public class CommandHistory implements Serializable {
private static final int HISTORY_MAXIMUM_SIZE = 200; // Enough. Small so it doesn't slow down 'TAB' search.
private final CircularList<String> commands = new CircularList<>(HISTORY_MAXIMUM_SIZE);
private transient Cursor cursor = new Cursor(this);
private Object readResolve() {
cursor = new Cursor(this);
return this;
}
/**
* Returns a CommandHistory.Cursor to provide access to the stored commands.
*/
public Cursor getCursor() {
return cursor;
}
/**
* Returns the number of commands in this CommandHistory.
*/
private int size() {
return commands.size();
}
/**
* Returns true if this CommandHistory contains no commands.
*/
private boolean isEmpty() {
return commands.isEmpty();
}
/**
* Adds an IssuedCommand to this CommandHistory and moves the cursor to the end.
*/
public void addCommand(IssuedCommand issuedCommand) {
commands.add(issuedCommand.getStringRepresentation());
getCursor().moveToEnd();
}
/**
* Returns a String representation of the last similar command or null if no similar command was found.
*/
public String getLastSimilarCommand(String command) {
for (int i = commands.size() - 1; i >= 0; i--) {
if (Utils.startsWithIgnoreCase(commands.get(i), command)) {
return commands.get(i);
}
}
return null;
}
/**
* Cursor inner class of CommandHistory that provides a set of methods for browsing and querying a CommandHistory.
*/
public static final class Cursor implements Serializable {
private final CommandHistory history;
private int index;
Cursor(CommandHistory history) {
this.history = history;
moveToEnd();
}
/**
* Returns the selected command or null if the CommandHistory does not have any commands or if the cursor is at the
* end of the CommandHistory.
*
* @return the selected command
*/
@Nullable
public String getSelectedCommand() {
if (!history.isEmpty() && index < history.size()) {
return history.commands.get(index);
} else {
return null;
}
}
/**
* Move the cursor up one command if it is not at the beginning of the history.
*
* @return the cursor
*/
public Cursor moveUp() {
if (index != 0) {
index--;
}
return this;
}
/**
* Move the cursor down one command if it is not at the end of the history.
*
* @return the cursor
*/
public Cursor moveDown() {
if (index < history.size()) {
index++;
}
return this;
}
/**
* Sets the cursor to one past the last command of the CommandHistory. The selected command after a call to this
* method is granted to be null.
*/
public void moveToEnd() {
index = history.size();
}
}
}