package siprp.higiene.gestao.riscos;

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

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import leaf.ui.LeafButton;
import leaf.ui.LeafError;
import leaf.ui.TreeTools;
import siprp.database.cayenne.objects.HsMedida;
import siprp.database.cayenne.objects.HsRisco;
import siprp.database.cayenne.objects.HsRiscoMedida;
import siprp.database.cayenne.objects.HsRiscoTema;
import siprp.logic.HigieneSegurancaLogic;

public class GerirRiscosPanel extends JPanel
{

	private static final long serialVersionUID = 1L;

	private static final String PANEL_TEMA = "PANEL_TEMA";

	private static final String PANEL_RISCO = "PANEL_RISCO";

	private static final String PANEL_MEDIDA = "PANEL_MEDIDA";

	private final JPanel panelButtons = new JPanel();

	private final JPanel panelTree = new JPanel();

	private final JPanel panelData = new JPanel();

	private final JPanel panelDataTema = new JPanel();

	private final JPanel panelDataRisco = new JPanel();

	private final GerirMedidaPanel panelDataMedida = new GerirMedidaPanel();

	private final LeafButton buttonTemaCriar = new LeafButton( "Criar" );

	private final LeafButton buttonTemaEditar = new LeafButton( "Editar" );

	private final LeafButton buttonTemaRemover = new LeafButton( "Remover" );

	private final LeafButton buttonRiscoCriar = new LeafButton( "Criar" );

	private final LeafButton buttonRiscoEditar = new LeafButton( "Editar" );

	private final LeafButton buttonRiscoRemover = new LeafButton( "Remover" );

	private final LeafButton buttonMedidaCriar = new LeafButton( "Criar" );

	private final LeafButton buttonMedidaRemover = new LeafButton( "Remover" );

	private final DefaultMutableTreeNode root = new DefaultMutableTreeNode();

	private final DefaultTreeModel model = new DefaultTreeModel( root );

	private final JTree tree = new JTree( model );

	private final JScrollPane scroll = new JScrollPane( tree );

	private final CardLayout cardLayout = new CardLayout();

	public GerirRiscosPanel()
	{
		startupComponents();
		startupLayout();
		placeComponents();
		setupListeners();
		refresh();
	}

	private void setupListeners()
	{
		buttonTemaCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarTema();
			}
		} );
		buttonTemaEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarTema();
			}
		} );
		buttonTemaRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerTema();
			}
		} );
		buttonRiscoCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarRisco();
			}
		} );
		buttonRiscoEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarRisco();
			}
		} );
		buttonRiscoRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerRisco();
			}
		} );
		buttonMedidaCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarMedida();
			}
		} );
		buttonMedidaRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerMedida();
			}
		} );
		tree.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				setEnabled();
				selectCard();
			}
		} );
		panelDataMedida.addPropertyChangeListener( GerirMedidaPanel.MEDIDA_CHANGED, new PropertyChangeListener()
		{
			@Override
			public void propertyChange( PropertyChangeEvent evt )
			{
				if( evt.getNewValue() != null )
				{
					refresh();
				}
			}
		} );
	}

	private void criarTema()
	{
		try
		{
			String temaString = JOptionPane.showInputDialog( this, "Criar tema", "Descri" + ccedil + atilde + "o", JOptionPane.QUESTION_MESSAGE );
			if( temaString != null )
			{
				HsRiscoTema tema = new HsRiscoTema();
				tema.setDescription( temaString );
				tema.save();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void editarTema()
	{
		try
		{
			HsRiscoTema tema = getSelectedTema();
			if( tema != null )
			{
				String temaString = JOptionPane.showInputDialog( this, "Editar tema", tema.getDescription() );
				if( temaString != null )
				{
					tema.setDescription( temaString );
					tema.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerTema()
	{
		try
		{
			HsRiscoTema tema = getSelectedTema();
			if( tema != null )
			{
				tema.delete();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void criarRisco()
	{
		try
		{
			HsRiscoTema tema = getSelectedTema();
			if( tema == null )
			{
				HsRisco risco = getSelectedRisco();
				if( risco != null )
				{
					tema = risco.getToHsRiscoTema();
				}
				else
				{
					HsRiscoMedida medida = getSelectedMedida();
					if( medida != null )
					{
						tema = medida.getToHsRisco().getToHsRiscoTema();
					}
				}
			}
			if( tema != null )
			{
				String riscoString = JOptionPane.showInputDialog( this, "Criar risco", "Descri" + ccedil + atilde + "o", JOptionPane.QUESTION_MESSAGE );
				if( riscoString != null )
				{
					HsRisco risco = new HsRisco();
					risco.setDescription( riscoString );
					risco.setToHsRiscoTema( tema );
					tema.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void editarRisco()
	{
		try
		{
			HsRisco risco = getSelectedRisco();
			if( risco != null )
			{
				String riscoString = JOptionPane.showInputDialog( this, "Editar risco", risco.getDescription() );
				if( riscoString != null )
				{
					risco.setDescription( riscoString );
					risco.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerRisco()
	{
		try
		{
			HsRisco risco = getSelectedRisco();
			if( risco != null && removerRiscoOK(risco) )
			{
				risco.delete();
				refresh();
			}
		}
		catch( Exception e )
		{
			LeafError.error( e );
		}
	}
	
	private boolean removerRiscoOK( HsRisco risco )
	{
		boolean result = true;
		if( risco.getHsRiscoEmpresaArray().size() > 0 )
		{
			if( JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog( this, "Este risco est" + aacute + " associado a uma ou mais empresas, \n tem a certeza que o deseja remover?", "Aviso", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ) )
			{
				result = false;
			}
		}
		return result;
	}

	private void criarMedida()
	{
		try
		{
			HsRisco risco = getSelectedRisco();
			if( risco == null )
			{
				HsRiscoMedida medida = getSelectedMedida();
				if( medida != null )
				{
					risco = medida.getToHsRisco();
				}
			}
			if( risco != null )
			{
				HsMedida medida = new HsMedida();
				medida.setDescription( "" );
				medida.setRequesitosLegais( "" );
				medida.save();
				HsRiscoMedida rel = new HsRiscoMedida();
				rel.setToHsRisco( risco );
				rel.setToHsMedida( medida );
				rel.save();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerMedida()
	{
		try
		{
			HsRiscoMedida medida = getSelectedMedida();
			if( medida != null )
			{
				medida.delete();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private HsRiscoTema getSelectedTema()
	{
		Object object = getSelectedObject();
		return object == null ? null : ((object instanceof HsRiscoTema) ? (HsRiscoTema) object : null);
	}

	private HsRisco getSelectedRisco()
	{
		Object object = getSelectedObject();
		return object == null ? null : ((object instanceof HsRisco) ? (HsRisco) object : null);
	}

	private HsRiscoMedida getSelectedMedida()
	{
		Object object = getSelectedObject();
		return object == null ? null : ((object instanceof HsRiscoMedida) ? (HsRiscoMedida) object : null);
	}

	private Object getSelectedObject()
	{
		DefaultMutableTreeNode node = getSelectedNode();
		return node == null ? null : node.getUserObject();
	}

	private DefaultMutableTreeNode getSelectedNode()
	{
		TreePath path = tree.getSelectionPath();
		return path == null ? null : (DefaultMutableTreeNode) path.getLastPathComponent();
	}

	private void startupComponents()
	{
		panelButtons.setPreferredSize( new Dimension( 150, 0 ) );
		panelTree.setPreferredSize( new Dimension( 400, 0 ) );
		tree.setRootVisible( false );
		tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
	}

	private void setEnabled()
	{
		HsRiscoTema tema = getSelectedTema();
		HsRisco risco = getSelectedRisco();
		HsRiscoMedida medida = getSelectedMedida();
		buttonMedidaCriar.setEnabled( risco != null || medida != null );
		buttonRiscoCriar.setEnabled( tema != null || risco != null || medida != null );

		buttonTemaEditar.setEnabled( tema != null );
		buttonRiscoEditar.setEnabled( risco != null );

		buttonMedidaRemover.setEnabled( medida != null );
		buttonRiscoRemover.setEnabled( risco != null );
		buttonTemaRemover.setEnabled( tema != null );
	}

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

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

		layout = new TableLayout( new double[] {
			TableLayout.FILL
		}, new double[] {
			TableLayout.FILL
		} );
		layout.setHGap( 5 );
		layout.setVGap( 5 );
		panelTree.setLayout( layout );

		layout = new TableLayout( new double[] {
			TableLayout.FILL
		}, new double[] {
			TableLayout.FILL
		} );
		layout.setHGap( 5 );
		layout.setVGap( 5 );
		panelDataTema.setLayout( layout );

		layout = new TableLayout( new double[] {
			TableLayout.FILL
		}, new double[] {
			TableLayout.FILL
		} );
		layout.setHGap( 5 );
		layout.setVGap( 5 );
		panelDataRisco.setLayout( layout );

		panelData.setLayout( cardLayout );
	}

	private void placeComponents()
	{
		JPanel panel = new JPanel();
		panel.setBorder( BorderFactory.createTitledBorder( "Tema" ) );
		panel.setLayout( new GridLayout( 3, 1 ) );
		panel.add( buttonTemaCriar );
		panel.add( buttonTemaEditar );
		panel.add( buttonTemaRemover );
		panelButtons.add( panel, new TableLayoutConstraints( 0, 0 ) );
		panel = new JPanel();
		panel.setBorder( BorderFactory.createTitledBorder( "Risco" ) );
		panel.setLayout( new GridLayout( 3, 1 ) );
		panel.add( buttonRiscoCriar );
		panel.add( buttonRiscoEditar );
		panel.add( buttonRiscoRemover );
		panelButtons.add( panel, new TableLayoutConstraints( 0, 1 ) );
		panel = new JPanel();
		panel.setBorder( BorderFactory.createTitledBorder( "Requisito" ) );
		panel.setLayout( new GridLayout( 2, 1 ) );
		panel.add( buttonMedidaCriar );
		panel.add( buttonMedidaRemover );
		panelButtons.add( panel, new TableLayoutConstraints( 0, 2 ) );

		panelTree.add( scroll, new TableLayoutConstraints( 0, 0 ) );

		panelData.add( panelDataTema, PANEL_TEMA );
		panelData.add( panelDataRisco, PANEL_RISCO );
		panelData.add( panelDataMedida, PANEL_MEDIDA );

		add( panelButtons, new TableLayoutConstraints( 0, 0 ) );
		add( panelTree, new TableLayoutConstraints( 1, 0 ) );
		add( panelData, new TableLayoutConstraints( 2, 0 ) );
	}

	private void selectCard()
	{
		HsRiscoTema tema = getSelectedTema();
		HsRisco risco = getSelectedRisco();
		HsRiscoMedida medida = getSelectedMedida();
		if( tema != null )
		{
			cardLayout.show( panelData, PANEL_TEMA );
		}
		else if( risco != null )
		{
			cardLayout.show( panelData, PANEL_RISCO );
		}
		else if( medida != null )
		{
			cardLayout.show( panelData, PANEL_MEDIDA );
			panelDataMedida.setMedida( medida.getToHsMedida() );
		}
	}

	private void refresh()
	{
		root.removeAllChildren();
		TreeTools.merge( root, HigieneSegurancaLogic.getRiscosTree() );
		TreeTools.refreshTree( tree, root );
		setEnabled();
	}

}
