package siprp.higiene.gestao.legislacao;

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

import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;

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.data.Validator;
import leaf.ui.LeafButton;
import leaf.ui.LeafError;
import leaf.ui.LeafIconButton;
import leaf.ui.LeafTextAreaEditor;
import leaf.ui.LeafUIConstants;
import leaf.ui.TreeTools;
import siprp.database.cayenne.objects.HsLegislacao;
import siprp.database.cayenne.objects.HsLegislacaoCategoria;
import siprp.logic.HigieneSegurancaLogic;

public class GerirLegislacaoPanel extends JPanel implements LeafUIConstants
{

	private static final long serialVersionUID = 1L;

	private final JPanel panelGeral = new JPanel();

	private final JPanel panelCategorias = new JPanel();

	private final JPanel panelButtonsGeral = new JPanel();

	private final LeafButton buttonGeralCriar = LeafIconButton.createDefaultNewButton();

	private final LeafButton buttonGeralRemover = LeafIconButton.createDefaultRemoveButton();

	private final JPanel panelButtonsCategoriasCategoria = new JPanel();

	private final LeafButton buttonCategoriaCriar = LeafIconButton.createDefaultNewButton();

	private final LeafButton buttonCategoriaEditar = LeafIconButton.createDefaultEditButton();

	private final LeafButton buttonCategoriaRemover = LeafIconButton.createDefaultRemoveButton();

	private final JPanel panelButtonsCategoriasLegislacao = new JPanel();

	private final LeafButton buttonCategoriasLegislacaoCriar = LeafIconButton.createDefaultNewButton();

	private final LeafButton buttonCategoriasLegislacaoRemover = LeafIconButton.createDefaultRemoveButton();

	private final DefaultMutableTreeNode rootGeral = new DefaultMutableTreeNode();

	private final DefaultTreeModel modelGeral = new DefaultTreeModel( rootGeral );

	private final JTree treeGeral = new JTree( modelGeral );

	private final JScrollPane scrollGeral = new JScrollPane( treeGeral );

	private final DefaultMutableTreeNode rootCategorias = new DefaultMutableTreeNode();

	private final DefaultTreeModel modelCategorias = new DefaultTreeModel( rootCategorias );

	private final JTree treeCategorias = new JTree( modelCategorias );

	private final JScrollPane scrollCategorias = new JScrollPane( treeCategorias );

	private HsLegislacao selectedLegislacaoGeral = null;

	private HsLegislacao selectedLegislacaoEspecifica = null;

	private HsLegislacaoCategoria selectedCategoria = null;

	private final LeafTextAreaEditor panelData = new LeafTextAreaEditor( new Validator<String>()
	{
		@Override
		public boolean isValid( String object )
		{
			return true;
		}
	} );

	public GerirLegislacaoPanel()
	{
		startupComponents();
		startupLayout();
		placeComponents();
		setupListeners();
		reload();
		setEnable();
	}

	private void startupComponents()
	{
		panelGeral.setBorder( BorderFactory.createTitledBorder( "Legisla" + ccedil + atilde + "o de aplica" + ccedil + atilde + "o geral" ) );
		
		panelCategorias.setBorder( BorderFactory.createTitledBorder( "Legisla" + ccedil + atilde + "o espec" + iacute + "fica" ) );
		panelButtonsCategoriasCategoria.setBorder( BorderFactory.createTitledBorder( "Categoria" ) );
		panelButtonsCategoriasLegislacao.setBorder( BorderFactory.createTitledBorder( "Legisla" + ccedil + atilde + "o" ) );
		
		treeCategorias.setRootVisible( false );
		treeGeral.setRootVisible( false );
		treeCategorias.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
		treeGeral.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
	}

	private void startupLayout()
	{
		LayoutManager layout = new TableLayout( new double[] {
				TableLayout.FILL, TableLayout.FILL
		}, new double[] {
				TableLayout.FILL, TableLayout.FILL
		} );
		this.setLayout( layout );

		layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.FILL
		}, new double[] {
				TableLayout.MINIMUM, TableLayout.FILL
		} );
		panelGeral.setLayout( layout );

		layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.MINIMUM, TableLayout.FILL
		}, new double[] {
				TableLayout.MINIMUM, TableLayout.FILL
		} );
		panelCategorias.setLayout( layout );

		layout = new GridLayout( 1, 2, 5, 5 );
		panelButtonsGeral.setLayout( layout );

		layout = new GridLayout( 1, 4, 5, 5 );
		panelButtonsCategoriasCategoria.setLayout( layout );

		layout = new GridLayout( 1, 4, 5, 5 );
		panelButtonsCategoriasLegislacao.setLayout( layout );
	}

	private void placeComponents()
	{
		panelButtonsGeral.add( buttonGeralCriar );
		panelButtonsGeral.add( buttonGeralRemover );

		panelButtonsCategoriasCategoria.add( buttonCategoriaCriar );
		panelButtonsCategoriasCategoria.add( buttonCategoriaEditar );
		panelButtonsCategoriasCategoria.add( buttonCategoriaRemover );
		panelButtonsCategoriasCategoria.add( new JPanel() );

		panelButtonsCategoriasLegislacao.add( buttonCategoriasLegislacaoCriar );
		panelButtonsCategoriasLegislacao.add( buttonCategoriasLegislacaoRemover );
		panelButtonsCategoriasLegislacao.add( new JPanel() );
		panelButtonsCategoriasLegislacao.add( new JPanel() );

		panelGeral.add( panelButtonsGeral, new TableLayoutConstraints( 0, 0 ) );
		panelGeral.add( scrollGeral, new TableLayoutConstraints( 0, 1, 1, 1 ) );

		panelCategorias.add( panelButtonsCategoriasCategoria, new TableLayoutConstraints( 0, 0 ) );
		panelCategorias.add( panelButtonsCategoriasLegislacao, new TableLayoutConstraints( 1, 0 ) );
		panelCategorias.add( scrollCategorias, new TableLayoutConstraints( 0, 1, 2, 1 ) );

		this.add( panelGeral, new TableLayoutConstraints( 0, 0 ) );
		this.add( panelCategorias, new TableLayoutConstraints( 0, 1 ) );
		this.add( panelData, new TableLayoutConstraints( 1, 0, 1, 1 ) );
	}

	private void setupListeners()
	{
		treeCategorias.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				TreePath selectionPath = e.getNewLeadSelectionPath();
				if( selectionPath != null )
				{
					Object last = selectionPath.getLastPathComponent();
					if( last instanceof DefaultMutableTreeNode )
					{
						Object userObject = ((DefaultMutableTreeNode) last).getUserObject();
						if( userObject instanceof HsLegislacao )
						{
							selectedLegislacaoEspecifica = (HsLegislacao) userObject;
						}
						else if( userObject instanceof HsLegislacaoCategoria )
						{
							selectedCategoria = (HsLegislacaoCategoria) userObject;
						}
					}
					treeGeral.clearSelection();
					selectedLegislacaoGeral = null;
				}
				else
				{
					selectedLegislacaoEspecifica = null;
					selectedCategoria = null;
				}
				refreshData();
				setEnable();
			}
		} );
		treeGeral.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				TreePath selectionPath = e.getNewLeadSelectionPath();
				if( selectionPath != null )
				{
					Object last = selectionPath.getLastPathComponent();
					if( last instanceof DefaultMutableTreeNode )
					{
						Object userObject = ((DefaultMutableTreeNode) last).getUserObject();
						if( userObject instanceof HsLegislacao )
						{
							selectedLegislacaoGeral = (HsLegislacao) userObject;
						}
					}
					treeCategorias.clearSelection();
					selectedLegislacaoEspecifica = null;
					selectedCategoria = null;
				}
				else
				{
					selectedLegislacaoGeral = null;
				}
				refreshData();
				setEnable();
			}
		} );
		panelData.addPropertyChangeListener( LeafTextAreaEditor.ACTION_SAVE, new PropertyChangeListener()
		{
			@Override
			public void propertyChange( PropertyChangeEvent evt )
			{
				try
				{
					String newValue = (String) evt.getNewValue();
					if( selectedLegislacaoEspecifica != null )
					{
						selectedLegislacaoEspecifica.setDescription( newValue );
						selectedLegislacaoEspecifica.save();
					}
					else if( selectedLegislacaoGeral != null )
					{
						selectedLegislacaoGeral.setDescription( newValue );
						selectedLegislacaoGeral.save();
					}
					reload();
				} catch( Exception e )
				{
					LeafError.error( e );
				}
			}
		} );
		buttonCategoriaCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarCategoria();
			}
		} );
		buttonCategoriaEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarCategoria();
			}
		} );
		buttonCategoriaRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerCategoria();
			}
		} );
		buttonCategoriasLegislacaoCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarCategoriaLegislacao();
			}
		} );
		buttonCategoriasLegislacaoRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerCategoriaLegislacao();
			}
		} );
		buttonGeralCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarGeral();
			}
		} );
		buttonGeralRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerGeral();
			}
		} );
	}

	private void criarCategoria()
	{
		try
		{
			String categoriaString = JOptionPane.showInputDialog( this, "Nova categoria", "" );
			if( categoriaString != null )
			{
				HsLegislacaoCategoria novaCategoria = new HsLegislacaoCategoria();
				novaCategoria.setDescription( categoriaString );
				novaCategoria.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void editarCategoria()
	{
		try
		{
			if( selectedCategoria != null )
			{
				String categoriaString = JOptionPane.showInputDialog( this, "Nova categoria", selectedCategoria.getDescription() );
				if( categoriaString != null )
				{
					selectedCategoria.setDescription( categoriaString );
					selectedCategoria.save();
					reload();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerCategoria()
	{
		try
		{
			if( selectedCategoria != null )
			{
				selectedCategoria.setDeletedDate( new Date() );
				selectedCategoria.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void criarCategoriaLegislacao()
	{
		try
		{
			if( selectedCategoria != null )
			{
				HsLegislacao novaLegislacao = new HsLegislacao();
				novaLegislacao.setDescription( "" );
				novaLegislacao.setToHsLegislacaoCategoria( selectedCategoria );
				novaLegislacao.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerCategoriaLegislacao()
	{
		try
		{
			if( selectedLegislacaoEspecifica != null )
			{
				selectedLegislacaoEspecifica.setDeletedDate( new Date() );
				selectedLegislacaoEspecifica.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerGeral()
	{
		try
		{
			if( selectedLegislacaoGeral != null )
			{
				selectedLegislacaoGeral.setDeletedDate( new Date() );
				selectedLegislacaoGeral.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void criarGeral()
	{
		try
		{
			HsLegislacao legislacao = new HsLegislacao();
			legislacao.setDescription( "" );
			legislacao.save();
			reload();
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void reload()
	{
		rootGeral.removeAllChildren();
		rootCategorias.removeAllChildren();
		TreeTools.merge( rootGeral, HigieneSegurancaLogic.getLegislacaoGeral() );
		TreeTools.merge( rootCategorias, HigieneSegurancaLogic.getLegislacaoEspecifica() );
		TreeTools.refreshTree( treeGeral, rootGeral );
		TreeTools.refreshTree( treeCategorias, rootCategorias );
	}

	private void refreshData()
	{
		buttonCategoriaEditar.setEnabled( false );
		buttonCategoriaRemover.setEnabled( false );
		buttonCategoriasLegislacaoCriar.setEnabled( false );
		buttonCategoriasLegislacaoRemover.setEnabled( false );
		buttonGeralRemover.setEnabled( false );
		panelData.setEnabled( false );
		if( selectedLegislacaoEspecifica != null )
		{
			panelData.setValue( selectedLegislacaoEspecifica.getDescription() );
			panelData.setEnabled( true );
		}
		else if( selectedLegislacaoGeral != null )
		{
			panelData.setValue( selectedLegislacaoGeral.getDescription() );
			panelData.setEnabled( true );
		}
		else
		{
			panelData.setValue( null );
		}
		if( selectedCategoria != null )
		{
			buttonCategoriaEditar.setEnabled( true );
			buttonCategoriaRemover.setEnabled( true );
		}
	}

	private void setEnable()
	{
		buttonCategoriaEditar.setEnabled( selectedCategoria != null );
		buttonCategoriaRemover.setEnabled( selectedCategoria != null );
		buttonCategoriasLegislacaoCriar.setEnabled( selectedCategoria != null );
		buttonCategoriasLegislacaoRemover.setEnabled( selectedLegislacaoEspecifica != null );
		buttonGeralRemover.setEnabled( selectedLegislacaoGeral != null );
	}

}
