package applets.error;

// 3DPedViz imports
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;

import java.util.*;

import pedviz.algorithms.*;
import pedviz.algorithms.sugiyama.SugiyamaLayout;
import pedviz.graph.*;
import pedviz.loader.CsvGraphLoader;
import pedviz.loader.RessourceGraphLoader;
import pedviz.view.DefaultEdgeView;
import pedviz.view.DefaultNodeView;
import pedviz.view.GraphView;
import pedviz.view.GraphView2D;
import pedviz.view.NodeEvent;
import pedviz.view.NodeListener;
import pedviz.view.rules.ColorRule;
import pedviz.view.rules.ShapeRule;
import pedviz.view.symbols.SymbolSexFemale;
import pedviz.view.symbols.SymbolSexMale;

public class Errors extends JApplet {
	GraphView graphView;
	LayoutedGraph layoutedGraph;

	JTree errorList;

	Graph graph;
	DefaultMutableTreeNode errorNode;

	DefaultNodeView n;

	DefaultEdgeView e;

	public void init() {

		graph = new Graph();

		// Loads graph from database (user, pass, connection, table)
		RessourceGraphLoader loader = new RessourceGraphLoader(
				getParameter("datasource"), ",");
		// sets columnnames for id, mom-id and dad-id
		loader.setSettings("PID", "MOM", "DAD");
		loader.load(graph);

		// Clusters nodes with same parents
		SameParents sameParents = new SameParents(graph);
		sameParents.run();

		//	
		graph.buildHierarchie(new HierarchieUpDown());

		e = new DefaultEdgeView();
		e.setColor(new Color(100, 100, 100));
		e.setHighlightedColor(Color.RED);
		e.setHighlightedWidth(0.5f);
		e.setColorForLongLines(new Color(200, 200, 200));
		e.setConnectChildren(true);
		e.setGapBottom(5);

		n = new DefaultNodeView();
		n.setColor(new Color(255, 255, 255));
		n.addHintAttribute("PID");
		n.addHintAttribute("MOM");
		n.addHintAttribute("DAD");
		n.addHintAttribute("SEX");
		n.setHighlightedColor(Color.RED);

		// runs sugiyama
		SugiyamaLayout layout = new SugiyamaLayout(graph, n, e);
		layout.run();
		layoutedGraph = layout.getLayoutGraph();

		// calcs coordinates for nodes with the "rubber bands" algorithm
		RubberBands rubberBands = new RubberBands(layoutedGraph);
		rubberBands.run();

		graphView = new GraphView2D();

		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(graphView.getComponent());

		errorList = new JTree();
		errorNode = new DefaultMutableTreeNode("Errors (0)");
		errorList = new JTree(errorNode);

		JScrollPane scrollPane = new JScrollPane(errorList);
		scrollPane.setMinimumSize(new Dimension(100, 100));
		scrollPane.setMaximumSize(new Dimension(100, 100));
		scrollPane.setPreferredSize(new Dimension(100, 100));
		JPanel panel = new JPanel(new BorderLayout());
		panel.add(scrollPane, BorderLayout.CENTER);
		JButton button = new JButton("Auto repair");
		button.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				Vector<String> log = GraphRepair.repair(graph);
				String temp = "";
				for (String message : log) {
					temp += message + "\n";
				}
				JOptionPane.showMessageDialog(null, temp);

				graph.buildHierarchie(new HierarchieUpDown());
				// runs sugiyama
				SugiyamaLayout layout = new SugiyamaLayout(graph, n, e);
				layout.run();
				layoutedGraph = layout.getLayoutGraph();

				// calcs coordinates for nodes with the "rubber bands" algorithm
				RubberBands rubberBands = new RubberBands(layoutedGraph);
				rubberBands.run();
				graphView.setGraph(layoutedGraph);

				checkErrors();
			}

		});
		panel.add(button, BorderLayout.SOUTH);
		getContentPane().add(panel, BorderLayout.SOUTH);
		// set background-color
		graphView.setBackgroundColor(new Color(255, 255, 255));

		// node look
		graphView.addRule(new ShapeRule("sex", "2", new SymbolSexFemale()));
		graphView.addRule(new ShapeRule("sex", "1", new SymbolSexMale()));
		graphView.addRule(new ColorRule("virtual", "1", Color.GRAY));

		graphView.setGraph(layoutedGraph);

		checkErrors();
	}

	private void checkErrors() {
		ErrorChecking errors = new ErrorChecking(graph);
		errors.run();

		errorNode.removeAllChildren();
		errorNode.setUserObject("Errors (" + errors.getErrors().size()
				+ " items)");

		for (GraphError i : errors.getErrors()) {
			errorNode.add(new DefaultMutableTreeNode(i));
		}
		int row = 0;
		while (row < errorList.getRowCount()) {
			errorList.expandRow(row);
			row++;
		}
		errorList.addTreeSelectionListener(new TreeSelectionListener() {

			public void valueChanged(TreeSelectionEvent arg0) {
				DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) errorList
						.getLastSelectedPathComponent();
				if (treeNode.getUserObject() instanceof GraphError) {
					GraphError error = (GraphError) treeNode.getUserObject();
					Node node = error.getNodes().get(0);
					graphView.unHighlightAll();
					graphView.highlight(error.getNodes());
					if (error.getType() == GraphError.INVALID_SEX_DAD) {
						graphView.highlight(graph.getNode(node.getIdDad()));
					}
					if (error.getType() == GraphError.INVALID_SEX_MOM) {
						graphView.highlight(graph.getNode(node.getIdMom()));
					}
				}
			}

		});
		errorList.updateUI();
	}

}

