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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.BorderFactory;
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.JTextArea;
import javax.swing.JTextField;

import cz.neubauer.tomas.hazardanalysis.Rizika;
import cz.neubauer.tomas.hazardanalysis.model.dangers.DangerEstimationBacking;
import cz.neubauer.tomas.hazardanalysis.model.dangers.DangerVariant;
import cz.neubauer.tomas.hazardanalysis.model.stages.VariantStage;

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

	/**
	 * 
	 */
	private static final long serialVersionUID = 5956510294800607915L;

	private Rizika application;

	private CriticalDangerAnalysisFrame owner;

	private ArrayList<DangerEstimationBacking> dangerData;

	private JScrollPane scrollPane;

	private JPanel pnlMain;

	private StepPanel stpStep1, stpStep2, stpStep3;

	private DangerCalculatorPanel cpnPocatecniRiziko;

	private JPanel pnlVariant;

	private JComboBox cmbVariant;

	private JPanel pnlHeader;

	private JTextField txtDangerNumber, txtDangerID, txtDangerGroup,
			txtDangerType;

	private JPanel pnlDescription;

	private JPanel pnlPersons;

	private JButton btnPersonSelection;

	private JTextField txtStage, txtDangerArea, txtPersons;

	private JComboBox cmbState;

	private JTextField txtDangerVariant;

	private JTextArea txaDangerEventDescription;

	private JPanel pnlButton;

	private JButton btnSave;

	private PersonSelectionFrame personSelectionFrame;

	public DangerEstimationFrame(Rizika application,
			CriticalDangerAnalysisFrame owner,
			ArrayList<VariantStage> variantStages) {
		this.owner = owner;
		this.application = application;
		dangerData = new ArrayList<DangerEstimationBacking>(variantStages
				.size());
		setVariantStagesData(variantStages);
		initGUI();
	}

	/**
	 * @param application
	 * @param variantStages
	 */
	public void setVariantStagesData(ArrayList<VariantStage> variantStages) {
		dangerData.clear();
		for (int i = 0; i < variantStages.size(); i++) {
			DangerEstimationBacking deb = new DangerEstimationBacking(
					application);
			deb.setVariantStage(variantStages.get(i));
			dangerData.add(deb);
		}
	}

	/**
	 * 
	 */
	private void initGUI() {
		setTitle("Formulář pro odhad rizika");
		setDefaultCloseOperation(HIDE_ON_CLOSE);
		GridBagLayout gbl = new GridBagLayout();
		pnlMain = new JPanel(gbl);

		gbl.rowHeights = new int[] { 14, 50, 75, 123, 123, 123 };

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(2, 6, 2, 6);
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		c.gridheight = 1;

		scrollPane = new JScrollPane(pnlMain);

		initVariantPanel();
		pnlMain.add(pnlVariant, c);
		c.gridy++;

		initHeaderPanel();
		pnlMain.add(pnlHeader, c);
		c.gridy++;

		initDescriptionPanel();
		pnlMain.add(pnlDescription, c);
		c.gridy++;

		initPocatecniPanel();
		pnlMain.add(cpnPocatecniRiziko, c);
		c.gridy++;

		initStep1Panel();
		pnlMain.add(stpStep1, c);
		c.gridy++;

		initStep2Panel();
		pnlMain.add(stpStep2, c);
		c.gridy++;

		initStep3Panel();
		pnlMain.add(stpStep3, c);
		c.gridy++;

		initButtonPanel();
		pnlMain.add(pnlButton, c);
		c.gridy++;

		scrollPane.setPreferredSize(new Dimension(800, 500));

		this.add(scrollPane);

		pack();
		setVisible(true);
		cmbVariantChanged();
	}

	/**
	 * 
	 */
	private void initButtonPanel() {
		pnlButton = new JPanel(new FlowLayout(FlowLayout.RIGHT));

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

	}

	/**
	 * 
	 */
	protected void btnSavePerformed() {
		DangerEstimationBacking deb = (DangerEstimationBacking) cmbVariant
				.getSelectedItem();

		int[] step0 = new int[] { cpnPocatecniRiziko.getS(),
				cpnPocatecniRiziko.getA(), cpnPocatecniRiziko.getE(),
				cpnPocatecniRiziko.getW() };
		deb.setStep0(step0);

		deb.setCounterAct1(stpStep1.getCounterActDescription());
		int[] step1 = new int[] { stpStep1.getS(), stpStep1.getA(),
				stpStep1.getE(), stpStep1.getW() };
		deb.setStep1(step1);

		deb.setCounterAct2(stpStep2.getCounterActDescription());
		int[] step2 = new int[] { stpStep2.getS(), stpStep2.getA(),
				stpStep2.getE(), stpStep2.getW() };
		deb.setStep2(step2);

		deb.setCounterAct3(stpStep3.getCounterActDescription());
		int[] step3 = new int[] { stpStep3.getS(), stpStep3.getA(),
				stpStep3.getE(), stpStep3.getW() };
		deb.setStep3(step3);

		deb.setDangerArea(txtDangerArea.getText());
		deb.setDangerEventDescription(txaDangerEventDescription.getText());
		deb.setPersons(txtPersons.getText());
		deb.setState(cmbState.getSelectedIndex());

		deb.saveHistory();

		JOptionPane.showMessageDialog(this, "Aktuální formulář byl uložen");

	}

	/**
	 * 
	 */
	private void initVariantPanel() {
		pnlVariant = new JPanel();

		cmbVariant = new JComboBox();
		for (int i = 0; i < dangerData.size(); i++) {
			cmbVariant.addItem(dangerData.get(i));
		}
		cmbVariant.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DangerEstimationFrame.this.cmbVariantChanged();

			}
		});

		pnlVariant.add(cmbVariant);
	}

	/**
	 * 
	 */
	protected void cmbVariantChanged() {
		DangerEstimationBacking deb = (DangerEstimationBacking) cmbVariant
				.getSelectedItem();

		DangerVariant dv = deb.getVariantStage().getDangerVariant();
		txtDangerNumber.setText(dv.getDangerType().getCode());

		ArrayList<DangerVariant> criticalVariants = owner.getCriticalVarians();

		int index = 0;
		DangerVariant currentDV;
		for (int i = 0; i < criticalVariants.size(); i++) {
			currentDV = criticalVariants.get(i);
			if (currentDV.getDangerType().equals(
					deb.getVariantStage().getDangerVariant().getDangerType())) {
				index++;
			}
			if (currentDV.equals(deb.getVariantStage().getDangerVariant())) {
				break;
			}
		}

		txtDangerID.setText(String.valueOf(index));
		txtDangerGroup.setText(dv.getDangerType().getDangerGroup().getName());
		txtDangerType.setText(dv.getDangerType().getDescription());
		txtStage.setText(deb.getVariantStage().getStage().getDescription());
		txtDangerVariant.setText(dv.getDescription());
		txtPersons.setText(deb.getPersons());
		txtDangerArea.setText(deb.getDangerArea());
		cmbState.setSelectedIndex(deb.getState());

		txaDangerEventDescription.setText(deb.getDangerEventDescription());

		cpnPocatecniRiziko.setS(deb.getStep0()[0]);
		cpnPocatecniRiziko.setA(deb.getStep0()[1]);
		cpnPocatecniRiziko.setE(deb.getStep0()[2]);
		cpnPocatecniRiziko.setW(deb.getStep0()[3]);

		stpStep1.setCounterActDescription(deb.getCounterAct1());
		stpStep1.setS(deb.getStep1()[0]);
		stpStep1.setA(deb.getStep1()[1]);
		stpStep1.setE(deb.getStep1()[2]);
		stpStep1.setW(deb.getStep1()[3]);

		stpStep2.setCounterActDescription(deb.getCounterAct2());
		stpStep2.setS(deb.getStep2()[0]);
		stpStep2.setA(deb.getStep2()[1]);
		stpStep2.setE(deb.getStep2()[2]);
		stpStep2.setW(deb.getStep2()[3]);

		stpStep3.setCounterActDescription(deb.getCounterAct3());
		stpStep3.setS(deb.getStep3()[0]);
		stpStep3.setA(deb.getStep3()[1]);
		stpStep3.setE(deb.getStep3()[2]);
		stpStep3.setW(deb.getStep3()[3]);

	}

	/**
	 * 
	 */
	private void initHeaderPanel() {
		GridBagLayout gbl = new GridBagLayout();
		gbl.columnWidths = new int[] { 80, 20, 80, 195 };
		gbl.rowHeights = new int[] { 13, 13 };
		pnlHeader = new JPanel(gbl);
		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(2, 6, 2, 6);
		c.gridwidth = 1;
		c.gridheight = 1;

		c.gridx = 0;
		c.gridy = 0;
		pnlHeader.add(new JLabel("Číslo nebezpečí dle ČSN EN 1050:"), c);

		txtDangerNumber = new JTextField();
		txtDangerNumber.setEditable(false);
		c.gridx = 0;
		c.gridy = 1;
		pnlHeader.add(txtDangerNumber, c);

		c.gridx = 1;
		c.gridy = 0;
		pnlHeader.add(new JLabel("Identif. číslo:"), c);

		txtDangerID = new JTextField();
		txtDangerID.setEditable(false);
		c.gridx = 1;
		c.gridy = 1;
		pnlHeader.add(txtDangerID, c);

		c.gridx = 2;
		c.gridy = 0;
		pnlHeader.add(new JLabel("Označení nebezpečí dle ČSN EN 1050:"), c);

		txtDangerGroup = new JTextField();
		txtDangerGroup.setEditable(false);
		c.gridx = 3;
		c.gridy = 0;
		pnlHeader.add(txtDangerGroup, c);

		txtDangerType = new JTextField();
		txtDangerType.setEditable(false);
		c.gridx = 2;
		c.gridy = 1;
		c.gridwidth = 2;
		pnlHeader.add(txtDangerType, c);

		pnlHeader.setBorder(BorderFactory.createLineBorder(Color.black, 1));

	}

	/**
	 * 
	 */
	private void initDescriptionPanel() {
		GridBagLayout gbl = new GridBagLayout();
		gbl.columnWidths = new int[] { 80, 180, 80, 180 };
		gbl.rowHeights = new int[] { 13, 13, 13, 50 };
		pnlDescription = new JPanel(gbl);
		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(2, 6, 2, 6);

		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		c.gridheight = 1;
		pnlDescription.add(new JLabel("Životní etapa stroje:"), c);

		txtStage = new JTextField();
		txtStage.setEditable(false);
		c.gridx = 1;
		c.gridy = 0;
		pnlDescription.add(txtStage, c);

		c.gridx = 2;
		c.gridy = 0;
		pnlDescription.add(new JLabel("Nebezpečný prostor:"), c);

		txtDangerArea = new JTextField();
		c.gridx = 3;
		c.gridy = 0;
		pnlDescription.add(txtDangerArea, c);

		c.gridx = 0;
		c.gridy = 1;
		pnlDescription.add(new JLabel("Ohrožené osoby:"), c);

		pnlPersons = new JPanel(new BorderLayout());
		txtPersons = new JTextField();
		txtPersons.setEditable(false);
		btnPersonSelection = new JButton("...");
		btnPersonSelection.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DangerEstimationFrame.this.btnPersonSelectionPerformed();
			}
		});
		c.gridx = 1;
		c.gridy = 1;
		pnlPersons.add(txtPersons, BorderLayout.CENTER);
		pnlPersons.add(btnPersonSelection, BorderLayout.EAST);
		pnlDescription.add(pnlPersons, c);

		c.gridx = 2;
		c.gridy = 1;
		pnlDescription.add(new JLabel("Provozní stav stroje:"), c);

		cmbState = new JComboBox();
		cmbState.addItem("normální provoz");
		cmbState.addItem("selhání stroje");
		cmbState.addItem("nepředpokládané chování obsluhy");
		cmbState.addItem("neoprávněný zásah třetí osoby");
		cmbState.addItem("stroj mimo provoz");
		cmbState.setSelectedIndex(0);

		c.gridx = 3;
		c.gridy = 1;
		pnlDescription.add(cmbState, c);

		c.gridx = 0;
		c.gridy = 2;
		pnlDescription
				.add(
						new JLabel(
								"<html><body>Popis nebezpečné situace/události:</body></html>"),
						c);

		txtDangerVariant = new JTextField();
		txtDangerVariant.setEditable(false);
		c.gridx = 1;
		c.gridy = 2;
		c.gridwidth = 3;
		c.gridheight = 1;
		pnlDescription.add(txtDangerVariant, c);

		txaDangerEventDescription = new JTextArea();
		JScrollPane scroll = new JScrollPane(txaDangerEventDescription);
		scroll.setViewportView(txaDangerEventDescription);
		c.gridx = 1;
		c.gridy = 3;
		c.gridwidth = 3;
		c.gridheight = 1;
		pnlDescription.add(scroll, c);

		pnlDescription
				.setBorder(BorderFactory.createLineBorder(Color.black, 1));

	}

	/**
	 * 
	 */
	protected void btnPersonSelectionPerformed() {
		if (personSelectionFrame == null) {
			personSelectionFrame = new PersonSelectionFrame(this);
		}

		personSelectionFrame.setVisible(true);
	}

	/**
	 * 
	 */
	private void initStep3Panel() {
		stpStep3 = new StepPanel(3,
				"Informace pro používání (dle ČSN EN ISO 12100-1:2004)",
				"Zbytkové riziko");
	}

	/**
	 * 
	 */
	private void initStep2Panel() {
		stpStep2 = new StepPanel(
				2,
				"Bezpečnostní ochrana a doplňková ochranná opatření (dle ČSN EN ISO 12100-1:2004)",
				"Snížené riziko po opatření");
	}

	/**
	 * 
	 */
	private void initStep1Panel() {
		stpStep1 = new StepPanel(
				1,
				"Opatření zabudovaná v konstrukci (dle ČSN EN ISO 12100-1:2004)",
				"Snížené riziko po opatření");
	}

	/**
	 * 
	 */
	private void initPocatecniPanel() {
		cpnPocatecniRiziko = new DangerCalculatorPanel("Počáteční riziko");
		cpnPocatecniRiziko.setBorder(BorderFactory.createLineBorder(
				Color.black, 1));
	}

	protected void setPersons(String text) {
		txtPersons.setText(text);
	}

	public ArrayList<DangerEstimationBacking> getDangerData() {
		return dangerData;
	}

	public void setDangerData(ArrayList<DangerEstimationBacking> dangerData) {
		this.dangerData = dangerData;
	}

	public void export(String filePrefix) {
		try {
			BufferedWriter bw = null;
			for (int i = 0; i < dangerData.size(); i++) {
				DangerEstimationBacking deb = dangerData.get(i);
				cmbVariant.setSelectedIndex(i);
				bw = new BufferedWriter(new FileWriter(new File(filePrefix
						+ "-"
						+ deb.getVariantStage().getStage().getDescription()
						+ "-"
						+ deb.getVariantStage().getDangerVariant()
								.getDangerType().getCode() + "-"
						+ txtDangerID.getText() + ".txt")));

				bw.write(txtDangerNumber.getText() + "\n");
				bw.write(txtDangerID.getText() + "\n");
				bw.write(txtDangerGroup.getText() + "\n");
				bw.write(txtDangerType.getText() + "\n");
				bw.write(deb.getVariantStage().getStage().getDescription()
						+ "\n");
				bw.write(txtPersons.getText() + "\n");
				bw.write(txtDangerArea.getText() + "\n");
				bw.write(cmbState.getSelectedItem() + "\n");
				bw.write(deb.getVariantStage().getDangerVariant()
						.getDescription()
						+ "\n");
				bw.write(txaDangerEventDescription.getText() + "\n");
				bw.write(cpnPocatecniRiziko.getCurrentS() + "\n");
				bw.write(cpnPocatecniRiziko.getCurrentA() + "\n");
				bw.write(cpnPocatecniRiziko.getCurrentE() + "\n");
				bw.write(cpnPocatecniRiziko.getCurrentW() + "\n");
				bw.write(cpnPocatecniRiziko.getCurrentDangerLevel() + "\n");

				bw.write(stpStep1.getCounterActDescription() + "\n");
				bw.write(stpStep1.getCurrentS() + "\n");
				bw.write(stpStep1.getCurrentA() + "\n");
				bw.write(stpStep1.getCurrentE() + "\n");
				bw.write(stpStep1.getCurrentW() + "\n");
				bw.write(stpStep1.getCurrentDangerLevel() + "\n");

				bw.write(stpStep2.getCounterActDescription() + "\n");
				bw.write(stpStep2.getCurrentS() + "\n");
				bw.write(stpStep2.getCurrentA() + "\n");
				bw.write(stpStep2.getCurrentE() + "\n");
				bw.write(stpStep2.getCurrentW() + "\n");
				bw.write(stpStep2.getCurrentDangerLevel() + "\n");

				bw.write(stpStep3.getCounterActDescription() + "\n");
				bw.write(stpStep3.getCurrentS() + "\n");
				bw.write(stpStep3.getCurrentA() + "\n");
				bw.write(stpStep3.getCurrentE() + "\n");
				bw.write(stpStep3.getCurrentW() + "\n");
				bw.write(stpStep3.getCurrentDangerLevel() + "\n");

				bw.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
