/*
 * ConsultaPanel.java
 *
 * Created on March 22, 2007, 10:58 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package siprp.medicina.processo.detalhes;

import com.evolute.utils.Singleton;
import com.evolute.utils.data.IDObject;
import com.evolute.utils.jdo.JDOProvider;
import com.evolute.utils.ui.DialogException;
import com.evolute.utils.ui.calendar.JCalendarPanel;
import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import siprp.medicina.MedicinaConstants;
import siprp.medicina.processo.ProcessoConstants;
import siprp.medicina.processo.ProcessoDataProvider;
import siprp.medicina.processo.ProcessoEvent;
import siprp.medicina.processo.ProcessoListener;
import siprp.medicina.processo.data.TrabalhadoresConsultasData;
import siprp.medicina.processo.data.TrabalhadoresConsultasDatasData;

/**
 *
 * @author fpalma
 */
public class ConsultaPanel extends JPanel
		implements ActionListener, MedicinaConstants, ChangeListener
{
	protected JFrame owner;
	protected JCalendarPanel dataConsultaPanel;
	protected JButton estadoButton;
	protected JButton emailButton;
	protected JButton observacoesButton;
	protected ObservacoesDialog observacoesDialog;
	
	protected final Vector<ProcessoListener> PROCESSO_LISTENERS = new Vector<ProcessoListener>();
	protected JDOProvider JDO;
	protected ProcessoDataProvider provider;
	
	protected Integer trabalhadorID;
	protected Integer processoID;
	protected TrabalhadoresConsultasData consulta;
	protected TrabalhadoresConsultasDatasData consultaData;
	
	/** Creates a new instance of ConsultaPanel */
	public ConsultaPanel( JFrame owner )
		throws Exception
	{
		this.owner = owner;
		JDO = ( JDOProvider ) Singleton.getInstance( Singleton.DEFAULT_JDO_PROVIDER );
		provider = ProcessoDataProvider.getProvider();
		setupComponents();
	}
	
	private void setupComponents()
	{
		JLabel dataLabel = new JLabel( "Data" );
		dataConsultaPanel = new JCalendarPanel( null );
		dataConsultaPanel.addChangeListener( this );
		estadoButton = new JButton( " " );
		estadoButton.addActionListener( this );
		emailButton = new JButton( "Email" );
		emailButton.addActionListener( this );
		observacoesButton = new JButton( "Coment\u00e1rio" );
		observacoesButton.addActionListener( this );
		
		double cols[] =
				new double[]{ TableLayout.MINIMUM, TableLayout.FILL };
		double rows[] = 
				new double[]{ TableLayout.MINIMUM, TableLayout.MINIMUM, 
								TableLayout.MINIMUM, TableLayout.MINIMUM };
		
		TableLayout tableLayout = new TableLayout( cols, rows );
		tableLayout.setVGap( 5 );
		setLayout( tableLayout );
		
		add( dataLabel, new TableLayoutConstraints( 0, 0 ) );
		add( dataConsultaPanel, new TableLayoutConstraints( 1, 0 ) );
		add( estadoButton, new TableLayoutConstraints( 0, 1, 1, 1 ) );
		add( emailButton, new TableLayoutConstraints( 0, 2, 1, 2 ) );
		add( observacoesButton, new TableLayoutConstraints( 0, 3, 1, 3 ) );
	}

	public void actionPerformed(ActionEvent e)
	{
		Object source = e.getSource();
		if( source.equals( observacoesButton ) )
		{
			editarObservacoes();
		}
		else if( source.equals( emailButton ) )
		{
			enviarEmail();
		}
		else if( source.equals( estadoButton ) )
		{
			mudarEstado();
		}
	}

	public void stateChanged(ChangeEvent e)
	{
		Object source = e.getSource();
		
		if( source.equals( dataConsultaPanel ) )
		{
			Date data = dataConsultaPanel.getDate();
			if( data == null )
			{
				return;
			}
			try
			{
				boolean nova = false;
				if( consulta == null )
				{
					nova = true;
					Integer consultaID = provider.getConsultaEmAbertoForProcesso( processoID );
					if( consultaID == null )
					{
						consulta = new TrabalhadoresConsultasData();
						consulta.set( TrabalhadoresConsultasData.TRABALHADOR_ID, trabalhadorID );
						consulta.set( TrabalhadoresConsultasData.PROCESSO_ID, processoID );
						consulta.set( TrabalhadoresConsultasData.ESTADO, new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) );
					}
					else
					{
						consulta = provider.getConsultaByID( consultaID );
						consulta.set( TrabalhadoresConsultasData.ESTADO, new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) );
					}
				}
				consulta.set( TrabalhadoresConsultasData.DATA, data );
				provider.saveConsulta( consulta );
				if( consultaData == null )
				{
					Integer consultaID = ( Integer )consulta.get( TrabalhadoresConsultasData.ID );
					Integer consultaDataID = provider.getLastConsultaDataIDForConsulta( consultaID );
					if( consultaDataID == null || nova )
					{
						consultaData = new TrabalhadoresConsultasDatasData();
						consultaData.set( TrabalhadoresConsultasDatasData.TRABALHADORES_CONSULTAS_ID, consultaID );
						consultaData.set( TrabalhadoresConsultasDatasData.ESTADO, new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) );
					}
					else
					{
						consultaData = provider.getConsultaDataByID( consultaDataID );
					}
				}
				consultaData.set( TrabalhadoresConsultasDatasData.DATA, data );
				provider.saveConsultaData( consultaData );
				
				notifyListeners( ProcessoEvent.ACCAO_MUDAR_DATA_MARCACAO );
			}
			catch( Exception ex )
			{
				DialogException.showExceptionMessage( ex, "Erro a gravar dados da consulta", true );
				return;
			}
		}
	}
	
	protected void editarObservacoes()
	{
		if( observacoesDialog == null )
		{
			observacoesDialog = new ObservacoesDialog( owner );
		}
		String texto = "";
		try
		{
			Integer dataID = provider.getLastConsultaDataIDForConsulta( ( Integer ) consulta.get( TrabalhadoresConsultasData.ID ) );
			IDObject observacoes = provider.getObservacoesConsultaData( dataID );
			if( observacoes != null )
			{
				texto = observacoes.toString();
			}
			texto = observacoesDialog.editarObservacao( texto );
			if( texto != null )
			{
				provider.saveObservacoesConsultaData( dataID, texto );
				notifyListeners( ProcessoEvent.ACCAO_ESCREVER_OBSERVACOES );
			}
		}
		catch( Exception ex )
		{
			DialogException.showExceptionMessage( ex, "Erro a carregar dados", true );
			return;
		}
	}
	
	protected void enviarEmail()
	{
		if( consulta == null )
		{
			return;
		}
		try
		{
			Integer consultaDataID;
			if( consultaData == null )
			{
				Integer consultaID = ( Integer )consulta.get( TrabalhadoresConsultasDatasData.ID );
				consultaDataID = provider.getLastConsultaDataIDForConsulta( consultaID );
				consultaData = provider.getConsultaDataByID( consultaDataID );
			}
			consultaDataID = ( Integer ) consultaData.get( TrabalhadoresConsultasDatasData.ID );
			provider.saveEmailConsultaData( consultaDataID, "teste@siprp.pt", "Email de teste.", "" );
			notifyListeners( ProcessoEvent.ACCAO_ESCREVER_MAIL );
		}
		catch( Exception ex )
		{
			DialogException.showExceptionMessage( ex, "Erro a gravar dados da consulta", true );
			return;
		}
	}
	
	protected void mudarEstado()
	{
		if( consulta == null )
		{
			return;
		}
		Integer estado = ( Integer ) consulta.get( TrabalhadoresConsultasData.ESTADO );
		EstadoChooser chooser = 
			new EstadoChooser( owner, ProcessoConstants.TIPO_CONSULTA, 
								estado != null ? estado.intValue() : MedicinaConstants.ESTADO_POR_REALIZAR );
		chooser.setVisible( true );
		int novoEstado = chooser.getEstado();
		if( estado == null || estado.intValue() != novoEstado )
		{
			try
			{
				consulta.set( TrabalhadoresConsultasData.ESTADO, new Integer( novoEstado ) );
				provider.saveConsulta( consulta );
				if( consultaData == null )
				{
					Integer consultaID = ( Integer )consulta.get( TrabalhadoresConsultasDatasData.ID );
					Integer consultaDataID = provider.getLastConsultaDataIDForConsulta( consultaID );
					consultaData = provider.getConsultaDataByID( consultaDataID );
				}
				consultaData.set( TrabalhadoresConsultasDatasData.ESTADO, new Integer( novoEstado ) );
				provider.saveConsultaData( consultaData );
				
				notifyListeners( ProcessoEvent.ACCAO_MUDAR_ESTADO_MARCACAO );
			}
			catch( Exception ex )
			{
				DialogException.showExceptionMessage( ex, "Erro a gravar dados da consulta", true );
				return;
			}
		}
	}
	
	public void addProcessoListener( ProcessoListener listener )
	{
		PROCESSO_LISTENERS.add( listener );
	}
	
	public void removeProcessoListener( ProcessoListener listener )
	{
		PROCESSO_LISTENERS.remove( listener );
	}
	
	public void clear()
	{
		dataConsultaPanel.setDate( null );
		estadoButton.setText( " " );
		consulta = null;
		consultaData = null;
	}
	
	public void fill( Object value )
	{
		clear();
		if( value != null )
		{
			try
			{
				consulta = ( TrabalhadoresConsultasData ) JDO.load( TrabalhadoresConsultasData.class, ( Integer ) value );
				Date data = ( Date ) consulta.get( TrabalhadoresConsultasData.DATA );
				Integer estado = ( Integer ) consulta.get( TrabalhadoresConsultasData.ESTADO );
				dataConsultaPanel.setDate( data );
				if( estado != null )
				{
					estadoButton.setText( ESTADOS_CONSULTA_STR[ estado.intValue() ] );
				}
				else
				{
					estadoButton.setText( " " );
				}
			}
			catch( Exception ex )
			{
				DialogException.showExceptionMessage( ex, "Erro a carregar dados da consulta", true );
			}
		}
		enableButtons();
	}
	
	protected void enableButtons()
	{
		if( consulta != null )
		{
			Integer estado = ( Integer ) consulta.get( TrabalhadoresConsultasData.ESTADO );
			dataConsultaPanel.setEnabled( estado == null || estado.intValue() == ESTADO_POR_REALIZAR );
			estadoButton.setEnabled( consulta.get( TrabalhadoresConsultasData.DATA ) != null );
			emailButton.setEnabled( consulta.get( TrabalhadoresConsultasData.DATA ) != null );
			observacoesButton.setEnabled( consulta.get( TrabalhadoresConsultasData.DATA ) != null );
		}
		else
		{
			dataConsultaPanel.setEnabled( true );
			estadoButton.setEnabled( false );
			emailButton.setEnabled( false );
			observacoesButton.setEnabled( false );
		}
	}
	
	public void setTrabalhadorID( Integer trabalhadorID )
	{
		this.trabalhadorID = trabalhadorID;
	}
	
	public void setProcessoID( Integer processoID )
	{
		this.processoID = processoID;
	}
	
	protected void notifyListeners( int accao )
	{
		HashMap<Integer,Integer> ids = new HashMap<Integer,Integer>();
		ids.put( ProcessoEvent.TIPO_PROCESSO, processoID );
		if( consulta != null )
		{
			ids.put( ProcessoEvent.TIPO_CONSULTA, ( Integer ) consulta.get( TrabalhadoresConsultasData.ID ) );
		}
		if( consultaData != null )
		{
			ids.put( ProcessoEvent.TIPO_DATA, ( Integer ) consulta.get( TrabalhadoresConsultasDatasData.ID ) );
		}
		ProcessoEvent event = new ProcessoEvent( this, accao, ids );
		for( int n = 0; n < PROCESSO_LISTENERS.size(); n++ )
		{
			PROCESSO_LISTENERS.get( n ).processoStateChanged( event );
		}
	}
}
