package siprp.medicina.processo.ui;

import static siprp.medicina.processo.logic.MedicinaProcessoLogic.CLOSE;
import static siprp.medicina.processo.logic.MedicinaProcessoLogic.CREATE_LEMBRETE;
import static siprp.medicina.processo.logic.MedicinaProcessoLogic.REALIZAR_PARCIAL_EXAME_MARCACAO;
import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;

import java.awt.Dimension;
import java.util.Date;
import java.util.List;

import javax.swing.JSeparator;

import leaf.data.OrderedMap;
import leaf.ui.LeafCalendarDialog;
import leaf.ui.LeafOptionDialog;
import leaf.ui.LeafTextDialog;
import leaf.ui.LeafWindow;
import leaf.ui.LeafLogic.LeafUIActionBinding;
import siprp.MedicinaConstants;
import siprp.database.cayenne.objects.Lembretes;
import siprp.database.cayenne.objects.PrtGruposProtocolo;
import siprp.database.cayenne.objects.Trabalhadores;
import siprp.database.cayenne.objects.TrabalhadoresEcd;
import siprp.database.cayenne.objects.TrabalhadoresEcdsDatas;
import siprp.medicina.processo.logic.MedicinaProcessoLogic;

public class MedicinaProcessoWindow extends LeafWindow
{
	private static final long serialVersionUID = 1L;

	private static final Dimension WINDOW_DIMENSION = new Dimension( 1024, 700 );

	public static final String TITLE = "Processos de Trabalhadores";

	private static final Dimension DIMENSION_TRABALHADORES_CHOOSER = new Dimension( 0, 200 );
	private static final Dimension DIMENSION_PROCESSO_TOOLBAR = new Dimension( 150, 0 );

	public final JSeparator separator = new JSeparator();
	@LeafPanel
	public final ProcessoDadosPanel panelProcessoDados;
	@LeafPanel
	public final ProcessoAccoesPanel panelProcessoToolbar;
	@LeafPanel
	public final ProcessoTreePanel panelProcessoTree;
	@LeafPanel
	public final TrabalhadoresChooserPanel panelTrabalhadoresChooser;

	public MedicinaProcessoWindow() throws Exception
	{
		super( new MedicinaProcessoLogic() );
		panelProcessoDados = new ProcessoDadosPanel( this );
		panelProcessoToolbar = new ProcessoAccoesPanel( this );
		panelProcessoTree = new ProcessoTreePanel( this );
		panelTrabalhadoresChooser = new TrabalhadoresChooserPanel( this );

		startup();
	}

	public MedicinaProcessoWindow(Trabalhadores trabalhador) throws Exception
	{
		super( new MedicinaProcessoLogic() );
		panelProcessoDados = new ProcessoDadosPanel( this );
		panelProcessoToolbar = new ProcessoAccoesPanel( this );
		panelProcessoTree = new ProcessoTreePanel( this );
		panelTrabalhadoresChooser = new TrabalhadoresChooserPanel( this );
		startup();
		runAction( MedicinaProcessoLogic.LOAD_TRABALHADOR, trabalhador );
	}

	private void startup()
	{
		setSize( WINDOW_DIMENSION );
		setTitle( TITLE );
		setupLayout();
		setupComponents();
		placeComponents();
		completeSetup();
	}

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

	private void setupComponents()
	{
		panelTrabalhadoresChooser.setPreferredSize( DIMENSION_TRABALHADORES_CHOOSER );
		panelProcessoToolbar.setPreferredSize( DIMENSION_PROCESSO_TOOLBAR );
	}

	private void placeComponents()
	{
		this.add( panelTrabalhadoresChooser, new TableLayoutConstraints( 0, 0, 2, 0 ) );
		this.add( separator, new TableLayoutConstraints( 0, 1, 2, 1 ) );
		this.add( panelProcessoToolbar, new TableLayoutConstraints( 0, 2 ) );
		this.add( panelProcessoTree, new TableLayoutConstraints( 1, 2 ) );
		this.add( panelProcessoDados, new TableLayoutConstraints( 2, 2 ) );
	}

	@LeafUIActionBinding(action = CLOSE)
	public void closeWindow()
	{
		close();
	}

	@LeafUIActionBinding(action = REALIZAR_PARCIAL_EXAME_MARCACAO)
	public void realizarExameParcial( TrabalhadoresEcdsDatas marcacao )
	{
		boolean atLeastOneRealizado = false;
		boolean atLeastOneFalta = false;
		if( marcacao != null )
		{
			List<TrabalhadoresEcd> ecds = marcacao.getTrabalhadoresEcdArray();
			if( ecds != null )
			{
				OrderedMap<PrtGruposProtocolo> allGrupos = marcacao.getStatesForeGruposExames();
				OrderedMap<PrtGruposProtocolo> grupos = new OrderedMap<PrtGruposProtocolo>();
				for( int row = 0; row < allGrupos.rows(); ++row )
				{
					List<Object> grupo = allGrupos.getRow( row );
					if( grupo != null && grupo.size() > 1 )
					{
						String estado = grupo.get( 1 ).toString();
						if( MedicinaConstants.ESTADOS_EXAME_STR[MedicinaConstants.ESTADO_POR_REALIZAR].equals( estado ) )
						{
							PrtGruposProtocolo key = allGrupos.getKeyForValue( grupo );
							grupos.addRow( key, grupo );
						}
					}
				}

				LeafOptionDialog<PrtGruposProtocolo> option = new LeafOptionDialog<PrtGruposProtocolo>( this, grupos, null, null, "Marcar falta para:", "Faltou >>" );
				List<PrtGruposProtocolo> selected = option.getSelected();
				if( selected != null )
				{
					for( TrabalhadoresEcd ecd : ecds )
					{
						if( selected.contains( ecd.getToPrtTiposElementosProtocolo().getToPrtGruposProtocolo() ) )
						{
							ecd.setEstado( MedicinaConstants.ESTADO_FALTOU );
							atLeastOneFalta = true;
						}
						else
						{
							ecd.setEstado( MedicinaConstants.ESTADO_REALIZADO );
							atLeastOneRealizado = true;
						}
					}
				}
			}
		}
		if( atLeastOneFalta )
		{
			if( atLeastOneRealizado )
			{
				marcacao.setEstado( MedicinaConstants.ESTADO_PARCIALMENTE_REALIZADO );
			}
			else
			{
				marcacao.setEstado( MedicinaConstants.ESTADO_FALTOU );
			}
		}
		else
		{
			if( atLeastOneRealizado )
			{
				marcacao.setEstado( MedicinaConstants.ESTADO_REALIZADO );
			}
			else
			{
			}
		}
	}

	@LeafUIActionBinding(action = CREATE_LEMBRETE)
	public void createLembrete( Lembretes lembrete )
	{
		if( lembrete != null )
		{
			Date date = new LeafCalendarDialog( this, null ).getDate();
			if( date != null && date.getTime() != 0 )
			{
				String text = new LeafTextDialog( this, null, "", true ).getText();
				if( text != null && !text.trim().equals( "" ) )
				{
					lembrete.setData( date );
					lembrete.setDescricao( text );
				}
				else
				{
					abortAction( true );
				}
			}
			else
			{
				abortAction( true );
			}
		}
	}
}
