package siprp.higiene.gestao.equipamentos;

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

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
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.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import leaf.ui.LeafButton;
import leaf.ui.LeafDialog;
import leaf.ui.LeafIconButton;
import leaf.ui.LeafUIConstants;
import leaf.ui.TreeTools;
import siprp.database.cayenne.objects.HsEquipamento;
import siprp.logic.HigieneSegurancaLogic;

public class GerirEquipamentosPanel extends JPanel implements CaretListener, LeafUIConstants
{
	
	private static final long serialVersionUID = 1L;

	private LeafIconButton buttonSaveRequesito = LeafIconButton.createButton( ICON_NAME_SAVE );

	private LeafIconButton buttonRevertRequesito = LeafIconButton.createButton( ICON_NAME_REVERT );

	private final JPanel panelButtons = new JPanel();

	private final JPanel panelTree = new JPanel();
	
	private final JPanel panelData = new JPanel();
	
	private final JTextField textTipo = new JTextField(20);
	
	private final JTextField textMarca = new JTextField(20);
	
	private final JTextField textModelo = new JTextField(20);

	private final LeafButton buttonCriar = LeafIconButton.createDefaultNewButton();

	private final LeafButton buttonRemover = LeafIconButton.createDefaultRemoveButton();

	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 );

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

	private void setupListeners()
	{
		buttonCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criar();
			}
		} );
		buttonRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				remover();
			}
		} );
		buttonSaveRequesito.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				save();
			}
		} );
		buttonRevertRequesito.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				revert();
			}
		} );
		tree.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				TreePath path = e.getNewLeadSelectionPath();
				if( path != null )
				{
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
					Object obj = node.getUserObject();
					if( obj instanceof HsEquipamento )
					{
						textTipo.setText( ((HsEquipamento)obj).getTipo() );
						textMarca.setText( ((HsEquipamento)obj).getMarca() );
						textModelo.setText( ((HsEquipamento)obj).getModelo());
					}
				}
				else
				{
					textTipo.setText( "" );
					textMarca.setText( "" );
					textModelo.setText( "" );
				}
				setEnabled();
			}
		} );
		textTipo.addCaretListener( this );
		textMarca.addCaretListener( this );
		textModelo.addCaretListener( this );
	}

	private void criar()
	{
		try
		{
			String tipo = JOptionPane.showInputDialog( this, "Tipo", "Criar novo equipamento", JOptionPane.QUESTION_MESSAGE );
			if( tipo != null )
			{
				HsEquipamento equipamento = new HsEquipamento();
				equipamento.setTipo( tipo );
				equipamento.save();
				refresh();
			}
		}
		catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}

	private void remover()
	{
		try
		{
			HsEquipamento equipamento = getSelected();
			if( equipamento != null && confirmDelete() )
			{
				equipamento.setDeletedDate( new Date() );
				equipamento.save();
				refresh();
			}
		}
		catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}
	
	private boolean confirmDelete()
	{
		return JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(
				null, "Tem a certeza que deseja remover o equipamento seleccionado?",
				"Confirmar remo" + ccedil + atilde + "o",
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null );
	}
	
	private void save()
	{
		try
		{
			HsEquipamento equipamento = getSelected();
			if( equipamento != null )
			{
				equipamento.setTipo( textTipo.getText() );
				equipamento.setMarca( textMarca.getText() );
				equipamento.setModelo( textModelo.getText() );
				equipamento.save();
				refresh();
			}
		}
		catch( Exception e )
		{
			LeafDialog.error( e );
		}
	}
	
	private void revert()
	{
		HsEquipamento equipamento = getSelected();
		if( equipamento != null )
		{
			textTipo.setText( equipamento.getTipo() );
			textMarca.setText( equipamento.getMarca() );
			textModelo.setText( equipamento.getModelo() );
		}
	}

	private HsEquipamento getSelected()
	{
		Object object = getSelectedObject();
		return object == null ? null : ((object instanceof HsEquipamento) ? (HsEquipamento) 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()
	{
		panelTree.setPreferredSize( new Dimension( 400, 400 ) );
		tree.setRootVisible( false );
		tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
	}

	private void setEnabled()
	{
		HsEquipamento equipamento = getSelected();
		buttonRemover.setEnabled( equipamento != null );
		textTipo.setEnabled( equipamento != null );
		textMarca.setEnabled( equipamento != null );
		textModelo.setEnabled( equipamento != null );
		buttonSaveRequesito.setEnabled( false );
		buttonRevertRequesito.setEnabled( false );
		if( equipamento != null )
		{
			boolean changed = !textTipo.getText().equals( equipamento.getTipo() );
			changed |= !textMarca.getText().equals( equipamento.getMarca()  == null ? "" : equipamento.getMarca() );
			changed |= !textModelo.getText().equals( equipamento.getModelo() == null ? "" : equipamento.getModelo() );
			buttonSaveRequesito.setEnabled( changed );
			buttonRevertRequesito.setEnabled( changed );
		}
	}

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

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

	private void placeComponents()
	{
		panelButtons.add( buttonCriar, new TableLayoutConstraints( 0, 0 ) );
		panelButtons.add( buttonRemover, new TableLayoutConstraints( 1, 0 ) );

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

		panelData.add( buttonSaveRequesito, new TableLayoutConstraints( 2, 0 ) );
		panelData.add( buttonRevertRequesito, new TableLayoutConstraints( 3, 0 ) );
		panelData.add( new JLabel("Tipo"), new TableLayoutConstraints( 0, 1 ) );
		panelData.add( textTipo, new TableLayoutConstraints( 1, 1, 3, 1 ) );
		panelData.add( new JLabel("Marca"), new TableLayoutConstraints( 0, 2 ) );
		panelData.add( textMarca, new TableLayoutConstraints( 1, 2, 3, 2 ) );
		panelData.add( new JLabel("Modelo"), new TableLayoutConstraints( 0, 3 ) );
		panelData.add( textModelo, new TableLayoutConstraints( 1, 3, 3, 3 ) );
		
		add( panelButtons, new TableLayoutConstraints( 0, 0 ) );
		add( panelTree, new TableLayoutConstraints( 0, 1, 1, 1 ) );
		add( panelData, new TableLayoutConstraints( 2, 1 ) );
	}

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

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

}
