package siprp.higiene.gestao.riscos;

import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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.TreeInserterDialog;
import leaf.ui.TreeTools;
import siprp.database.cayenne.objects.BaseObject;
import siprp.database.cayenne.objects.Empresas;
import siprp.database.cayenne.objects.HsPosto;
import siprp.database.cayenne.objects.HsPostoRisco;
import siprp.database.cayenne.objects.HsRisco;
import siprp.database.cayenne.objects.HsRiscoEmpresa;
import siprp.logic.HigieneSegurancaLogic;
import siprp.logic.node.NodeRisco;

public class AdicionarRiscosPanel extends JPanel
{

	private static final long serialVersionUID = 1L;

	public static final String SELECTION_CHANGED = "RISCOS_SELECTION_CHANGED";

	private final LeafButton buttonAdicionar = new LeafButton( "Adicionar" );

	private final LeafButton buttonRemover = 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;

	private HsPosto posto = null;

	public AdicionarRiscosPanel()
	{
		startupComponents();
		setupLayout();
		placeComponents();
		startupListeners();
	}

	private void startupComponents()
	{
		buttonAdicionar.setEnabled( false );
		buttonRemover.setEnabled( false );
		tree.setRootVisible( false );
		tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
	}

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

	private void placeComponents()
	{
		JPanel panel = new JPanel();
		TableLayout layout = new TableLayout( new double[] {
				TableLayout.MINIMUM, TableLayout.FILL, TableLayout.MINIMUM
		}, new double[] {
			TableLayout.MINIMUM
		} );
		layout.setHGap( 5 );
		layout.setVGap( 5 );
		panel.setLayout( layout );
		panel.add( buttonAdicionar, new TableLayoutConstraints( 0, 0 ) );
		panel.add( buttonRemover, new TableLayoutConstraints( 2, 0 ) );

		add( panel, new TableLayoutConstraints( 0, 0 ) );
		add( scroll, new TableLayoutConstraints( 0, 1 ) );
	}

	private void startupListeners()
	{
		buttonAdicionar.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				add();
			}
		} );
		buttonRemover.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				rem();
			}
		} );
		tree.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener()
		{
			@Override
			public void valueChanged( TreeSelectionEvent e )
			{
				setEnabled();
				TreePath path = tree.getSelectionPath();
				if( path != null )
				{
					Object selection = path.getLastPathComponent();
					firePropertyChange( SELECTION_CHANGED, null, selection );
				}
			}
		} );
	}

	private void add()
	{
		DefaultMutableTreeNode allRiscos = getAllRiscos();
		TreeTools.removeAll( allRiscos, getRiscosTree() );
		TreeInserterDialog dialog = new TreeInserterDialog( "Adicionar Riscos", allRiscos );
		DefaultMutableTreeNode result = dialog.getResult();
		if( result != null )
		{
			addResult( result );
			refresh();
		}
		setEnabled();
	}

	private DefaultMutableTreeNode getAllRiscos()
	{
		DefaultMutableTreeNode result = new DefaultMutableTreeNode();
		if( posto == null )
		{
			result = HigieneSegurancaLogic.getRiscosTree();
		}
		else
		{
			result = HigieneSegurancaLogic.getRiscosTree( posto.getToHsArea().getToEmpresas() );
		}
		return result;
	}

	private DefaultMutableTreeNode getRiscosTree()
	{
		DefaultMutableTreeNode result = new DefaultMutableTreeNode();
		for( int i = 0; i < root.getChildCount(); ++i )
		{
			DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) root.getChildAt( i );
			BaseObject userObject = (BaseObject) childNode.getUserObject();
			HsRisco risco = null;
			if( userObject instanceof HsRiscoEmpresa )
			{
				risco = ((HsRiscoEmpresa) userObject).getToHsRisco();
			}
			else if( userObject instanceof HsPostoRisco )
			{
				risco = ((HsPostoRisco) userObject).getToHsRisco();
			}
			if( risco != null )
			{
				result.add( new NodeRisco( risco ) );
			}
		}
		return result;
	}

	private void addResult( DefaultMutableTreeNode root )
	{
		try
		{
			if( root != null )
			{
				if( root instanceof NodeRisco )
				{
					HsRisco risco = (HsRisco) root.getUserObject();
					if( empresa != null )
					{
						HsRiscoEmpresa rel = new HsRiscoEmpresa();
						rel.setToEmpresa( empresa );
						rel.setToHsRisco( risco );
						rel.save();
					}
					else if( posto != null )
					{
						HsPostoRisco rel = new HsPostoRisco();
						rel.setToHsPosto( posto );
						rel.setToHsRisco( risco );
						rel.save();
					}
				}
				for( int i = 0; i < root.getChildCount(); ++i )
				{
					DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt( i );
					addResult( child );
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void rem()
	{
		try
		{
			TreePath path = tree.getSelectionPath();
			if( path != null )
			{
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
				Object obj = node.getUserObject();
				if( obj != null )
				{
					((BaseObject) obj).delete();
					refresh();
				}
			}
		} catch( Exception e )
		{
			LeafError.error( e );
		}
	}

	private void setEnabled()
	{
		if( empresa != null )
		{
			buttonAdicionar.setEnabled( true );
		}
		else if( posto != null )
		{
			buttonAdicionar.setEnabled( true );
		}
		else
		{
			buttonAdicionar.setEnabled( false );
		}
		buttonRemover.setEnabled( tree.getSelectionCount() > 0 );
	}

	public void refresh()
	{
		root.removeAllChildren();
		if( empresa != null )
		{
			for( HsRiscoEmpresa rel : empresa.getHsRiscoEmpresaArray() )
			{
				root.add( new DefaultMutableTreeNode( rel ) );
			}
		}
		else if( posto != null )
		{
			for( HsPostoRisco rel : posto.getHsPostoRiscoArray() )
			{
				root.add( new DefaultMutableTreeNode( rel ) );
			}
		}
		setEnabled();
		TreeTools.refreshTree( tree, root );
	}

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

	public void setPosto( HsPosto posto )
	{
		this.posto = posto;
		this.empresa = null;
		refresh();
	}

}
