package siprp.higiene.gestao.normalizacao;

import static com.evolute.utils.strings.UnicodeLatin1Map.atilde;
import static com.evolute.utils.strings.UnicodeLatin1Map.ccedil;
import static com.evolute.utils.strings.UnicodeLatin1Map.oacute;
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.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.AbstractDocument.LeafElement;
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.LeafDialog;
import leaf.ui.LeafIconButton;
import leaf.ui.LeafTextAreaEditor;
import leaf.ui.LeafUIConstants;
import leaf.ui.TreeTools;
import siprp.database.cayenne.objects.HsNormalizacao;
import siprp.logic.HigieneSegurancaLogic;

public class GerirNormalizacaoPanel extends JPanel implements LeafUIConstants, CaretListener
{

	private static final long serialVersionUID = 1L;

	private final JPanel panelPortuguesa = new JPanel();

	private final JPanel panelInternacional = new JPanel();

	private final JPanel panelButtonsPortuguesa = new JPanel();

	private final LeafButton buttonPortuguesaCriar = LeafIconButton.createDefaultNewButton();
	
	private final LeafButton buttonPortuguesaEditar = LeafIconButton.createDefaultEditButton();

	private final LeafButton buttonPortuguesaRemover = LeafIconButton.createDefaultRemoveButton();

	private final JPanel panelButtonsInternacional = new JPanel();

	private final LeafButton buttonInternacionalCriar = LeafIconButton.createDefaultNewButton();
	
	private final LeafButton buttonInternacionalEditar = LeafIconButton.createDefaultEditButton();

	private final LeafButton buttonInternacionalRemover = LeafIconButton.createDefaultRemoveButton();
	
	private final LeafButton buttonSave = LeafIconButton.createButton( ICON_NAME_SAVE );
	
	private final LeafButton buttonRevert = LeafIconButton.createButton( ICON_NAME_REVERT );

	private final DefaultMutableTreeNode rootPortuguesa = new DefaultMutableTreeNode();

	private final DefaultTreeModel modelPortuguesa = new DefaultTreeModel( rootPortuguesa );

	private final JTree treePortuguesa = new JTree( modelPortuguesa );

	private final JScrollPane scrollPortuguesa = new JScrollPane( treePortuguesa );

	private final DefaultMutableTreeNode rootInternacional = new DefaultMutableTreeNode();

	private final DefaultTreeModel modelInternacional = new DefaultTreeModel( rootInternacional );

	private final JTree treeInternacional = new JTree( modelInternacional );

	private final JScrollPane scrollInternacional = new JScrollPane( treeInternacional );

	private HsNormalizacao selectedPortuguesa = null;

	private HsNormalizacao selectedInternacional = null;

	private final JPanel panelData = new JPanel();
	
	private final JTextField textCodigo = new JTextField(10);
	
	private final JTextArea textAreaDescricao = new JTextArea();

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

	private void startupComponents()
	{
		panelPortuguesa.setBorder( BorderFactory.createTitledBorder( "Normaliza" + ccedil + atilde + "o Portuguesa" ) );

		panelInternacional.setBorder( BorderFactory.createTitledBorder( "Normaliza" + ccedil + atilde + "o Internacional" ) );

		treeInternacional.setRootVisible( false );
		treePortuguesa.setRootVisible( false );
		treeInternacional.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
		treePortuguesa.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
		
		textCodigo.setEnabled( false );
		
		buttonSave.setEnabled( false );
		buttonRevert.setEnabled( false );
	}

	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
		} );
		panelPortuguesa.setLayout( layout );
		((TableLayout) layout).setHGap( 5 );
		((TableLayout) layout).setVGap( 5 );
		
		layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.FILL
		}, new double[] {
				TableLayout.MINIMUM, TableLayout.FILL
		} );
		((TableLayout) layout).setHGap( 5 );
		((TableLayout) layout).setVGap( 5 );
		
		panelInternacional.setLayout( layout );

		layout = new GridLayout( 1, 3, 5, 5 );
		panelButtonsPortuguesa.setLayout( layout );

		layout = new GridLayout( 1, 3, 5, 5 );
		panelButtonsInternacional.setLayout( layout );
		
		layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.PREFERRED, TableLayout.FILL, TableLayout.MINIMUM, TableLayout.MINIMUM
		}, new double[] {
				TableLayout.MINIMUM, TableLayout.MINIMUM, TableLayout.FILL
		} );
		((TableLayout) layout).setHGap( 5 );
		((TableLayout) layout).setVGap( 5 );
		panelData.setLayout( layout );
	}

	private void placeComponents()
	{
		panelButtonsPortuguesa.add( buttonPortuguesaCriar );
		panelButtonsPortuguesa.add( buttonPortuguesaEditar );
		panelButtonsPortuguesa.add( buttonPortuguesaRemover );

		panelButtonsInternacional.add( buttonInternacionalCriar );
		panelButtonsInternacional.add( buttonInternacionalEditar );
		panelButtonsInternacional.add( buttonInternacionalRemover );

		panelPortuguesa.add( panelButtonsPortuguesa, new TableLayoutConstraints( 0, 0 ) );
		panelPortuguesa.add( scrollPortuguesa, new TableLayoutConstraints( 0, 1, 1, 1 ) );

		panelInternacional.add( panelButtonsInternacional, new TableLayoutConstraints( 0, 0 ) );
		panelInternacional.add( scrollInternacional, new TableLayoutConstraints( 0, 1, 1, 1 ) );

		panelData.add( buttonSave, new TableLayoutConstraints( 3, 0 ) );
		panelData.add( buttonRevert, new TableLayoutConstraints( 4, 0 ) );
		panelData.add( new JLabel("C" + oacute + "digo"), new TableLayoutConstraints( 0, 1 ) );
		panelData.add( textCodigo, new TableLayoutConstraints( 1, 1 ) );
		panelData.add( textAreaDescricao, new TableLayoutConstraints( 0, 2, 4, 2 ) );
		
		this.add( panelPortuguesa, new TableLayoutConstraints( 0, 0 ) );
		this.add( panelInternacional, new TableLayoutConstraints( 0, 1 ) );
		this.add( panelData, new TableLayoutConstraints( 1, 0, 1, 1 ) );
	}

	private void setupListeners()
	{
		treeInternacional.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 HsNormalizacao )
						{
							selectedInternacional = (HsNormalizacao) userObject;
						}
					}
					treePortuguesa.clearSelection();
					selectedPortuguesa = null;
				}
				else
				{
					selectedInternacional = null;
				}
				refreshData();
				setEnable();
			}
		} );
		treePortuguesa.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 HsNormalizacao )
						{
							selectedPortuguesa = (HsNormalizacao) userObject;
						}
					}
					treeInternacional.clearSelection();
					selectedInternacional = null;
				}
				else
				{
					selectedPortuguesa = null;
				}
				refreshData();
				setEnable();
			}
		} );
		textCodigo.addCaretListener( this );
		textAreaDescricao.addCaretListener( this );
		buttonPortuguesaCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarPortuguesa();
			}
		} );
		buttonPortuguesaEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarPortuguesa();
			}
		} );
		buttonPortuguesaRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerPortuguesa();
			}
		} );
		buttonInternacionalCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarInternacional();
			}
		} );
		buttonInternacionalEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarInternacional();
			}
		} );
		buttonInternacionalRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerInternacional();
			}
		} );
		buttonSave.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				try
				{
					save();
				} catch( Exception e1 )
				{
					LeafDialog.error( e1 );
				}
			}
		} );
		buttonRevert.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				if( selectedInternacional != null )
				{
					textAreaDescricao.setText( selectedInternacional.getDescricao() );
					textAreaDescricao.setEnabled( true );
					textCodigo.setText( selectedInternacional.getCodigo() );
				}
				else if( selectedPortuguesa != null )
				{
					textAreaDescricao.setText( selectedPortuguesa.getDescricao() );
					textAreaDescricao.setEnabled( true );
					textCodigo.setText( selectedPortuguesa.getCodigo() );
				}
				else
				{
					textAreaDescricao.setText( "" );
					textCodigo.setText( "" );
				}
			}
		} );
	}
	
	private void save() throws Exception
	{
		if( selectedInternacional != null )
		{
			selectedInternacional.setCodigo( textCodigo.getText() );
			selectedInternacional.setDescricao( textAreaDescricao.getText() );
			selectedInternacional.save();
		}
		else if( selectedPortuguesa != null )
		{
			selectedPortuguesa.setCodigo( textCodigo.getText() );
			selectedPortuguesa.setDescricao( textAreaDescricao.getText() );
			selectedPortuguesa.save();
		}
		reload();
	}
	
	private String getCodigoForNormalizacao( boolean criar, boolean portuguesa )
	{
		String result = null;
		if( criar )
		{
			result = JOptionPane.showInputDialog( this, "C" + oacute + "digo", "Criar normaliza" + ccedil + atilde + "o" + (portuguesa ? " Portuguesa": " internacional"), JOptionPane.QUESTION_MESSAGE );
		}
		else
		{
			result = JOptionPane.showInputDialog( this, "C" + oacute + "digo", portuguesa ? selectedPortuguesa.getCodigo() : selectedInternacional.getCodigo() );
		}
		return result;
	}
	
	private boolean isValidCodigo( String codigo )
	{
		boolean result = false;
		if( codigo != null )
		{
			result = true;
		}
		return result;
	}

	private void criarPortuguesa()
	{
		try
		{
			String codigo = getCodigoForNormalizacao(true,true);
			if( isValidCodigo(codigo) )
			{
				HsNormalizacao normalizacao = new HsNormalizacao();
				normalizacao.setDescricao( "" );
				normalizacao.setCodigo( codigo );
				normalizacao.setPortuguesa( true );
				normalizacao.save();
				reload();				
			}
		} catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}
	
	private void editarPortuguesa()
	{
		try
		{
			if( selectedPortuguesa != null )
			{
				String codigo = getCodigoForNormalizacao(false, true);
				if( isValidCodigo(codigo) )
				{
					selectedPortuguesa.setCodigo( codigo );
					selectedPortuguesa.save();
					reload();				
				}
			}
		} catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}
	
	private void removerPortuguesa()
	{
		try
		{
			if( selectedPortuguesa != null && LeafDialog.confirmDelete( false, false, "normaliza" + ccedil + atilde + "o" ) )
			{
				selectedPortuguesa.setDeletedDate( new Date() );
				selectedPortuguesa.save();
				reload();
			}
		} catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}

	private void criarInternacional()
	{
		try
		{
			String codigo = getCodigoForNormalizacao(true, false);
			if( isValidCodigo(codigo) )
			{
				HsNormalizacao normalizacao = new HsNormalizacao();
				normalizacao.setDescricao( "" );
				normalizacao.setCodigo( codigo );
				normalizacao.setPortuguesa( false );
				normalizacao.save();
				reload();				
			}
		} catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}
	
	private void editarInternacional()
	{
		try
		{
			if( selectedInternacional != null )
			{
				String codigo = getCodigoForNormalizacao(false, false);
				if( isValidCodigo(codigo) )
				{
					selectedInternacional.setCodigo( codigo );
					selectedInternacional.save();
					reload();				
				}
			}
		} catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}

	private void removerInternacional()
	{
		try
		{
			if( selectedInternacional != null && LeafDialog.confirmDelete( false, false, "normaliza" + ccedil + atilde + "o" ) )
			{
				selectedInternacional.setDeletedDate( new Date() );
				selectedInternacional.save();
				reload();
			}
		}
		catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}

	
	private void reload()
	{
		rootPortuguesa.removeAllChildren();
		rootInternacional.removeAllChildren();
		textCodigo.setText( "" );
		TreeTools.merge( rootPortuguesa, HigieneSegurancaLogic.getNormalizacaoTree( true ) );
		TreeTools.merge( rootInternacional, HigieneSegurancaLogic.getNormalizacaoTree( false ) );
		TreeTools.refreshTree( treePortuguesa, rootPortuguesa, false );
		TreeTools.refreshTree( treeInternacional, rootInternacional, false );
	}

	private void refreshData()
	{
		buttonInternacionalRemover.setEnabled( false );
		buttonPortuguesaRemover.setEnabled( false );
		buttonInternacionalEditar.setEnabled( false );
		buttonPortuguesaEditar.setEnabled( false );
		textAreaDescricao.setEnabled( false );
		buttonSave.setEnabled( false );
		buttonRevert.setEnabled( false );
		if( selectedInternacional != null )
		{
			textAreaDescricao.setText( selectedInternacional.getDescricao() );
			textAreaDescricao.setEnabled( true );
			textCodigo.setText( selectedInternacional.getCodigo() );
			textCodigo.setEnabled( true );
		}
		else if( selectedPortuguesa != null )
		{
			textAreaDescricao.setText( selectedPortuguesa.getDescricao() );
			textAreaDescricao.setEnabled( true );
			textCodigo.setText( selectedPortuguesa.getCodigo() );
			textCodigo.setEnabled( true );
		}
		else
		{
			textAreaDescricao.setText( "" );
			textCodigo.setText( "" );
		}
	}

	private void setEnable()
	{
		buttonPortuguesaEditar.setEnabled( selectedPortuguesa != null );
		buttonPortuguesaRemover.setEnabled( selectedPortuguesa != null );
		buttonInternacionalEditar.setEnabled( selectedInternacional != null );
		buttonInternacionalRemover.setEnabled( selectedInternacional != null );
	}

	@Override
	public void caretUpdate( CaretEvent e )
	{
		buttonSave.setEnabled( true );
		buttonRevert.setEnabled( true );
	}

}
