package siprp.higiene.relatorio;

import static com.evolute.utils.strings.UnicodeLatin1Map.aacute;
import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import leaf.ui.LeafButton;
import leaf.ui.LeafError;
import leaf.ui.LeafIconButton;
import siprp.database.cayenne.objects.HsRelatorioPostoRisco;
import siprp.database.cayenne.objects.HsRelatorioRiscoValorQualitativo;
import siprp.logic.HigieneSegurancaLogic;

public class GerirValoresRiscoPanel extends JPanel implements ActionListener, CaretListener
{

	private static final long serialVersionUID = 1L;

	private static final String ICON_NAME_SAVE = "siprp/higiene/gestao/riscos/save.png";

	private static final String ICON_NAME_REVERT = "siprp/higiene/gestao/riscos/revert.png";

	public static final String VALUE_CHANGED = "VALUE_CHANGED";

	private final JRadioButton radioValorQuantitativo = new JRadioButton();

	private final JRadioButton radioValorQualitativo = new JRadioButton();

	private final JFormattedTextField textSeveridade = new JFormattedTextField();

	private final JFormattedTextField textProbabilidade = new JFormattedTextField();

	private final JComboBox comboValorQualitativo = new JComboBox();

	private final LeafButton buttonSave = LeafIconButton.createButton( ICON_NAME_SAVE );

	private final LeafButton buttonRevert = LeafIconButton.createButton( ICON_NAME_REVERT );

	private final ButtonGroup bg = new ButtonGroup();

	private HsRelatorioPostoRisco valoresRisco = null;

	public GerirValoresRiscoPanel()
	{
		startupListeners();
		startupComponents();
		startupLayout();
		placeComponents();
		loadValoresQualitativos();
	}

	private void startupListeners()
	{
		radioValorQualitativo.addActionListener( this );
		radioValorQuantitativo.addActionListener( this );
		comboValorQualitativo.addActionListener( this );
		textProbabilidade.addCaretListener( this );
		textSeveridade.addCaretListener( this );
		buttonSave.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				save();
			}
		} );
		buttonRevert.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				refresh();
			}
		} );

	}

	private void startupComponents()
	{
		textSeveridade.setPreferredSize( new Dimension( 30, 0 ) );
		textProbabilidade.setPreferredSize( new Dimension( 30, 0 ) );
		buttonSave.setEnabled( false );
		buttonRevert.setEnabled( false );
		bg.add( radioValorQualitativo );
		bg.add( radioValorQuantitativo );
	}

	private void startupLayout()
	{
		TableLayout layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.MINIMUM, TableLayout.PREFERRED, TableLayout.FILL, TableLayout.MINIMUM, TableLayout.PREFERRED, TableLayout.FILL
		}, new double[] {
				TableLayout.MINIMUM, TableLayout.MINIMUM, TableLayout.MINIMUM
		} );
		layout.setVGap( 5 );
		layout.setHGap( 5 );
		setLayout( layout );
	}

	private void placeComponents()
	{
		TableLayout layout = new TableLayout( new double[] {
				TableLayout.FILL, TableLayout.MINIMUM, TableLayout.MINIMUM
		}, new double[] {
			TableLayout.MINIMUM
		} );
		layout.setVGap( 5 );
		layout.setHGap( 5 );
		JPanel panel = new JPanel();
		panel.setLayout( layout );
		panel.add( buttonSave, new TableLayoutConstraints( 1, 0 ) );
		panel.add( buttonRevert, new TableLayoutConstraints( 2, 0 ) );

		add( panel, new TableLayoutConstraints( 1, 0, 6, 0 ) );
		add( radioValorQuantitativo, new TableLayoutConstraints( 0, 1 ) );
		add( new JLabel( "Severidade" ), new TableLayoutConstraints( 1, 1 ) );
		add( textSeveridade, new TableLayoutConstraints( 2, 1 ) );
		add( new JLabel( "Probabilidade" ), new TableLayoutConstraints( 4, 1 ) );
		add( textProbabilidade, new TableLayoutConstraints( 5, 1 ) );
		add( radioValorQualitativo, new TableLayoutConstraints( 0, 2 ) );
		add( comboValorQualitativo, new TableLayoutConstraints( 1, 2, 5, 2 ) );
	}

	private void loadValoresQualitativos()
	{
		comboValorQualitativo.removeAllItems();
		for( HsRelatorioRiscoValorQualitativo valor : HigieneSegurancaLogic.getAllValoresQualitativos() )
		{
			comboValorQualitativo.addItem( valor );
		}
	}

	void refresh()
	{
		if( valoresRisco != null )
		{
			boolean qualitativo = valoresRisco.getToHsRelatorioRiscoValorQualitativo() != null;
			radioValorQuantitativo.setSelected( !qualitativo );
			radioValorQualitativo.setSelected( qualitativo );
			String severidade = (valoresRisco.getSeveridade() == null ? null : valoresRisco.getSeveridade() + "");
			String probabilidade = (valoresRisco.getProbabilidade() == null ? null : valoresRisco.getProbabilidade() + "");
			textSeveridade.setText( severidade );
			textProbabilidade.setText( probabilidade );
			if( valoresRisco.getToHsRelatorioRiscoValorQualitativo() != null )
			{
				comboValorQualitativo.setSelectedItem( valoresRisco.getToHsRelatorioRiscoValorQualitativo() );
			}
		}
		else
		{
			bg.clearSelection();
			textSeveridade.setText( null );
			textProbabilidade.setText( null );
		}
	}

	private void setEnabled()
	{
		if( isEnabled() )
		{
			textProbabilidade.setEnabled( valoresRisco != null && radioValorQuantitativo.isSelected() );
			textSeveridade.setEnabled( valoresRisco != null && radioValorQuantitativo.isSelected() );
			radioValorQualitativo.setEnabled( valoresRisco != null );
			radioValorQuantitativo.setEnabled( valoresRisco != null );
			comboValorQualitativo.setEnabled( valoresRisco != null && radioValorQualitativo.isSelected() );
			if( valoresRisco != null )
			{
				boolean changes = false;
				boolean wasQual = valoresRisco.getToHsRelatorioRiscoValorQualitativo() != null;
				boolean isQual = radioValorQualitativo.isSelected();
				if( !isQual )
				{
					changes = wasQual;
					if( !changes )
					{
						boolean probChanged = false;
						boolean sevChanged = false;
						String prob = textProbabilidade.getText();
						String sev = textSeveridade.getText();
						if( prob == null )
						{
							probChanged = valoresRisco.getProbabilidade() != null;
						}
						else
						{
							probChanged = !prob.equals( valoresRisco.getProbabilidade() == null ? "" : valoresRisco.getProbabilidade() + "" );
						}
						if( sev == null )
						{
							sevChanged = valoresRisco.getSeveridade() != null;
						}
						else
						{
							sevChanged = !sev.equals( valoresRisco.getSeveridade() == null ? "" : valoresRisco.getSeveridade() + "" );
						}
						changes = probChanged || sevChanged;
					}
				}
				else
				{
					changes = !wasQual;
					if( !changes )
					{
						changes = !comboValorQualitativo.getSelectedItem().equals( valoresRisco.getToHsRelatorioRiscoValorQualitativo() );
					}
				}
				buttonSave.setEnabled( changes );
				buttonRevert.setEnabled( changes );
			}
		}
		else
		{
			buttonRevert.setEnabled( false );
			buttonSave.setEnabled( false );
			radioValorQualitativo.setEnabled( false );
			radioValorQuantitativo.setEnabled( false );
			comboValorQualitativo.setEnabled( false );
			textProbabilidade.setEnabled( false );
			textSeveridade.setEnabled( false );
		}
	}

	public void setRelatorioPostoRisco( HsRelatorioPostoRisco rel )
	{
		this.valoresRisco = rel;
		refresh();
		setEnabled();
	}

	private void error( boolean probabilidade )
	{
		JOptionPane.showMessageDialog( this, "Valor inv" + aacute + "lido para " + (probabilidade ? "'Probabilidade'" : "'Severidade'") + ".", "Erro", JOptionPane.ERROR_MESSAGE, null );
	}

	private void save()
	{
		try
		{
			if( valoresRisco != null )
			{
				if( radioValorQualitativo.isSelected() )
				{
					valoresRisco.setToHsRelatorioRiscoValorQualitativo( (HsRelatorioRiscoValorQualitativo) comboValorQualitativo.getSelectedItem() );
				}
				else
				{
					valoresRisco.setToHsRelatorioRiscoValorQualitativo( null );
					Integer probabilidade = null;
					Integer severidade = null;
					boolean ok = true;
					if( textProbabilidade.getText() != null && !textProbabilidade.getText().trim().equals( "" ) )
					{
						try
						{
							probabilidade = new Integer( textProbabilidade.getText() );
						} catch( NumberFormatException e1 )
						{
							ok = false;
						}
						if( !ok || !HigieneSegurancaLogic.isProbabilidadeValida( probabilidade ) )
						{
							error( true );
						}
					}
					if( textSeveridade.getText() != null && !textSeveridade.getText().trim().equals( "" ) )
					{
						if( ok )
						{
							try
							{
								severidade = new Integer( textSeveridade.getText() );
							} catch( NumberFormatException e2 )
							{
								ok = false;
							}
							if( !ok || !HigieneSegurancaLogic.isSeveridadeValida( severidade ) )
							{
								error( false );
							}
						}
					}
					boolean pvalid = HigieneSegurancaLogic.isProbabilidadeValida( probabilidade );
					boolean svalid = HigieneSegurancaLogic.isSeveridadeValida( severidade );

					valoresRisco.setProbabilidade( pvalid && svalid ? probabilidade : null );
					valoresRisco.setSeveridade( pvalid && svalid ? severidade : null );
				}
				valoresRisco.save();
				firePropertyChange( VALUE_CHANGED, null, valoresRisco );
				refresh();
				setEnabled();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	@Override
	public void caretUpdate( CaretEvent e )
	{
		setEnabled();
	}

	@Override
	public void actionPerformed( ActionEvent e )
	{
		setEnabled();
	}

}
