package nars.gui.output;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.border.EmptyBorder;
import nars.NAR;
import nars.entity.Sentence;
import nars.entity.Task;
import automenta.vivisect.swing.AwesomeToggleButton;
import automenta.vivisect.swing.AwesomeButton;
import automenta.vivisect.swing.NPanel;
import automenta.vivisect.swing.NSlider;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JTextField;
import nars.gui.InferenceLogger;
import nars.gui.InferenceLogger.LogOutput;
import nars.gui.NARControls;
import nars.gui.WrapLayout;
import nars.util.AbstractObserver;
import nars.io.Output;
import nars.io.Output.ERR;
import nars.io.Output.EXE;
import nars.io.TextOutput;
abstract public class LogPanel extends NPanel implements LogOutput {
static CharSequence getText(Class c, Object o, boolean showStamp, NAR nar) {
return TextOutput.getOutputString(c, o, showStamp, nar);
}
protected final NAR nar;
private AbstractObserver out;
public static final int maxIOTextSize = (int) 3E5;
public static final int clearMargin = (int) 3E4;
protected boolean showErrors = true;
protected boolean showStamp = false;
protected boolean showQuestions = true;
protected boolean showStatements = true;
protected boolean showExecutions = true;
/**
* the log file
*/
protected PrintWriter logFile = null;
private final InferenceLogger logger;
private String logFilePath;
public static final Class[] outputEvents = Output.DefaultOutputEvents;
public LogPanel(NARControls c) {
this(c, outputEvents);
}
String filter = "";
public LogPanel(NARControls c, Class... events) {
super();
setLayout(new BorderLayout());
this.nar = c.nar;
this.logger = c.logger;
out = new AbstractObserver(nar, false, events) {
@Override public void event(final Class event, final Object[] arguments) {
LogPanel.this.output(event, arguments.length > 1 ? arguments : arguments[0]);
}
};
//JPanel menuBottom = new JPanel(new WrapLayout(FlowLayout.RIGHT, 0, 0));
JPanel menuTop = new JPanel(new WrapLayout(FlowLayout.LEFT, 0, 0));
//menuBottom.setOpaque(false);
//menuBottom.setBorder(new EmptyBorder(0,0,0,0));
menuTop.setOpaque(false);
menuTop.setBorder(new EmptyBorder(0, 0, 0, 0));
JButton clearButton = new AwesomeButton('\uf016');
clearButton.setForeground(Color.WHITE);
clearButton.setBackground(Color.DARK_GRAY);
clearButton.setToolTipText("Clear");
clearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clearLog();
}
});
menuTop.add(clearButton);
final String defaultStreamButtonLabel = "Stream to File..";
final JToggleButton streamButton = new AwesomeToggleButton('\uf0c7', '\uf052');
streamButton.setForeground(Color.WHITE);
streamButton.setBackground(Color.DARK_GRAY);
streamButton.setToolTipText(defaultStreamButtonLabel);
streamButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (streamButton.isSelected()) {
if (!openLogFile()) {
streamButton.setSelected(false);
} else {
streamButton.setToolTipText("Streaming...");
}
} else {
streamButton.setToolTipText(defaultStreamButtonLabel);
closeLogFile();
}
}
});
menuTop.add(streamButton);
menuTop.add(Box.createHorizontalStrut(4));
final JToggleButton showStatementsBox = new JToggleButton(".");
showStatementsBox.setForeground(Color.WHITE);
showStatementsBox.setBackground(Color.DARK_GRAY);
showStatementsBox.setToolTipText("Show Statements");
showStatementsBox.setSelected(showStatements);
showStatementsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showStatements = showStatementsBox.isSelected();
}
});
menuTop.add(showStatementsBox);
final JToggleButton showQuestionsBox = new JToggleButton("?");
showQuestionsBox.setForeground(Color.WHITE);
showQuestionsBox.setBackground(Color.DARK_GRAY);
showQuestionsBox.setToolTipText("Show Questions");
showQuestionsBox.setSelected(showQuestions);
showQuestionsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showQuestions = showQuestionsBox.isSelected();
}
});
menuTop.add(showQuestionsBox);
final JToggleButton showExecutionsBox = new JToggleButton("!");
showExecutionsBox.setForeground(Color.WHITE);
showExecutionsBox.setBackground(Color.DARK_GRAY);
showExecutionsBox.setToolTipText("Show Goals & Executions");
showExecutionsBox.setSelected(showExecutions);
showExecutionsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showExecutions = showExecutionsBox.isSelected();
}
});
menuTop.add(showExecutionsBox);
final JToggleButton showErrorBox = new JToggleButton("Errors");
showErrorBox.setForeground(Color.WHITE);
showErrorBox.setBackground(Color.DARK_GRAY);
showErrorBox.setSelected(showErrors);
showErrorBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showErrors = showErrorBox.isSelected();
}
});
menuTop.add(showErrorBox);
final JToggleButton showStampBox = new JToggleButton("Stamp");
showStampBox.setForeground(Color.WHITE);
showStampBox.setBackground(Color.DARK_GRAY);
showStampBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setShowStamp(showStampBox.isSelected());
}
});
menuTop.add(showStampBox);
final JToggleButton showTraceBox = new JToggleButton("Trace");
showTraceBox.setForeground(Color.WHITE);
showTraceBox.setBackground(Color.DARK_GRAY);
showTraceBox.setEnabled(true);
showTraceBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setTrace(showTraceBox.isSelected());
}
});
setTrace(showTraceBox.isSelected());
menuTop.add(showTraceBox);
menuTop.add(Box.createHorizontalStrut(4));
final NSlider fontSlider = new NSlider(12f, 6f, 40f) {
@Override
public void onChange(float v) {
setFontSize(v);
}
};
fontSlider.setPrefix("Font size: ");
menuTop.add(fontSlider);
final JTextField filterBox = new JTextField("");
filterBox.setPreferredSize(new Dimension(255,20));
filterBox.setForeground(Color.WHITE);
filterBox.setBackground(Color.DARK_GRAY);
filterBox.setEnabled(true);
filterBox.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent ke) {
}
@Override
public void keyPressed(KeyEvent ke) {
}
@Override
public void keyReleased(KeyEvent ke) {
filter = filterBox.getText();
}
});
menuTop.add(filterBox);
//add(menuBottom, BorderLayout.SOUTH);
add(menuTop, BorderLayout.NORTH);
addContainerListener(new ContainerListener() {
@Override
public void componentAdded(ContainerEvent e) {
}
@Override
public void componentRemoved(ContainerEvent e) {
}
});
}
abstract public void setFontSize(float v);
abstract protected void clearLog();
@Override
protected void onShowing(boolean showing) {
if (showing) {
out.setActive(true);
} else {
out.setActive(false);
}
}
public void output(final Class c, Object o) {
if ((c == ERR.class) && (!showErrors)) {
return;
}
if ((c == EXE.class) && !showExecutions) {
return;
}
if (o instanceof Task) {
Sentence s = ((Task) o).sentence;
if (s!=null) {
if (s.isQuestion() && !showQuestions) {
return;
}
if (s.isJudgment() && !showStatements) {
return;
}
if (s.isGoal()&& !showExecutions) {
return;
}
}
}
print(c, o);
}
abstract void print(Class c, Object o);
abstract void limitBuffer(int incomingDataSize);
public static Color getChannelColor(Class c) {
switch (c.getSimpleName()) {
case "OUT":
return Color.GREEN;
case "IN":
return Color.YELLOW;
case "ERR":
return Color.ORANGE;
}
return Color.GRAY;
}
final static Color getPriorityColor(final float val) {
return new Color(val, val, val);
}
final static Color getNegativeEvidenceColor(final float val) {
return new Color(0, 0, val);
}
final static Color getPositiveEvidenceColor(final float val) {
return new Color(val,0,0);
}
final static Color getStatementColor(final char punctuation, final float priority) {
float r = 1f, g = 1f, b = 1f;
/*switch (punctuation) {
case '!': r = 1f; g = 0.75f; b = 0f; break;
case '?': b = 1f; r = 1.0f; g = 1f; break;
case '=': r = 0.0f; g = 0f; b = 0.0f; break; //solution
case '.': break;
}
r *= 0.25f + 0.75f*priority;
g *= 0.25f + 0.75f*priority;
b *= 0.25f + 0.75f*priority;*/
return new Color(r, g, b);
}
public static final class LOG {
}
@Override
public void traceAppend(Class channel, String s) {
output(LOG.class, channel.getSimpleName() + ": " + s);
}
public void setTrace(boolean b) {
if (b) {
logger.setActive(true);
logger.addOutput(this);
} else {
logger.setActive(false);
logger.removeOutput(this);
}
}
public boolean openLogFile() {
FileDialog dialog = new FileDialog((Dialog) null, "Inference Log", FileDialog.SAVE);
dialog.setVisible(true);
String directoryName = dialog.getDirectory();
logFilePath = dialog.getFile();
if (logFilePath == null) {
return false;
}
try {
boolean append = true;
boolean autoflush = true;
logFile = new PrintWriter(new FileWriter(directoryName + logFilePath, append), autoflush);
output(LOG.class, "Stream opened: " + logFilePath);
return true;
} catch (IOException ex) {
output(ERR.class, "Log file save: I/O error: " + ex.getMessage());
}
return false;
}
public void closeLogFile() {
if (logFile != null) {
output(LOG.class, "Stream saved: " + logFilePath);
logFile.close();
logFile = null;
}
}
public void setShowStamp(boolean showStamp) {
this.showStamp = showStamp;
}
}