// GtpShellText.java
package net.sf.gogui.gui;
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Style;
import net.sf.gogui.game.Clock;
class GtpShellText
extends JTextPane
{
public GtpShellText(int historyMin, int historyMax, boolean timeStamp)
{
GuiUtil.setMonospacedFont(this);
m_startTime = System.currentTimeMillis();
m_timeStamp = timeStamp;
m_historyMin = historyMin;
m_historyMax = historyMax;
GuiUtil.addStyle(this, "error", Color.red);
GuiUtil.addStyle(this, "warning", Color.decode("#ff7000"));
GuiUtil.addStyle(this, "output", null, null, true);
GuiUtil.addStyle(this, "log", new Color(0.5f, 0.5f, 0.5f));
GuiUtil.addStyle(this, "livegfx", Color.decode("#5498B0"));
GuiUtil.addStyle(this, "time", new Color(0, 0, 0.5f));
GuiUtil.addStyle(this, "invalid", new Color(1.0f, 0.58f, 0.25f));
setEditable(false);
}
public void appendComment(String text)
{
m_isLastTextNonGTP = false;
appendText(text, "log");
}
public void appendError(String text)
{
m_isLastTextNonGTP = false;
appendTimeStamp();
appendText(text, "error");
}
public void appendInput(String text)
{
m_isLastTextNonGTP = false;
appendTimeStamp();
appendText(text, null);
}
public void appendInvalidResponse(String text)
{
m_isLastTextNonGTP = true;
appendText(text, "invalid");
}
public void appendLog(String text, boolean isLiveGfx, boolean isWarning)
{
m_isLastTextNonGTP = true;
if (isLiveGfx)
appendText(text, "livegfx");
else if (isWarning)
appendText(text, "warning");
else
appendText(text, "log");
}
public void appendOutput(String text)
{
m_isLastTextNonGTP = false;
appendTimeStamp();
appendText(text, "output");
}
public static int findTruncateIndex(String text, int truncateLines)
{
int indexNewLine = 0;
int lines = 0;
while ((indexNewLine = text.indexOf('\n', indexNewLine)) != -1)
{
++indexNewLine;
++lines;
if (lines == truncateLines)
return indexNewLine;
}
return -1;
}
public int getLinesTruncated()
{
return m_truncated;
}
public String getLog()
{
Document doc = getDocument();
try
{
return doc.getText(0, doc.getLength());
}
catch (BadLocationException e)
{
assert false;
return "";
}
}
/** Check if last text appended is not part of the GTP streams.
Returns true, if last text is standard error of program or invalid
response lines. */
public boolean isLastTextNonGTP()
{
return m_isLastTextNonGTP;
}
public void setPositionToEnd()
{
int length = getDocument().getLength();
setCaretPosition(length);
}
public void setTimeStamp(boolean enable)
{
m_timeStamp = enable;
}
private boolean m_isLastTextNonGTP;
private boolean m_timeStamp;
private final int m_historyMin;
private final int m_historyMax;
private int m_lines;
private int m_truncated;
private final long m_startTime;
private void appendText(String text, String style)
{
assert SwingUtilities.isEventDispatchThread();
if (text.equals(""))
return;
int indexNewLine = 0;
while ((indexNewLine = text.indexOf('\n', indexNewLine)) != -1)
{
++m_lines;
++indexNewLine;
}
Document doc = getDocument();
Style s = null;
if (style != null)
s = getStyle(style);
try
{
int length = doc.getLength();
doc.insertString(length, text, s);
setPositionToEnd();
}
catch (BadLocationException e)
{
assert false;
}
if (m_lines > m_historyMax)
{
truncateHistory();
setPositionToEnd();
}
}
private void appendTimeStamp()
{
if (! m_timeStamp)
return;
long timeMillis = System.currentTimeMillis();
double diff = (float)(timeMillis - m_startTime) / 1000;
appendText(Clock.getTimeString(diff, -1) + " ", "time");
}
private void truncateHistory()
{
int truncateLines = m_lines - m_historyMin;
Document doc = getDocument();
try
{
String text = doc.getText(0, doc.getLength());
int truncateIndex = findTruncateIndex(text, truncateLines);
assert truncateIndex != -1;
doc.remove(0, truncateIndex);
m_lines -= truncateLines;
m_truncated += truncateLines;
}
catch (BadLocationException e)
{
assert false;
}
}
}