/**
 * 
 */
package cz.neubauer.tomas.hazardanalysis.viewcontroller.administration;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import cz.neubauer.tomas.hazardanalysis.model.components.Component;
import cz.neubauer.tomas.hazardanalysis.model.dangers.DangerGroup;
import cz.neubauer.tomas.hazardanalysis.model.dangers.DangerType;
import cz.neubauer.tomas.hazardanalysis.model.dangers.DangerVariant;
import cz.neubauer.tomas.hazardanalysis.model.tablemodels.ComponentDangerVariantTableModel;
import cz.neubauer.tomas.hazardanalysis.viewcontroller.windowmanipulator.WindowManipulator;

/**
 * @author Tomáš Neubauer
 */
public class ComponentDangerVariantFrame extends JFrame {

	private boolean saved;

	/**
	 * 
	 */
	private static final long serialVersionUID = -2009393442557761987L;

	private AdminFrame owner;

	private JPanel pnlForm, pnlTable, pnlButtons;

	private JButton btnSave, btnClose;

	private JTextField txtComponentName;

	private JTextField txtComponentLocation;

	private JTable tableVariants;

	private ComponentDangerVariantTableModel componentDangerVariantTableModel;

	private ArrayList<Integer> assignedDangerVariantIDs;

	private JComboBox cmbGroups;

	private JComboBox cmbTypes;

	private ArrayList<DangerGroup> dangerGroups;

	private DangerGroup currentDangerGroup;

	private DangerType currentDangerType;

	private Component component;

	public ComponentDangerVariantFrame(AdminFrame owner, Component component,
			ArrayList<DangerGroup> dangerGroups) {
		this.owner = owner;
		this.component = component;
		this.dangerGroups = dangerGroups;
		assignedDangerVariantIDs = new ArrayList<Integer>(10);
		saved = true;
		initGUI();
		// updateSelectedDangerVariants();
		refreshDangerVariants();
	}

	// /**
	// *
	// */
	// private void updateSelectedDangerVariants() {
	// assignedDangerVariantIDs.clear();
	// int dangerGroupCount = component.getDangerGroupCount();
	// DangerGroup dg;
	// for (int i = 0; i < dangerGroupCount; i++) {
	// dg = component.getDangerGroup(i);
	//
	// int dangerTypeCount = dg.getDangerTypeCount();
	// DangerType dt;
	// for (int j = 0; j < dangerTypeCount; j++) {
	// dt = dg.getDangerType(j);
	//
	// int dangerVariantCount = dt.getDangerVariantCount();
	// for (int k = 0; k < dangerVariantCount; k++) {
	// assignedDangerVariantIDs.add(new Integer(dt
	// .getDangerVariant(k).getId()));
	// }
	// }
	// }
	// }

	/**
	 * 
	 */
	private void initGUI() {
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setTitle("Přiřazení nebezpečí komponentě");

		initPanelTable();
		this.add(pnlTable, BorderLayout.CENTER);

		initPanelForm();
		this.add(pnlForm, BorderLayout.NORTH);

		initPanelButtons();
		this.add(pnlButtons, BorderLayout.SOUTH);

		pack();
		WindowManipulator.centerWindow(this);
		setVisible(true);
	}

	/**
	 * 
	 */
	private void initPanelButtons() {
		pnlButtons = new JPanel(new FlowLayout(FlowLayout.CENTER));

		btnSave = new JButton("Uložit");
		btnSave.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ComponentDangerVariantFrame.this.btnSavePerformed();
			}
		});
		pnlButtons.add(btnSave);

		btnClose = new JButton("Zavřít");
		btnClose.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ComponentDangerVariantFrame.this.btnClosePerformed();
			}
		});
		pnlButtons.add(btnClose);
	}

	/**
	 * 
	 */
	protected void btnClosePerformed() {
		dispose();
	}

	/**
	 * 
	 */
	protected void btnSavePerformed() {
		if (txtComponentName.getText().equals("")) {
			JOptionPane
					.showMessageDialog(this, "Není vyplněn název komponenty");
		} else if (txtComponentLocation.getText().equals("")) {
			JOptionPane.showMessageDialog(this,
					"Není vyplněno umístění komponenty");
		} else {
			component.setName(txtComponentName.getText());
			component.setLocation(txtComponentLocation.getText());
			component.saveToDB(owner.getConnection());

			try {
				Statement stmt = owner.getConnection().createStatement();
				Statement stmt2 = owner.getConnection().createStatement();
				// stmt
				// .executeUpdate("DELETE FROM component_danger_variant cdv
				// WHERE cdv.component_id = '"
				// + component.getId()
				// + "' AND (SELECT danger_type_id FROM danger_variant dv WHERE
				// dv.id = cdv.danger_variant_id) = '"
				// + currentDangerType.getId() + "';");
				ResultSet rs = stmt2
						.executeQuery("SELECT id FROM danger_variant WHERE danger_type_id = '"
								+ currentDangerType.getId() + "';");
				while (rs.next()) {
					stmt
							.executeUpdate("DELETE FROM component_danger_variant WHERE component_id = '"
									+ component.getId()
									+ "' AND danger_variant_id = '"
									+ rs.getInt("id") + "';");
				}

				// omponent.setDangerGroups(new ArrayList<DangerGroup>(100));

				DangerType dt = currentDangerType;

				int dangerVariantCount = dt.getDangerVariantCount();
				DangerVariant dv;
				for (int k = 0; k < dangerVariantCount; k++) {
					dv = dt.getDangerVariant(k);
					if (dv.isSelected()) {
						stmt
								.executeUpdate("INSERT INTO component_danger_variant VALUES ('"
										+ component.getId()
										+ "', '"
										+ dv.getId() + "');");
					}
				}

				owner.refreshTree();
				owner.getOwner().refresh();
				component = owner.getOwner().getApplication()
						.getComponentCatalog().getComponentByName(
								component.getName());
				componentDangerVariantTableModel.setComponent(component);
				componentDangerVariantTableModel.fireTableDataChanged();
				stmt.close();
				JOptionPane.showMessageDialog(this, "Komponenta byla uložena",
						"Informace", JOptionPane.INFORMATION_MESSAGE);
				saved = true;
				// dispose();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 
	 */
	private void initPanelForm() {
		pnlForm = new JPanel(new GridLayout(8, 1));

		pnlForm.add(new JLabel("Název komponenty"));

		txtComponentName = new JTextField(component.getName(), 10);
		pnlForm.add(txtComponentName);

		pnlForm.add(new JLabel("Umístění komponenty"));

		txtComponentLocation = new JTextField(component.getLocation(), 10);
		pnlForm.add(txtComponentLocation);

		initCombos();
		pnlForm.add(new JLabel("Skupina nebezpečí"));
		pnlForm.add(cmbGroups);
		pnlForm.add(new JLabel("Typ nebezpečí"));
		pnlForm.add(cmbTypes);
	}

	/**
	 * 
	 */
	private void initPanelTable() {
		pnlTable = new JPanel();
		componentDangerVariantTableModel = new ComponentDangerVariantTableModel(
				component, new ArrayList<DangerVariant>(10));

		tableVariants = new JTable(componentDangerVariantTableModel);

		tableVariants.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		tableVariants.getColumnModel().getColumn(0).setPreferredWidth(400);
		tableVariants.getColumnModel().getColumn(1).setPreferredWidth(50);

		tableVariants.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				ComponentDangerVariantFrame.this.tableClicked();
			}
		});
		JScrollPane spn = new JScrollPane(tableVariants);
		spn.setViewportView(tableVariants);
		spn.setPreferredSize(new Dimension(453, 200));

		pnlTable.add(spn, BorderLayout.CENTER);
	}

	/**
	 * @param dangerGroup
	 * 
	 */
	private void refreshComboTypes(int dangerGroupIndex) {
		cmbTypes.removeAllItems();
		currentDangerGroup = dangerGroups.get(dangerGroupIndex);
		ArrayList<DangerType> types = currentDangerGroup.getTypes();
		int dangerTypeCount = types.size();
		for (int i = 0; i < dangerTypeCount; i++) {
			cmbTypes.addItem(types.get(i));
		}
		if (types.size() > 0) {
			currentDangerType = types.get(0);
		} else {
			currentDangerType = null;
			cmbTypes.addItem("Tato skupina neobsahuje žádné typy");
		}

	}

	/**
	 * 
	 */
	private void initCombos() {
		cmbGroups = new JComboBox();
		cmbTypes = new JComboBox();

		cmbGroups.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ComponentDangerVariantFrame.this.cmbGroupsChanged();
			}
		});
		int dangerGroupCount = dangerGroups.size();
		for (int i = 0; i < dangerGroupCount; i++) {
			cmbGroups.addItem(dangerGroups.get(i));
		}

		cmbTypes = new JComboBox();
		cmbTypes.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ComponentDangerVariantFrame.this.cmbTypesChanged();
			}
		});
		refreshComboTypes(0);
	}

	/**
	 * 
	 */
	protected void tableClicked() {
		int selectedRowIndex = tableVariants.getSelectedRow();
		int selectedColumnIndex = tableVariants.getSelectedColumn();
		if (selectedColumnIndex == 1 && selectedRowIndex >= 0) {
			saved = false;
			DangerVariant selectedDangerVariant = currentDangerType
					.getVariants().get(selectedRowIndex);
			selectedDangerVariant.setSelected(!selectedDangerVariant
					.isSelected());
			componentDangerVariantTableModel.fireTableDataChanged();
		}
	}

	/**
	 * 
	 */
	protected void cmbTypesChanged() {
		int selectedIndex = cmbTypes.getSelectedIndex();
		if (selectedIndex >= 0) {
			if (!saved) {
				if (JOptionPane.showConfirmDialog(this,
						"Byly provedeny změny. Uložit?") == JOptionPane.YES_OPTION) {
					btnSavePerformed();
					// refreshDangerVariants();
				}
			}
			saved = true;
			if (currentDangerGroup.getDangerTypeCount() > 0) {
				currentDangerType = currentDangerGroup
						.getDangerType(selectedIndex);
			} else {
				currentDangerType = null;
			}
			refreshDangerVariants();
		}
	}

	/**
	 * 
	 */
	protected void cmbGroupsChanged() {
		currentDangerGroup = dangerGroups.get(cmbGroups.getSelectedIndex());
		refreshComboTypes(cmbGroups.getSelectedIndex());
	}

	/**
	 * 
	 */
	private void refreshDangerVariants() {
		if (currentDangerType != null) {
			int dangerVariantCount = currentDangerType.getDangerVariantCount();
			ArrayList<DangerVariant> variants = currentDangerType.getVariants();
			DangerVariant currentDangerVariant;
			for (int i = 0; i < dangerVariantCount; i++) {
				currentDangerVariant = variants.get(i);
				if (component.hasDangerVariant(currentDangerVariant)) {
					currentDangerVariant.setSelected(true);
				} else {
					currentDangerVariant.setSelected(false);
				}
			}
			componentDangerVariantTableModel
					.setDangerVariants(currentDangerType.getVariants());
		} else {
			componentDangerVariantTableModel.getDangerVariants().clear();
		}
		// this.tableVariants.setModel(dangerVariantTableModel);
	}

	public ArrayList<Integer> getSelectedDangerVariantIDs() {
		return assignedDangerVariantIDs;
	}

	public void setSelectedDangerVariantIDs(
			ArrayList<Integer> selectedDangerVariantIDs) {
		assignedDangerVariantIDs = selectedDangerVariantIDs;
	}
}
