import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Random;
import java.util.Comparator;
import javax.imageio.ImageIO;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.table.TableColumn;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import sun.awt.VerticalBagLayout;
import CLIPSJNI.Environment;
import CLIPSJNI.FactAddressValue;
import CLIPSJNI.MultifieldValue;
import CLIPSJNI.PrimitiveValue;
import CLIPSJNI.SymbolValue;
public class App implements ActionListener {
private JFrame frame;
private JLabel image;
private Environment clips;
private Properties properties;
private ButtonGroup answerButtons;
private JTextArea textPane;
private JButton nextButton;
private JPanel answerPanel;
private JPanel imagePanel;
private JTable answersTable;
private String assertedName;
private String lastAssertedName = "";
private boolean concatenate;
public App() {
frame = new JFrame("Cities");
frame.getContentPane().setLayout(new GridLayout(3, 1));
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel textPanel = new JPanel();
textPane = new JTextArea();
textPane.setLineWrap(true);
textPane.setOpaque(false);
textPane.setEditable(false);
textPane.setLayout(new BorderLayout());
textPanel.setLayout(new BorderLayout(10, 10));
textPanel.add(textPane);
answerPanel = new JPanel();
answerButtons = new ButtonGroup();
imagePanel = new JPanel();
JPanel nextButtonPanel = new JPanel();
nextButton = new JButton();
nextButton.setActionCommand("next");
nextButtonPanel.add(nextButton);
nextButton.addActionListener(this);
frame.setLayout(new VerticalBagLayout());
frame.getContentPane().add(textPanel);
frame.getContentPane().add(answerPanel);
frame.getContentPane().add(imagePanel);
frame.getContentPane().add(nextButtonPanel);
frame.setMinimumSize(new Dimension(360, 240));
frame.pack();
frame.setVisible(true);
clips = new Environment();
clips.load("control.clp");
clips.load("knowledgebase.clp");
clips.reset();
clips.run(1);
properties = new Properties();
loadProperties(new File("exsys.properties"));
try {
nextUIState();
} catch (Exception e) {
e.printStackTrace();
}
}
private void nextUIState() throws Exception {
answerPanel.removeAll();
MultifieldValue currentStateMultifieldValue = (MultifieldValue) clips
.eval("(find-all-facts ((?f currentState)) TRUE)");
List<FactAddressValue> currentStateList = currentStateMultifieldValue
.multifieldValue();
if (currentStateList.isEmpty()) {
return;
}
FactAddressValue currentState = currentStateList.get(0);
assertedName = currentState.getFactSlot("name").toString();
if (assertedName.contentEquals(lastAssertedName)) {
clips.run(1);
nextUIState();
return;
}
lastAssertedName = assertedName;
if (currentState.getFactSlot("state").toString().equals("final")) {
nextButton.setActionCommand("restart");
nextButton.setText(properties.getProperty("RESTART").toString());
MultifieldValue citiesMultifieldValue = (MultifieldValue) clips
.eval("(find-all-facts ((?f result)) TRUE)");
List<FactAddressValue> cityList = citiesMultifieldValue
.multifieldValue();
if (!cityList.isEmpty()) {
textPane.setText(properties.getProperty("RESULTS_END_TEXT")
.toString());
String headers[] = { properties.getProperty("CITIES") };
ArrayList<Result> resultList = new ArrayList<Result>();
for (FactAddressValue city : cityList) {
resultList.add(new Result(city.getFactSlot("city")
.getValue().toString()));
}
Collections.sort(resultList, new ResultComparator());
String data[][] = new String[resultList.size()][1];
int i = 0;
for (Result result : resultList) {
data[i][0] = result.getName();
if (i == 0) {
displayImage(result.getImage());
}
String newName = data[i++][0];
System.out.println(newName);
}
answersTable = new JTable(data, headers);
answersTable.getTableHeader().setReorderingAllowed(false);
answersTable.setEnabled(false);
JScrollPane scrollPane = new JScrollPane(answersTable);
answerPanel.add(scrollPane);
frame.pack();
} else {
textPane.setText(properties.getProperty("NO_RESULTS_END_TEXT")
.toString());
}
answerPanel.repaint();
return;
} else if (currentState.getFactSlot("state").toString()
.equals("initial")) {
displayImage(null);
nextButton.setActionCommand("start");
nextButton.setText(properties.getProperty("START").toString());
} else {
nextButton.setActionCommand("next");
nextButton.setText(properties.getProperty("NEXT").toString());
}
String text = ((SymbolValue) currentState.getFactSlot("text"))
.lexemeValue();
textPane.setText(properties.getProperty(text).toString());
boolean checkboxes = false;
if (currentState.getFactSlot("answerType").toString()
.equals("checkBox")) {
checkboxes = true;
}
answerPanel.removeAll();
answerButtons = !checkboxes ? new ButtonGroup() : null;
MultifieldValue answersMultifieldValue = (MultifieldValue) currentState
.getFactSlot("answers");
List<PrimitiveValue> answersList = answersMultifieldValue
.multifieldValue();
for (PrimitiveValue answer : answersList) {
JToggleButton button;
if (checkboxes) {
button = new JCheckBox(properties
.getProperty(answer.toString()).toString(), false);
concatenate = true;
} else {
button = new JRadioButton(properties.getProperty(
answer.toString()).toString(), false);
concatenate = false;
}
MultifieldValue selectedMultifieldValue = (MultifieldValue) currentState
.getFactSlot("selected");
List<PrimitiveValue> selectedList = selectedMultifieldValue
.multifieldValue();
for (PrimitiveValue selected : selectedList) {
if (answer.toString().equals(selected.toString())) {
button.setSelected(true);
break;
}
}
button.setActionCommand(answer.toString());
answerPanel.add(button);
if (!checkboxes) {
answerButtons.add(button);
}
}
answerPanel.repaint();
frame.pack();
}
@Override
public void actionPerformed(ActionEvent event) {
String multifieldChain = "";
if (event.getActionCommand().equals("next")) {
for (Component component : answerPanel.getComponents()) {
if (component instanceof JToggleButton) {
JToggleButton button = (JToggleButton) component;
if (button.isSelected()) {
if (concatenate) {
multifieldChain += " " + button.getActionCommand();
} else {
String toAssert = "(" + assertedName + " "
+ button.getActionCommand() + ")";
clips.assertString(toAssert);
}
}
}
}
if (concatenate) {
if (multifieldChain.equals("")) {
clips.assertString("(" + assertedName + " ANY)");
} else {
clips.assertString("(" + assertedName + " "
+ multifieldChain + ")");
}
}
String evalString = "(facts)";
clips.eval(evalString);
clips.run(1);
try {
nextUIState();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
if (event.getActionCommand().equals("start")) {
clips.assertString("(start)");
System.out.println("(start)");
clips.run(1);
try {
nextUIState();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
if (event.getActionCommand().equals("restart")) {
clips.reset();
System.out.println("clips.reset");
clips.run(1);
try {
nextUIState();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
}
private void loadProperties(File propertiesFile) {
InputStream is;
try {
is = new FileInputStream(propertiesFile);
properties.load(is);
} catch (FileNotFoundException e) {
System.out.println("Cannot find configuration file.");
} catch (IOException e) {
System.out.println("Some problems with configuration file.");
}
}
private void displayImage(BufferedImage image) {
if (this.image != null) {
this.imagePanel.remove(this.image);
}
if (image != null) {
this.image = new JLabel(new ImageIcon(image));
this.imagePanel.add(this.image);
} else {
this.image = null;
}
frame.pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new App();
}
});
}
}
class Result {
private String name;
private BufferedImage image;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Result() {
}
public Result(String name) {
this.image = null;
this.name = name;
}
public BufferedImage getImage() {
if (this.image != null) {
return this.image;
}
Document doc;
try {
String name = URLEncoder.encode(this.name, "UTF-8");
String query = "http://www.bing.com/images/search?q=" + name
+ "+&go=&qs=n&form=QBLH&pq=" + name;
doc = Jsoup.connect(query).get();
Elements images = doc.select("#sg_root a img");
if (images.size() > 0) {
String url = images.get(0).attr("src");
System.out.println(query + " -> " + url);
this.image = ImageIO.read(new URL(url));
}
} catch (IOException e) {
e.printStackTrace();
this.image = null;
}
return this.image;
}
}
class ResultComparator implements Comparator<Result> {
public int compare(Result o1, Result o2) {
return o1.getName().compareTo(o2.getName());
}
}