package de.ugoe.cs.eventbench.swing;

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;

import de.ugoe.cs.eventbench.assertions.AssertEvent;
import de.ugoe.cs.eventbench.assertions.FileEqualsReplay;
import de.ugoe.cs.eventbench.assertions.TextEqualsReplay;
import de.ugoe.cs.eventbench.data.Event;
import de.ugoe.cs.eventbench.data.GlobalDataContainer;
import de.ugoe.cs.util.console.Console;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.JFileChooser;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.border.EtchedBorder;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;

public class DlgInsert extends JDialog {

	/**
	 * Id for object serialization.
	 */
	private static final long serialVersionUID = 1L;

	private final JPanel contentPanel = new JPanel();
	private JTextField textFieldExpectedValue;
	private JTextField textFieldActualFile;
	private JTextField textFieldExpectedFile;

	/**
	 * Launch the application.
	 */
	public static void showDialog(List<Event<?>> sequences, int selectedIndex,
			final boolean insertBefore) {
		try {
			DlgInsert dialog = new DlgInsert(sequences, selectedIndex,
					insertBefore);
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the dialog.
	 */
	@SuppressWarnings("unchecked")
	public DlgInsert(final List<Event<?>> sequences, final int selectedIndex,
			final boolean insertBefore) {

		final javax.swing.DefaultListModel modelListTargets = new javax.swing.DefaultListModel();

		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setTitle("Insert testcase");

		setModal(true);
		setBounds(100, 100, 530, 631);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);
		final JComboBox comboBoxTestcase = new JComboBox();
		final JPanel panelTextEquals = new JPanel();
		panelTextEquals.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		final JPanel panelFileEquals = new JPanel();
		panelFileEquals.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));

		// JComboBox: comboBoxTestcase
		comboBoxTestcase.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if ("comboBoxChanged".equals(arg0.getActionCommand())) {

					// TextEquals
					if (comboBoxTestcase.getSelectedIndex() == 0) {
						panelTextEquals.setVisible(true);
						panelFileEquals.setVisible(false);
					}
					// FileEquals
					else if (comboBoxTestcase.getSelectedIndex() == 1) {
						panelTextEquals.setVisible(false);
						panelFileEquals.setVisible(true);
					}
				}
			}
		});
		comboBoxTestcase.setModel(new DefaultComboBoxModel(new String[] {
				"TextEquals", "OutputFileEquals" }));
		comboBoxTestcase.setSelectedIndex(0);
		comboBoxTestcase.setBounds(91, 11, 178, 20);
		contentPanel.add(comboBoxTestcase);
		// ***

		// JLabel
		JLabel label = new JLabel("Testcase:");
		label.setBounds(12, 14, 86, 14);
		contentPanel.add(label);

		JLabel label_1 = new JLabel("Expected value:");
		label_1.setBounds(10, 11, 96, 14);

		JLabel label_2 = new JLabel("Target:");
		label_2.setBounds(10, 38, 86, 14);
		// ***

		// JTextField: textFieldExpectedValue
		textFieldExpectedValue = new JTextField();
		textFieldExpectedValue.setColumns(10);
		textFieldExpectedValue.setBounds(116, 8, 368, 20);
		// ***

		// JPanel: panel
		panelTextEquals.setLayout(null);
		panelTextEquals.setBounds(10, 39, 494, 350);
		contentPanel.add(panelTextEquals);
		panelTextEquals.add(label_1);
		panelTextEquals.add(label_2);
		panelTextEquals.add(textFieldExpectedValue);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(421, 36, 63, 14);
		panelTextEquals.add(scrollPane);

		final JList listTargets = new JList(modelListTargets);		
		scrollPane.setViewportView(listTargets);
		
		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(10, 63, 474, 276);
		panelTextEquals.add(scrollPane_1);
		
		//JTree to hold the targets
		JTree tree = new JTree();
		tree.setModel(new DefaultTreeModel(
			new DefaultMutableTreeNode("Targets") {
				{
					List<DefaultMutableTreeNode> nodes = new ArrayList<DefaultMutableTreeNode>();
					List<String> listTargets = new ArrayList<String>();
					List<String> sortedTargets = new ArrayList<String>();

					try {
						listTargets = (List<String>) GlobalDataContainer.getInstance().getData("ListTargets");
					}
					catch (ClassCastException e) {
						Console.println("Not able to cast data in GlobalDataContainer to List of Strings");
					}
		
					int parts = 1;
					while(sortedTargets.size() < listTargets.size()) {
						for(int i=0; i<listTargets.size(); i++) {
							String splitted[] = listTargets.get(i).split("/>");
							if(splitted.length == parts) {
								sortedTargets.add(listTargets.get(i));
								modelListTargets.addElement(listTargets.get(i));
								
								//insert in tree
								boolean inserted = false;
								for(int j=parts-2; j>=0 && !inserted; j--) {
									splitted[j] = splitted[j] + "/>";
									for(int k=0; k<nodes.size(); k++) {
										if(nodes.get(k).toString().compareTo(splitted[j]) == 0) {
											DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(splitted[j+1]);
											nodes.add(newNode);
											nodes.get(k).add(newNode);
											inserted = true;
											break;
										}
									}
								}
								
								if(!inserted) {
									DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(listTargets.get(i).toString());
									nodes.add(newNode);
									add(newNode);
								}
							}
						}
						
						parts++;
					}
				}
			}
		));
		scrollPane_1.setViewportView(tree);
		

		if (listTargets.getComponentCount() > 0)
			listTargets.setSelectedIndex(0);

		panelFileEquals.setBounds(12, 400, 494, 120);
		contentPanel.add(panelFileEquals);
		panelFileEquals.setLayout(null);
		panelFileEquals.setVisible(false);

		JLabel lblNewLabel = new JLabel("Actual file:");
		lblNewLabel.setBounds(10, 11, 89, 14);
		panelFileEquals.add(lblNewLabel);

		textFieldActualFile = new JTextField();
		textFieldActualFile.setBounds(10, 30, 474, 20);
		panelFileEquals.add(textFieldActualFile);
		textFieldActualFile.setColumns(10);

		JButton btnNewButton = new JButton("Search file");
		btnNewButton.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent arg0) {
				final JFileChooser fc = new JFileChooser();
				if (fc.showOpenDialog(contentPanel) == 0) {
					textFieldExpectedFile.setText(fc.getSelectedFile()
							.getAbsolutePath());
				}
			}
		});
		btnNewButton.setBounds(93, 61, 89, 23);
		panelFileEquals.add(btnNewButton);

		JLabel lblNewLabel_1 = new JLabel("Expected file:");
		lblNewLabel_1.setBounds(10, 70, 89, 14);
		panelFileEquals.add(lblNewLabel_1);

		textFieldExpectedFile = new JTextField();
		textFieldExpectedFile.setColumns(10);
		textFieldExpectedFile.setBounds(10, 88, 474, 20);
		panelFileEquals.add(textFieldExpectedFile);
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
			buttonPane.setBounds(12, 531, 494, 51);
			contentPanel.add(buttonPane);
			{
				// JButton: okButton
				JButton okButton = new JButton("Insert");
				okButton.setBounds(349, 11, 135, 31);
				okButton.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent arg0) {

						// FileEquals
						if (panelFileEquals.isVisible()) {
							if (textFieldActualFile.getText().length() == 0)
								JOptionPane.showMessageDialog(null,
										"Please declare an actual file.",
										"No actual file declared",
										JOptionPane.OK_OPTION);
							else if (!new File(textFieldExpectedFile.getText())
									.exists()) {
								if (textFieldExpectedFile.getText().length() == 0)
									JOptionPane.showMessageDialog(null,
											"Please choose an expected file.",
											"No expected file chosen",
											JOptionPane.OK_OPTION);
								else
									JOptionPane.showMessageDialog(
											null,
											"The expected file \""
													+ textFieldActualFile
															.getText()
													+ "\" does not exist.",
											"Expected file does not exist",
											JOptionPane.OK_OPTION);
								return;
							} else {
								FileEqualsReplay file = new FileEqualsReplay();
								file.setActualFile(textFieldActualFile
										.getText());
								file.setExpectedFile(textFieldExpectedFile
										.getText());

								AssertEvent<FileEqualsReplay> e = new AssertEvent<FileEqualsReplay>(
										"FileEquals");
								e.addReplayEvent(file);
								e.setTarget(" ");
								if (insertBefore)
									sequences.add(selectedIndex, e);
								else
									sequences.add(selectedIndex + 1, e);
							}
						}
						// TextEquals
						else {
							if (textFieldExpectedValue.getText().length() == 0) {
								JOptionPane
										.showMessageDialog(
												null,
												"\"Expected value\" is missing.",
												"Expected value",
												JOptionPane.OK_OPTION);
								return;
							} else if (listTargets.getSelectedIndex() == -1) {
								JOptionPane.showMessageDialog(null,
										"Please select a target.",
										"No target selected",
										JOptionPane.OK_OPTION);
								return;
							} else {
								TextEqualsReplay text = new TextEqualsReplay();
								text.setExpectedValue(textFieldExpectedValue
										.getText());
								text.setTarget(modelListTargets.get(
										listTargets.getSelectedIndex())
										.toString());

								AssertEvent<TextEqualsReplay> e = new AssertEvent<TextEqualsReplay>(
										"TextEquals");
								e.addReplayEvent(text);
								e.setTarget(" ");
								if (insertBefore)
									sequences.add(selectedIndex, e);
								else
									sequences.add(selectedIndex + 1, e);
							}
						}

						dispose();
					}
				});
				buttonPane.setLayout(null);
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
				// ***
			}

			{
				// JButton: cancelButton
				JButton cancelButton = new JButton("Cancel");
				cancelButton.setBounds(10, 11, 135, 31);
				cancelButton.addMouseListener(new MouseAdapter() {

					public void mouseClicked(MouseEvent arg0) {
						dispose();
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
				// ***
			}
		}
		// ***
	}
}
