/* File: BeliefListener.java
 * Author: Jason Gookins
 * Description: The class which handles events that are passed between classes.
 */

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

public class BeliefListener implements ActionListener, ContainerListener, KeyListener, ListSelectionListener, MouseListener, PropertyChangeListener
{
	/************************
	 ** Instance Variables **
	 ************************/

	private Belief belief;
	private BeliefMenuBar beliefMenuBar;
	private ToolPane toolPane;
	private ListPane listPane;
	private NetworkPane networkPane;
	private Timer listPaneTimer;
	private boolean isListPaneRetracted;
	private JFileChooser fileChooser;
	private ProgressDialog progressDialog;
	private JProgressBar progressBar;
	private ArrayList<Node> minimizedNodes;
	private int cycles;
	private int beforeChange;
	private View currentView;
	private ArrayList<View> views;



	/**********************
	 ** Main Constructor **
	 **********************/

	public BeliefListener(Belief belief)
	{
		this.belief = belief;
	}



	/********************
	 ** Listening Init **
	 ********************/

	public void setListenerTargets()
	{
		this.beliefMenuBar = belief.getBeliefMenuBar();
		this.toolPane = belief.getToolPane();
		this.listPane = toolPane.getListPane();
		this.networkPane = toolPane.getNetworkPane();
		this.isListPaneRetracted = true;
		this.minimizedNodes = new ArrayList<Node>();
		this.cycles = 0;
		this.beforeChange = 0;
		this.views = new ArrayList<View>();
	}



	/***************
	 ** Accessors **
	 ***************/

	public View getCurrentView()
	{
		return this.currentView;
	}

	public ArrayList<View> getViews()
	{
		return this.views;
	}

	public ListPane getListPane()
	{
		return this.listPane;
	}



	/**************
	 ** Mutators **
	 **************/

	public void setCurrentView(View newCurrentView)
	{
		this.currentView = newCurrentView;
	}

	public void setViews(ArrayList<View> newViews)
	{
		this.views = newViews;
	}



	/*******************
	 ** Action Events **
	 *******************/

	public void actionPerformed(ActionEvent evt)
	{
		if (evt.getSource().equals(toolPane.getListButton()))
		{
			startListPaneTimer();
		}
		else if (evt.getSource().equals(listPaneTimer))
		{
			moveListPane();
		}
		else if (evt.getActionCommand().equals("newNetworkMenuItem"))
		{
			newNetwork();
		}
		else if (evt.getActionCommand().equals("openNetworkMenuItem"))
		{
		}
		else if (evt.getActionCommand().equals("saveNetworkMenuItem"))
		{
		}
		else if (evt.getActionCommand().equals("saveAsNetworkMenuItem"))
		{
		}
		else if (evt.getActionCommand().equals("importNetworkMenuItem"))
		{
			if (networkPane.getNodes().size() > 0)
			{
				BeliefListenerDialog beliefListenerDialog = new BeliefListenerDialog("Belief", "importSaveQuery", new JOptionPane("Do you wish to save your current network first?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION));
			}
			else
			{
				importNetwork();
			}
		}
		else if (evt.getActionCommand().equals("exportNetworkMenuItem"))
		{
			exportNetwork();
		}
		else if (evt.getActionCommand().equals("logOutMenuItem"))
		{
			if (networkPane.getNodes().size() > 0)
			{
				BeliefListenerDialog beliefListenerDialog = new BeliefListenerDialog("Belief", "logoutSaveQuery", new JOptionPane("Do you wish to save your current network first?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION));
			}
			else
			{
				logOut();
			}
		}
		else if (evt.getActionCommand().equals("addNodesMenuItem"))
		{
			AddNodesDialog addNodesDialog = new AddNodesDialog(belief, networkPane.getNodes());
		}
		else if (evt.getActionCommand().equals("runNetworkMenuItem"))
		{
			RunDialog runDialog = new RunDialog(belief);
		}
		else if (evt.getActionCommand().equals("resetNetworkMenuItem"))
		{
			resetNetwork();
		}
		else if (evt.getActionCommand().equals("helpTopicsMenuItem"))
		{
			Help help = new Help();
		}
		else if (evt.getActionCommand().equals("aboutBeliefMenuItem"))
		{
			AboutDialog aboutDialog = new AboutDialog(belief);
		}
		else
		{
			for (int i = 0; i < views.size(); i++)
			{
				String view = views.get(i).getName();

				if (evt.getActionCommand().equals(view + "View"))
				{
					setCurrentView(views.get(i));

					break;
				}
			}
		}
	}



	/**********************
	 ** Container Events **
	 **********************/

	public void componentAdded(ContainerEvent evt)
	{
		Node node = (Node)evt.getChild();

		listPane.addNodeToLists(node);

		if (networkPane.getNodes().size() > 1)
		{
			beliefMenuBar.getRunNetworkMenuItem().setEnabled(true);
		}
		else
		{
			beliefMenuBar.getSaveAsNetworkMenuItem().setEnabled(true);
			beliefMenuBar.getExportNetworkMenuItem().setEnabled(true);
		}
	}

	public void componentRemoved(ContainerEvent evt)
	{
		Node node = (Node)evt.getChild();

		listPane.removeNodeFromLists(node);

		if (networkPane.getNodes().size() < 2)
		{
			beliefMenuBar.getRunNetworkMenuItem().setEnabled(false);

			if (networkPane.getNodes().size() < 1)
			{
				beliefMenuBar.getSaveAsNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getExportNetworkMenuItem().setEnabled(false);
			}
		}
	}



	/****************
	 ** Key Events **
	 ****************/

	public void keyPressed(KeyEvent evt)
	{
		if (evt.getKeyCode() == KeyEvent.VK_A && evt.isControlDown())
		{
			if (networkPane.getAreNamesDisplayed())
			{
				networkPane.setAreNamesDisplayed(false);
			}
			else
			{
				networkPane.setAreNamesDisplayed(true);
			}

			networkPane.repaint();
		}
	}



	/***************************
	 ** List Selection Events **
	 ***************************/

	public void valueChanged(ListSelectionEvent evt)
	{
		JList sourceList = (JList)evt.getSource();

		refreshDisplayedNodeData(sourceList);
	}



	/******************
	 ** Mouse Events **
	 ******************/

	public void mousePressed(MouseEvent evt)
	{
		int x = evt.getX();
		int y = evt.getY();

		for (Node node : networkPane.getNodes())
		{
			if (node.getIsHighlighted())
			{
				node.setIsHighlighted(false);

				networkPane.repaint(node.getXPos(), node.getYPos(), 50, 50);

				if (node.getHasGiven() == 1 || node.getHasGoal() == 1)
				{
					listPane.clearDistributionData();
				}

				break;
			}
		}

		if (networkPane.isNodeHit(x, y))
		{
			Node clickedNode = networkPane.getClickedNode();

			clickedNode.setIsHighlighted(true);

			listPane.selectListCells(listPane.getNameList().indexOf(clickedNode.getName()));

			listPane.getNameListDisplay().ensureIndexIsVisible(listPane.getNameList().indexOf(clickedNode.getName()));

			if (clickedNode.getHasGiven() == 1)
			{
				listPane.displayDistributionData(currentView.getGivenDistributions().get(currentView.getGivenDistNodes().indexOf(clickedNode)), clickedNode.getMinimumBound(), clickedNode.getMaximumBound(), clickedNode.getGivenDistMutability());
			}
			else if (clickedNode.getHasGoal() == 1)
			{
				listPane.displayDistributionData(currentView.getGoalDistributions().get(currentView.getGoalDistNodes().indexOf(clickedNode)), clickedNode.getMinimumBound(), clickedNode.getMaximumBound(), null);
			}

			listPane.getDescriptionTextArea().setText(clickedNode.getDescription());
		}
		else
		{
			listPane.deselectListCells();
		}
	}



	/****************************
	 ** Property Change Events **
	 ****************************/

	public void propertyChange(PropertyChangeEvent evt)
	{
		if (evt.getPropertyName().equals("progress"))
		{
			int progress = (Integer)evt.getNewValue();

			progressDialog.updateProgress(progress);
		}
	}



	/**********************
	 ** Instance Methods **
	 **********************/

	private void startListPaneTimer()
	{
		if (listPaneTimer != null)
		{
			if (listPaneTimer.isRunning())
			{
				listPaneTimer.stop();
			}

			listPaneTimer = null;
		}

		listPaneTimer = new Timer(10, this);
		listPaneTimer.start();
	}

	private void moveListPane()
	{
		if (isListPaneRetracted == true)
		{
			listPane.setPreferredSize(new Dimension(listPane.getWidth() + 10, listPane.getHeight()));
			listPane.setMinimumSize(new Dimension(listPane.getWidth() + 10, listPane.getHeight()));
			listPane.revalidate();

			if (listPane.getWidth() == 310)
			{
				listPaneTimer.stop();
				isListPaneRetracted = false;
			}
		}
		else
		{
			listPane.setPreferredSize(new Dimension(listPane.getWidth() - 10, listPane.getHeight()));
			listPane.setMinimumSize(new Dimension(listPane.getWidth() - 10, listPane.getHeight()));
			listPane.revalidate();

			if (listPane.getWidth() == 0)
			{
				listPaneTimer.stop();
				isListPaneRetracted = true;
			}
		}
	}

	private void newNetwork()
	{
		if (networkPane.getNodes().size() > 0)
		{
			int newNetworkDialog = JOptionPane.showConfirmDialog(belief, "Do you wish to save your current network before working with a new one?", "Belief", JOptionPane.YES_NO_CANCEL_OPTION);

			if (newNetworkDialog != JOptionPane.CANCEL_OPTION)
			{
				if (newNetworkDialog == JOptionPane.YES_OPTION)
				{
					exportNetwork();
				}

				for (Node node : networkPane.getNodes())
				{
					networkPane.remove(node);
				}

				networkPane.getEdges().clear();
				networkPane.getNodes().clear();

				networkPane.repaint();
				networkPane.setNetworkRan(false);
				beliefMenuBar.getRunNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getResetNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getSaveNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getSaveAsNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getExportNetworkMenuItem().setEnabled(false);
			}
		}
	}

	private void importNetwork()
	{
		fileChooser = new JFileChooser();
		fileChooser.addChoosableFileFilter(new NetworkFilter());
		fileChooser.setAcceptAllFileFilterUsed(false);
		int returnVal = fileChooser.showOpenDialog(belief);

		if (returnVal == JFileChooser.APPROVE_OPTION)	
		{
			File csvFile = fileChooser.getSelectedFile();
			ArrayList<String> csvFileInput = new ArrayList<String>();

			if (networkPane.getNodes().size() > 0)
			{
				for (Node node : networkPane.getNodes())
				{
					networkPane.remove(node);
				}

				networkPane.getEdges().clear();
				networkPane.getNodes().clear();

				networkPane.repaint();
				networkPane.setNetworkRan(false);
				beliefMenuBar.getRunNetworkMenuItem().setEnabled(false);
				beliefMenuBar.getResetNetworkMenuItem().setEnabled(false);
			}

			try
			{
				Scanner scannerCSVIn = new Scanner(csvFile);

				while (scannerCSVIn.hasNextLine())
				{
					csvFileInput.add(scannerCSVIn.nextLine());
				}

				scannerCSVIn.close();
			}
			catch (IOException ioe)
			{
				ioe.printStackTrace();
			}

			if (csvFileInput.size() > 0)
			{
				ArrayList<Node> nodes = networkPane.getNodes();
				ArrayList<Edge> edges = networkPane.getEdges();
				ArrayList<ArrayList<Integer>> childrenMatrix = new ArrayList<ArrayList<Integer>>();
				int numberOfNodes = Integer.parseInt(csvFileInput.get(0));

				edges.clear();
				nodes.clear();

				for (int i = 0; i < numberOfNodes; i++)
				{
					String fileInputLine = csvFileInput.get(i + 1);
					Scanner nodeData = new Scanner(fileInputLine);
					nodeData.useDelimiter(",");

					Node node = new Node();

					node.setIndex(nodeData.nextInt());
					node.setXPos(nodeData.nextInt());
					node.setYPos(nodeData.nextInt());
					node.setName(nodeData.next());
					node.setOperation(nodeData.next());
					node.setPriority(nodeData.nextInt());
					node.setMinimumBound(nodeData.nextInt());
					node.setMaximumBound(nodeData.nextInt());
					node.setGivenDistMutability(nodeData.next());
					node.setHasGiven(nodeData.nextInt());
					node.setHasGoal(nodeData.nextInt());

					int numberOfChildren = nodeData.nextInt();

					if (numberOfChildren > 0)
					{
						ArrayList<Integer> children = new ArrayList<Integer>();

						children.add(node.getIndex());

						for (int j = 0; j < numberOfChildren; j++)
						{
							children.add(nodeData.nextInt());
						}

						childrenMatrix.add(children);
					}

					if (nodeData.hasNext())
					{
						node.setDescription(nodeData.nextLine().replaceFirst(",", ""));
					}

					networkPane.addNode(node);
					nodeData.close();
				}

				for (ArrayList<Integer> children : childrenMatrix)
				{
					for (int i = 1; i < children.size(); i++)
					{
						nodes.get(children.get(0)).getChildren().add(nodes.get(children.get(i)));
					}
				}

				for (Node parentNode : nodes)
				{
					for (Node childNode : parentNode.getChildren())
					{
						Edge edge = new Edge(childNode, parentNode);

						edges.add(edge);

						childNode.getParents().add(parentNode);
					}
				}

				for (int i = numberOfNodes + 1; i < csvFileInput.size(); i++)
				{
					String fileInputLine = csvFileInput.get(i);
					Scanner viewData = new Scanner(fileInputLine);
					viewData.useDelimiter(",");
					View newView = new View(viewData.next());
					int numberOfGivenNodes = viewData.nextInt();

					for (int j = 0; j < numberOfGivenNodes; j++)
					{
						newView.getGivenDistNodes().add(nodes.get(viewData.nextInt()));
					}

					for (int j = 0; j < numberOfGivenNodes; j++)
					{
						ArrayList<Integer> givenDistribution = new ArrayList<Integer>();

						for (int k = 0; k < 10; k++)
						{
							givenDistribution.add(viewData.nextInt());
						}

						newView.getGivenDistributions().add(givenDistribution);
					}

					int numberOfGoalNodes = viewData.nextInt();

					for (int j = 0; j < numberOfGoalNodes; j++)
					{
						newView.getGoalDistNodes().add(nodes.get(viewData.nextInt()));
					}

					for (int j = 0; j < numberOfGoalNodes; j++)
					{
						ArrayList<Integer> goalDistribution = new ArrayList<Integer>();

						for (int k = 0; k < 10; k++)
						{
							goalDistribution.add(viewData.nextInt());
						}

						newView.getGoalDistributions().add(goalDistribution);
					}

					views.add(newView);
					beliefMenuBar.addNewViewMenuItem(newView);
				}
			}

			beliefMenuBar.getSaveAsNetworkMenuItem().setEnabled(true);
			beliefMenuBar.getExportNetworkMenuItem().setEnabled(true);
			toolPane.getNetworkLabel().setText(csvFile.getName());

			networkPane.repaint();
		}
	}

	private void exportNetwork()
	{
		fileChooser = new JFileChooser();
		fileChooser.addChoosableFileFilter(new NetworkFilter());
		fileChooser.setAcceptAllFileFilterUsed(false);
		int returnVal = fileChooser.showSaveDialog(belief);

		if (returnVal == JFileChooser.APPROVE_OPTION)
		{
			File outputFile = fileChooser.getSelectedFile();
			ArrayList<Node> nodes = networkPane.getNodes();

			try
			{
				BufferedWriter csvOut;

				if (outputFile.exists())
				{
					csvOut = new BufferedWriter(new FileWriter(outputFile));
				}
				else
				{
					csvOut = new BufferedWriter(new FileWriter(outputFile + ".csv"));
				}

				csvOut.write(Integer.toString(nodes.size()));
				csvOut.newLine();

				for (Node node : nodes)
				{
					csvOut.write(node.getIndex() + ",");
					csvOut.write(node.getXPos() + ",");
					csvOut.write(node.getYPos() + ",");
					csvOut.write(node.getName() + ",");
					csvOut.write(node.getOperation() + ",");
					csvOut.write(node.getPriority() + ",");
					csvOut.write(node.getMinimumBound() + ",");
					csvOut.write(node.getMaximumBound() + ",");
					csvOut.write(node.getGivenDistMutability() + ",");
					csvOut.write(node.getHasGiven() + ",");
					csvOut.write(node.getHasGoal() + ",");
					csvOut.write(Integer.toString(node.getChildren().size()));

					if (node.getChildren().size() > 0)
					{
						for (Node childNode : node.getChildren())
						{
							csvOut.write("," + childNode.getIndex());
						}
					}

					if (node.getDescription() != null)
					{
						if (node.getDescription().length() > 0)
						{
							csvOut.write("," + node.getDescription());
						}
					}

					csvOut.newLine();
				}

				int l = 0;
				for (int i = 0; i < views.size(); i++)
				{
					View view = views.get(i);

					csvOut.write(view.getName() + ",");
					csvOut.write(view.getGivenDistNodes().size() + ",");

					for (int j = 0; j < view.getGivenDistNodes().size(); j++)
					{
						csvOut.write(view.getGivenDistNodes().get(j).getIndex() + ",");
					}

					for (int j = 0; j < view.getGivenDistributions().size(); j++)
					{
						for (int k = 0; k < view.getGivenDistributions().get(j).size(); k++)
						{
							csvOut.write(view.getGivenDistributions().get(j).get(k) + ",");
						}
					}

					csvOut.write(Integer.toString(view.getGoalDistNodes().size()));

					if (view.getGoalDistNodes().size() > 0)
					{
						csvOut.write(",");

						for (int j = 0; j < view.getGoalDistNodes().size(); j++)
						{
							csvOut.write(view.getGoalDistNodes().get(j).getIndex() + ",");
						}

						int m = 0;
						for (int j = 0; j < view.getGoalDistributions().size(); j++)
						{
							for (int k = 0; k < view.getGoalDistributions().get(j).size() - 1; k++)
							{
								csvOut.write(view.getGoalDistributions().get(j).get(k) + ",");
							}
							csvOut.write(Integer.toString(view.getGoalDistributions().get(j).get(view.getGoalDistributions().get(j).size() - 1)));

							m++;

							if (m < view.getGoalDistributions().size())
							{
								csvOut.write(",");
							}
						}
					}

					l++;

					if (l < views.size())
					{
						csvOut.newLine();
					}
				}

				csvOut.close();
			}
			catch (IOException ioe)
			{
				ioe.printStackTrace();
			}
		}
	}

	private void logOut()
	{
		CardLayout mainLayout = (CardLayout)belief.getContentPane().getLayout();

		beliefMenuBar.setVisible(false);

		for (Node node : networkPane.getNodes())
		{
			networkPane.remove(node);
		}

		networkPane.getEdges().clear();
		networkPane.getNodes().clear();

		networkPane.repaint();
		networkPane.setNetworkRan(false);
		beliefMenuBar.getRunNetworkMenuItem().setEnabled(false);
		beliefMenuBar.getResetNetworkMenuItem().setEnabled(false);
		beliefMenuBar.getSaveNetworkMenuItem().setEnabled(false);
		beliefMenuBar.getSaveAsNetworkMenuItem().setEnabled(false);
		beliefMenuBar.getExportNetworkMenuItem().setEnabled(false);

		mainLayout.show(belief.getContentPane(), "loginPane");
		belief.getLoginPane().getUsernameTextField().requestFocus();
	}

	public void addNodes(String[] newNodes)
	{
		int xPos = 25, yPos = 25, newRow = 1;

		for (String newNodeName : newNodes)
		{
			Node newNode = new Node();

			newNode.setName(newNodeName);
			newNode.setXPos(xPos);
			newNode.setYPos(yPos);

			networkPane.addNode(newNode);

			xPos += 75;

			if (newRow % 10 == 0)
			{
				xPos = 25;
				yPos += 75;
			}

			newRow++;
		}

		networkPane.repaint();
	}

	public void setupNewRun(int numberOfRuns, boolean minimizeChange)
	{
		for (Node givenNode : currentView.getGivenDistNodes())
		{
			givenNode.setGivenDistribution(currentView.getGivenDistributions().get(currentView.getGivenDistNodes().indexOf(givenNode)));
		}

		for (Node goalNode : currentView.getGoalDistNodes())
		{
			goalNode.setGoalDistribution(currentView.getGoalDistributions().get(currentView.getGoalDistNodes().indexOf(goalNode)));
		}

		if (numberOfRuns > 0)
		{
			progressDialog = new ProgressDialog(belief, numberOfRuns, minimizeChange);
		}
	}

	public void runNetwork(int numberOfRuns, boolean minimizeChange)
	{
		IVV ivv = new IVV(networkPane.getNodes(), 10, numberOfRuns, minimizeChange, this);
		ivv.addPropertyChangeListener(this);
		ivv.execute();
	}

	public void postProcessing(int numberOfRuns, boolean minimizeChange)
	{
		progressDialog.cleanUpAfterClosing();

		for (Node node : networkPane.getNodes())
		{
			if (node.getHasGoal() == 1 || node.getHasGiven() == 1)
			{
				for (int i = 0; i < listPane.getNameList().size(); i++)
				{
					if (listPane.getNameList().get(i).toString().equals(node.getName()))
					{
						listPane.getChangeList().set(i, Integer.toString(node.getChange()) + "%");
					}
				}
			}
		}

		networkPane.repaint();
		networkPane.setNetworkRan(true);
		beliefMenuBar.getRunNetworkMenuItem().setEnabled(false);
		beliefMenuBar.getResetNetworkMenuItem().setEnabled(true);

		if (minimizeChange)
		{
			boolean runAgain = true;

			if (cycles > 0)
			{
				int afterChange = 0;

				for (Node node: networkPane.getNodes())
				{
					if (node.getHasGiven() == 1)
					{
						afterChange += node.getChange();
					}
				}

				if ((beforeChange * 0.05) >= (beforeChange - afterChange))
				{
					runAgain = false;

					listPane.sortChangeList();
					listPane.sortDistTypeList();
					refreshDisplayedNodeData(listPane.getNameListDisplay());
				}
			}

			if (runAgain)
			{
				beforeChange = 0;

				listPane.sortChangeList();
				listPane.sortDistTypeList();

				for (Node node : networkPane.getNodes())
				{
					if (node.getHasGiven() == 1)
					{
						beforeChange += node.getChange();
					}
				}

				if (listPane.getDistTypeList().get(0).toString().equals("Given"))
				{
					if (!listPane.getChangeList().get(0).toString().equals("0%"))
					{
						for (Node node : networkPane.getNodes())
						{
							if (listPane.getNameList().get(0).toString().equals(node.getName()))
							{
								node.setOriginalGivenDistribution(node.getGivenDistribution());
								node.setGivenDistribution(node.getResultDistribution());
								node.setGivenDistMutability("fixed");
								node.setChange(0);
								minimizedNodes.add(node);

								break;
							}
						}
					}
				}

				cycles++;
				refreshDisplayedNodeData(listPane.getNameListDisplay());
				progressDialog = new ProgressDialog(belief, numberOfRuns, minimizeChange);
			}
		}
	}

	private void resetNetwork()
	{
		cycles = 0;

		for (int i = minimizedNodes.size() - 1; i >= 0; i--)
		{
			Node node = minimizedNodes.get(i);

			node.setGivenDistribution(node.getOriginalGivenDistribution());
			node.setOriginalGivenDistribution(new ArrayList<Integer>());
			node.setGivenDistMutability("opt");

			minimizedNodes.remove(i);
		}

		for (Node node: networkPane.getNodes())
		{
			if (node.getHasGoal() == 1 || node.getHasGiven() == 1)
			{
				node.setColor(Color.lightGray);
				node.setChange(0);
				node.setNormalizedGoalDistribution(new ArrayList<Float>());
				node.setResultDistribution(new ArrayList<Integer>());
				node.setNormalizedResultDistribution(new ArrayList<Float>());

				for (int i = 0; i < listPane.getNameList().size(); i++)
				{
					if (listPane.getNameList().get(i).toString().equals(node.getName()))
					{
						listPane.getChangeList().set(i, "0%");
					}
				}
			}
		}

		networkPane.repaint();
		networkPane.setNetworkRan(false);
		beliefMenuBar.getRunNetworkMenuItem().setEnabled(true);
		beliefMenuBar.getResetNetworkMenuItem().setEnabled(false);
		refreshDisplayedNodeData(listPane.getNameListDisplay());
	}

	private void refreshDisplayedNodeData(JList sourceList)
	{
		if (sourceList.getSelectedValue() != null)
		{
			int index = sourceList.getSelectedIndex();

			listPane.selectListCells(index);

			for (Node node1 : networkPane.getNodes())
			{
				if (listPane.getNameList().get(index).toString().equals(node1.getName()))
				{
					for (Node node2 : networkPane.getNodes())
					{
						if (node2.getIsHighlighted())
						{
							node2.setIsHighlighted(false);

							if (node2.getHasGiven() == 1 || node2.getHasGoal() == 1)
							{
								listPane.clearDistributionData();
							}

							networkPane.repaint(node2.getXPos(), node2.getYPos(), 50, 50);

							break;
						}
					}

					node1.setIsHighlighted(true);

					networkPane.repaint(node1.getXPos(), node1.getYPos(), 50, 50);

					if (node1.getHasGiven() == 1)
					{
						listPane.displayDistributionData(currentView.getGivenDistributions().get(currentView.getGivenDistNodes().indexOf(node1)), node1.getMinimumBound(), node1.getMaximumBound(), node1.getGivenDistMutability());
					}
					else if (node1.getHasGoal() == 1)
					{
						listPane.displayDistributionData(currentView.getGoalDistributions().get(currentView.getGoalDistNodes().indexOf(node1)), node1.getMinimumBound(), node1.getMaximumBound(), null);
					}
					listPane.getDescriptionTextArea().setText(node1.getDescription());

					Rectangle nodeArea = new Rectangle(node1.getXPos() - 25, node1.getYPos() - 25, 100, 100);

					if (!networkPane.getVisibleRect().contains(nodeArea))
					{
						networkPane.scrollRectToVisible(nodeArea);
					}

					break;
				}
			}
		}
	}



	/****************************************
	 ** Currently Unused Interface Methods **
	 ****************************************/

	public void keyReleased(KeyEvent evt) { }

	public void keyTyped(KeyEvent evt) { }

	public void mouseClicked(MouseEvent evt) { }

	public void mouseEntered(MouseEvent evt) { }

	public void mouseExited(MouseEvent evt) { }

	public void mouseReleased(MouseEvent evt) { }



	/**********************
	 ** Internal Classes **
	 **********************/

	private class BeliefListenerDialog extends InternalModalDialog
	{
		private String type;
		private JOptionPane pane;

		public BeliefListenerDialog(String title, String type, JOptionPane pane)
		{
			super(title, belief, pane);

			this.type = type;
			this.pane = pane;
		}

		public void cleanUpAfterClosing()
		{
			if (type.equals("importSaveQuery"))
			{
				if (pane.getValue().equals(JOptionPane.YES_OPTION))
				{
					//saveNetwork();
					//importNetwork();
				}
				else if (pane.getValue().equals(JOptionPane.NO_OPTION))
				{
					importNetwork();
				}
			}
			else if (type.equals("logoutSaveQuery"))
			{
				if (pane.getValue().equals(JOptionPane.YES_OPTION))
				{
				}
				else if (pane.getValue().equals(JOptionPane.NO_OPTION))
				{
					logOut();
				}
			}
		}
	}

	private class NetworkFilter extends FileFilter
	{
		public final static String csv = "csv";

		public NetworkFilter()
		{
			super();
		}

		public boolean accept(File file)
		{
			boolean accepted = false;

			if (file.isDirectory())
			{
				accepted = true;
			}
			else
			{
				String extension = this.getExtension(file);

				if (extension != null)
				{
					if (extension.equals(csv))
					{
						accepted = true;
					}
					else
					{
						accepted = false;
					}
				}
			}

			return accepted;
		}

		public String getDescription()
		{
			return "CSV Files (*.csv)";
		}

		public String getExtension(File file)
		{
			String extension = null;
			String name = file.getName();
			int i = name.lastIndexOf('.');

			if (i > 0 && i < name.length() - 1)
			{
				extension = name.substring(i + 1).toLowerCase();
			}

			return extension;
		}
	}
}
