package siprp.higiene.gestao.postos;

import static com.evolute.utils.strings.UnicodeLatin1Map.aacute;
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.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.TreeNode;
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.Empresas;
import siprp.database.cayenne.objects.HsArea;
import siprp.database.cayenne.objects.HsPosto;
import siprp.logic.node.AreaNode;
import siprp.logic.node.PostoNode;

public class GerirAreasPanel extends JPanel
{

	private static final long serialVersionUID = 1L;

	private final JPanel panelButtons = new JPanel();

	private final JPanel panelTree = new JPanel();

	public final LeafButton buttonAreaCriar = new LeafButton( "Criar" );

	public final LeafButton buttonAreaEditar = new LeafButton( "Editar" );

	public final LeafButton buttonAreaRemover = new LeafButton( "Remover" );

	public final LeafButton buttonPostoCriar = new LeafButton( "Criar" );

	public final LeafButton buttonPostoEditar = new LeafButton( "Editar" );

	public final LeafButton buttonPostoRemover = new LeafButton( "Remover" );

	private final DefaultMutableTreeNode root = new DefaultMutableTreeNode();

	private final DefaultTreeModel model = new DefaultTreeModel( root );

	public final JTree tree = new JTree( model );

	private final JScrollPane scroll = new JScrollPane( tree );

	private Empresas empresa = null;

	public GerirAreasPanel()
	{
		startupComponents();
		startupLayout();
		placeComponents();
		setupListeners();
	}

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

	private void startupLayout()
	{
		TableLayout layout = new TableLayout( new double[] {
			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, TableLayout.FILL
		}, new double[] {
			TableLayout.MINIMUM
		} );
		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 );
	}

	private void placeComponents()
	{
		JPanel panel = new JPanel();
		panel.setBorder( BorderFactory.createTitledBorder( "Area" ) );
		panel.setLayout( new GridLayout( 3, 1 ) );
		panel.add( buttonAreaCriar );
		panel.add( buttonAreaEditar );
		panel.add( buttonAreaRemover );
		panelButtons.add( panel, new TableLayoutConstraints( 0, 0 ) );

		panel = new JPanel();
		panel.setBorder( BorderFactory.createTitledBorder( "Posto" ) );
		panel.setLayout( new GridLayout( 3, 1 ) );
		panel.add( buttonPostoCriar );
		panel.add( buttonPostoEditar );
		panel.add( buttonPostoRemover );
		panelButtons.add( panel, new TableLayoutConstraints( 1, 0 ) );

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

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

	private void setupListeners()
	{
		tree.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				setEnabled();
			}
		} );
		buttonAreaCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarArea();
			}
		} );
		buttonAreaEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarArea();
			}
		} );
		buttonAreaRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerArea();
			}
		} );
		buttonPostoCriar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				criarPosto();
			}
		} );
		buttonPostoEditar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				editarPosto();
			}
		} );
		buttonPostoRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				removerPosto();
			}
		} );
	}

	private void criarArea()
	{
		try
		{
			if( empresa != null )
			{
				String areaString = JOptionPane.showInputDialog( this, "Descri" + ccedil + atilde + "o", "Criar nova " + aacute + "rea", JOptionPane.QUESTION_MESSAGE );
				if( areaString != null )
				{
					HsArea area = new HsArea();
					area.setToEmpresas( empresa );
					area.setDescription( areaString );
					area.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void editarArea()
	{
		try
		{
			HsArea area = getSelectedArea();
			if( area != null )
			{
				String areaString = JOptionPane.showInputDialog( this, "Descri" + ccedil + atilde + "o",  area.getDescription() );
				if( areaString != null )
				{
					area.setDescription( areaString );
					area.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerArea()
	{
		try
		{
			HsArea area = getSelectedArea();
			if( area != null )
			{
				area.delete();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void criarPosto()
	{
		try
		{
			HsArea area = getSelectedArea();
			if( area != null )
			{
				String postoString = JOptionPane.showInputDialog( this, "Descri" + ccedil + atilde + "o", "Criar novo posto de trabalho", JOptionPane.QUESTION_MESSAGE );
				if( postoString != null )
				{
					HsPosto posto = new HsPosto();
					posto.setToHsArea( area );
					posto.setDescription( postoString );
					posto.save();
					refresh();
				}
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}
	
	private void editarPosto()
	{
		try
		{
			HsPosto posto = getSelectedPosto();
			if( posto != null )
			{
				String postoString = JOptionPane.showInputDialog( this, "Descri" + ccedil + atilde + "o", posto.getDescription() );
				if( postoString != null )
				{
					posto.setDescription( postoString );
					posto.save();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void removerPosto()
	{
		try
		{
			HsPosto posto = getSelectedPosto();
			if( posto != null )
			{
				posto.setDeletedDate( new Date() );
				posto.save();
				refresh();
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private HsArea getSelectedArea()
	{
		HsArea result = null;
		TreePath path = tree.getSelectionPath();
		if( path != null )
		{
			Object leaf = path.getLastPathComponent();
			if( leaf != null )
			{
				if( leaf instanceof AreaNode )
				{
					result = (HsArea) ((AreaNode) leaf).getUserObject();
				}
				else if( leaf instanceof PostoNode )
				{
					result = (HsArea) ((HsPosto) ((PostoNode) leaf).getUserObject()).getToHsArea();
				}
			}
		}
		return result;
	}

	private HsPosto getSelectedPosto()
	{
		HsPosto result = null;
		TreePath path = tree.getSelectionPath();
		if( path != null )
		{
			Object leaf = path.getLastPathComponent();
			if( leaf != null && (leaf instanceof PostoNode) )
			{
				result = (HsPosto) ((PostoNode) leaf).getUserObject();
			}
		}
		return result;
	}

	private void setEnabled()
	{
		TreePath path = tree.getSelectionPath();
		TreeNode node = path == null ? null : (TreeNode) path.getLastPathComponent();
		boolean areaSelected = node != null && (node instanceof AreaNode);
		boolean postoSelected = node != null && (node instanceof PostoNode);
		buttonPostoCriar.setEnabled( areaSelected || postoSelected );
		buttonPostoEditar.setEnabled( postoSelected );
		buttonPostoRemover.setEnabled( postoSelected );
		buttonAreaRemover.setEnabled( areaSelected );
		buttonAreaCriar.setEnabled( empresa != null );
		buttonAreaEditar.setEnabled( areaSelected );
	}

	public void refresh()
	{
		root.removeAllChildren();
		if( empresa != null )
		{
			for( HsArea area : empresa.getHsAreaArray() )
			{
				addArea( area );
			}
		}
		setEnabled();
		TreeTools.refreshTree( tree, root );
	}

	private void addArea( HsArea area )
	{
		if( area != null )
		{
			AreaNode areaNode = new AreaNode( area );
			for( HsPosto posto : area.getHsPostoArray() )
			{
				addPosto( posto, areaNode );
			}
			root.add( areaNode );
		}
	}

	private void addPosto( HsPosto posto, AreaNode areaNode )
	{
		if( posto != null && posto.getDeletedDate() == null )
		{
			PostoNode postoNode = new PostoNode( posto );
			areaNode.add( postoNode );
		}
	}

	public void setEmpresa( Empresas empresa )
	{
		this.empresa = empresa;
		refresh();
	}

}
