package de.visone.nlpext.deprecated;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import de.visone.base.Mediator;
import de.visone.base.Network;
import de.visone.nlpext.gui.AbstractNLPPanel;
import de.visone.nlpext.util.HeadlessMediator;

/**
 * Provides functionality for pruning a network, simplifying the edges of a
 * network and to scale nodes so that their area is proportional to a centrality
 * measure.
 * 
 * @author <a href="mailto:endele@inf.uni-konstanz.de">Simon Endele</a>
 */
@SuppressWarnings("serial")
public class VisualizationPanel extends AbstractNLPPanel implements
		ActionListener {
	public static final String[] TASKS = { "Merge multi-edges",
			"NodeSize = Centrality", "Prune" };

	private JComboBox taskComboBox;
	private JTextField attributeTextField;
	private JTextField valueTextField;
	private JCheckBox pruneAlsoEqualCheckBox;
	private JButton applyButton;

	public VisualizationPanel(final Mediator mediator) {
		super(mediator);
	}

	@Override
	protected void init() {
		setLayout(new GridBagLayout());
		// networkDisplayPanel.setBorder(BorderFactory.createTitledBorder(getString("display.title")));
		final GridBagConstraints c = new GridBagConstraints();
		c.insets = new Insets(GAP, GAP, 0, 0); // (top, left, bottom, right)

		taskComboBox = new JComboBox(TASKS);
		attributeTextField = new JTextField("Betweenness", 10);
		valueTextField = new JTextField("0.0", 10);
		pruneAlsoEqualCheckBox = new JCheckBox("", false);

		applyButton = new JButton("Apply");
		applyButton.addActionListener(this);

		c.anchor = GridBagConstraints.NORTHWEST;
		c.gridy = 0;
		c.gridx = 0;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(new JLabel("Task: "), c);
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(taskComboBox, c);
		c.gridy++;
		c.gridx = 0;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(new JLabel("Attribute name: "), c);
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(attributeTextField, c);
		c.gridy++;
		c.gridx = 0;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(new JLabel("ScaleFactor/MinValue: "), c);
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(valueTextField, c);
		c.gridy++;
		c.gridx = 0;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(new JLabel("Prune also equal: "), c);
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0.0;
		add(pruneAlsoEqualCheckBox, c);
		c.gridy++;
		c.anchor = GridBagConstraints.NORTH;
		c.insets = new Insets(2 * GAP, GAP, 2 * GAP, GAP); // (top, left,
															// bottom, right)
		c.gridx = 0;
		c.gridwidth = 3;
		c.weighty = 1.0;
		add(applyButton, c);

		// dummy panel
		c.insets = new Insets(0, 0, 0, 0); // (top, left, bottom, right)
		c.weighty = 0.0;
		c.weightx = 1.0;
		c.gridy = 0;
		c.gridx = 2;
		c.gridwidth = 1;
		add(new JPanel(), c);
	}

	@Override
	public void actionPerformed(final ActionEvent e) {
		if (e.getSource() == applyButton) {
			checkInput();
		}
	}

	/**
	 * Tests if a network is selected, if it has an attribute with the specified
	 * name and if a double value was entered to the value text field, and the
	 * calls the task method.
	 */
	private void checkInput() {
		final int task = taskComboBox.getSelectedIndex();
		final Network network = mediator.getActiveNetwork();
		if (network == null) {
			error("No network selected!"); // ///////////////////////
			return;
		}
		if (task == 0) {
			NetworkUtil.simplifyEdges(network);
			LayoutUtil.updateViews(network);
			return;
		}
		final String attrName = attributeTextField.getText();
		final String valueString = valueTextField.getText();
		double minValue;
		try {
			minValue = Double.parseDouble(valueString);
		} catch (final NumberFormatException ex) {
			error("No double value: " + valueString + "!");
			return;
		}
		switch (taskComboBox.getSelectedIndex()) {
		case 1:
			LayoutUtil.scaleNodes(network, attrName, minValue);
			break;
		case 2:
			NetworkUtil.removeNodes(network, attrName, minValue,
					pruneAlsoEqualCheckBox.isSelected());
			break;
		}
		LayoutUtil.updateViews(network);
	}

	/**
	 * Loads a network from a graphml-file (and the betweenness from a
	 * csv-file), places each node label in the center of its node, removes
	 * nodes [...], simplifies the edges, applies a SmartOrganicLayouter and
	 * saves the network as pdf.
	 */
	public static void main(final String[] args) throws Exception {
		new HeadlessMediator();
		if (args == null || args.length != 7) {
			System.out.println("Usage is:: ");
			System.out
					.println("\tjava VisualizationPanel <network.graphml> <centrality.csv> <minCentr> <pruneEqual> <nodeScale> <doLayout> <minNodeDist>");
			return;
		}
		final File networkFile = new File(args[0]);
		final File csvFile = new File(args[1]);
		final double minCentr = Double.parseDouble(args[2]);
		final boolean pruneEqual = Boolean.parseBoolean(args[3]);
		final double nodeScale = Double.parseDouble(args[4]);
		final boolean layout = Boolean.parseBoolean(args[5]);
		final double minNodeDist = Double.parseDouble(args[6]);

		// guess the attribute name. works for data written by
		// CentralityComputer
		final String attributeName = csvFile.getName()
				.replaceFirst("\\.csv$", "").replaceFirst(".*_", "");
		final Network network = NetworkUtil.loadNetwork(networkFile);
		// NodeMap wordMap = TextNetwork.getWordMap(network);
		NetworkUtil.loadAttribute(network, csvFile, NetworkUtil.NAME_ATTRIBUTE);

		LayoutUtil.centerLabels(network);

		NetworkUtil.removeNodes(network, attributeName, minCentr, pruneEqual);
		System.out.println("After pruning: n=" + network.numberOfNodes()
				+ ", m=" + network.numberOfEdges());
		NetworkUtil.simplifyEdges(network);
		System.out.println("After simplifying: n=" + network.numberOfNodes()
				+ ", m=" + network.numberOfEdges());
		LayoutUtil.scaleNodes(network, attributeName, nodeScale);

		if (layout) {
			System.out.println("Layouting network...");
			LayoutUtil.getDefault().layout(network);
			// LayoutUtil.getStressMajorization(true, true, minNodeDist).layout(
			// network);
		}

		final String networkFileName = networkFile.getName();
		// save network as pdf
		final File output = new File(networkFileName.substring(0,
				networkFileName.lastIndexOf(".")) + ".pdf");
		NetworkUtil.exportAsPDF(network, output);

		// save network as graphml
		final File outputGraphML = new File(networkFileName.substring(0,
				networkFileName.lastIndexOf(".")) + "_layout.graphml");
		NetworkUtil.saveNetwork(network, outputGraphML);
	}
}
