/*
 * ProcessoPanel.java
 *
 * Created on March 21, 2007, 9:11 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package siprp.medicina.processo;

import com.evolute.utils.dataui.ControllableComponent;
import com.evolute.utils.images.ImageIconLoader;
import com.evolute.utils.ui.DialogException;
import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Vector;
import javax.swing.*;
import siprp.ficha.FichaWindow;
import siprp.ficha.SaveExameListener;
import siprp.medicina.MedicinaConstants;
import siprp.medicina.MedicinaDataProvider;
import siprp.medicina.processo.data.TrabalhadoresProcessoData;

/**
 *
 * @author fpalma
 */
public class ProcessoPanel extends JPanel
		implements ActionListener, ControllableComponent, 
					MedicinaConstants, ProcessoConstants, SaveExameListener
{
	private static final String ECDS_ICON_PATH = "siprp/medicina/processo/icons/ecds.png";
	private static final String CONSULTA_ICON_PATH = "siprp/medicina/processo/icons/consulta.png";
	private static final String FICHA_APTIDAO_ICON_PATH = "siprp/medicina/processo/icons/fichaaptidao.png";
	private static final String FECHAR_ICON_PATH = "siprp/medicina/processo/icons/lock.png";
	
	private static final DateFormat D_F = DateFormat.getDateInstance( DateFormat.SHORT, new Locale( "pt", "PT" ) );
	
	private JTextField estadoText;
	private JTextField inicioText;
	private JTextField fimText;
	private JButton motivoButton;
	private JButton novoECDButton;
	private JButton novaConsultaButton;
	private JButton emitirFAButton;
	private JButton fecharButton;
		
	protected JFrame owner;
	
	private final Vector<ProcessoListener> PROCESSO_LISTENERS = new Vector<ProcessoListener>();
	
	private ProcessoDataProvider provider;
	
	private Integer trabalhadorID = null;
	private TrabalhadoresProcessoData processo;
	
	/** Creates a new instance of ProcessoPanel */
	public ProcessoPanel( JFrame owner )
		throws Exception
	{
		this.owner = owner;
		provider = ProcessoDataProvider.getProvider();
		setupComponents();
		enableButtons();
	}
	
	
	private void setupComponents()
	{
		motivoButton = new JButton( "Motivo" );
		motivoButton.addActionListener( this );
		JLabel estadoLabel = new JLabel( "Estado" );
		estadoText = new JTextField();
		estadoText.setPreferredSize( new Dimension( 120, 20 ) );
		estadoText.setEditable( false );
		JLabel inicioLabel = new JLabel( "In\u00edcio" );
		inicioText = new JTextField();
		inicioText.setPreferredSize( new Dimension( 120, 20 ) );
		inicioText.setEditable( false );
		JLabel fimLabel = new JLabel( "Fim" );
		fimText = new JTextField();
		fimText.setPreferredSize( new Dimension( 120, 20 ) );
		fimText.setEditable( false );
		novoECDButton = new JButton( "Marcar ECDs" );
		novoECDButton.setIcon( getIcon( ECDS_ICON_PATH ) );
		novoECDButton.addActionListener( this );
		novaConsultaButton = new JButton( "Marcar Consulta" );
		novaConsultaButton.setIcon( getIcon( CONSULTA_ICON_PATH ) );
		novaConsultaButton.addActionListener( this );
		emitirFAButton = new JButton( "Ficha de Aptid\u00e3o" );
		emitirFAButton.setIcon( getIcon( FICHA_APTIDAO_ICON_PATH ) );
		emitirFAButton.addActionListener( this );
		fecharButton = new JButton( "Fechar Processo" );
		fecharButton.setIcon( getIcon( FECHAR_ICON_PATH ) );
		fecharButton.addActionListener( this );
		JPanel buttonPanel = new JPanel();
		
		double cols[] =
				new double[]{ TableLayout.MINIMUM, TableLayout.PREFERRED, TableLayout.FILL };
		double rows[] =
				new double[]{ TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED,
				TableLayout.PREFERRED, TableLayout.FILL };
		
		TableLayout tableLayout = new TableLayout( cols, rows );
		setLayout( tableLayout );
		
		add( motivoButton, new TableLayoutConstraints( 0, 0, 2, 0 ) );
		add( estadoLabel, new TableLayoutConstraints( 0, 1 ) );
		add( estadoText, new TableLayoutConstraints( 1, 1 ) );
		add( inicioLabel, new TableLayoutConstraints( 0, 2 ) );
		add( inicioText, new TableLayoutConstraints( 1, 2 ) );
		add( fimLabel, new TableLayoutConstraints( 0, 3 ) );
		add( fimText, new TableLayoutConstraints( 1, 3 ) );
		add( buttonPanel, new TableLayoutConstraints( 2, 1, 2, 3 ) );
		
		buttonPanel.setLayout( new GridLayout( 2, 2 ) );
		buttonPanel.add( novoECDButton );
		buttonPanel.add( novaConsultaButton );
		buttonPanel.add( emitirFAButton );
		buttonPanel.add( fecharButton );
	}
	
	public void actionPerformed(ActionEvent e)
	{
		Object source = e.getSource();
		if( source.equals( motivoButton ) )
		{
			escolherMotivo();
		}
		else if( source.equals( novoECDButton ) )
		{
			novoECD();
		}
		else if( source.equals( novaConsultaButton ) )
		{
			novaConsulta();
		}
		else if( source.equals( emitirFAButton ) )
		{
			emitirFA();
		}
		else if( source.equals( fecharButton ) )
		{
			fecharProcesso();
		}
	}
	
	protected boolean gravarProcesso()
	{
		if( processo.get( TrabalhadoresProcessoData.ESTADO ) == null )
		{
			processo.set( TrabalhadoresProcessoData.ESTADO, PROCESSO_ABERTO_CODE );
			processo.set( TrabalhadoresProcessoData.DATA_INICIO, new Date() );
		}
		try
		{
			provider.saveProcesso( processo );
			
			return true;
		}
		catch( Exception ex )
		{
			DialogException.showExceptionMessage( ex, "Erro a gravar processo", true );
			return false;
		}
	}
	
	protected void escolherMotivo()
	{
		EscolherMotivoDialog dialog = new EscolherMotivoDialog( owner );
		dialog.setVisible( true );
		Integer motivo[] = dialog.getMotivo();
		if( motivo != null && motivo[ 0 ] != null )
		{
			processo.set( TrabalhadoresProcessoData.MOTIVO, motivo[ 0 ] );
			processo.set( TrabalhadoresProcessoData.SUB_MOTIVO, motivo[ 1 ] );
			if( gravarProcesso() )
			{
				reload();
				HashMap<Integer,Integer> ids = new HashMap<Integer,Integer>();
				ids.put( ProcessoEvent.TIPO_PROCESSO, ( Integer ) processo.get( TrabalhadoresProcessoData.ID ) );
				ProcessoEvent event = new ProcessoEvent( this, ProcessoEvent.ACCAO_ESCOLHER_MOTIVO, ids );
				for( int n = 0; n < PROCESSO_LISTENERS.size(); n++ )
				{
					PROCESSO_LISTENERS.get( n ).processoStateChanged( event );
				}
			}
		}
	}
	
	protected void novoECD()
	{
	}
	
	protected void novaConsulta()
	{
		notifyListeners( ProcessoEvent.ACCAO_MARCAR_CONSULTA );
	}
	
	protected void emitirFA()
	{
		if( trabalhadorID != null )
		{
			try
			{
				FichaWindow.getWindow().editTrabalhador( trabalhadorID, this );
			}
			catch( Exception ex )
			{
				DialogException.showException( ex );
			}
		}
	}
	
	protected void fecharProcesso()
	{
		String options[] = new String[]{ "N\u00e3o", "Sim" };
		int option = JOptionPane.showOptionDialog( owner, 
						"Tem a certeza que quer fechar o processo sem Ficha de Aptid\u00e3o?",
						"Fechar", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, 
						getIcon( FECHAR_ICON_PATH ), options, options[ 0 ] );
		if( option == 1 )
		{
			processo.set( TrabalhadoresProcessoData.ESTADO, PROCESSO_FECHADO_CODE );
			processo.set( TrabalhadoresProcessoData.DATA_FIM, new Date() );
			if( gravarProcesso() )
			{
				enableButtons();
				notifyListeners( ProcessoEvent.ACCAO_FECHAR );
				reload();
			}
		}
	}

	public void clear()
	{
		processo = null;
		estadoText.setText( "" );
		inicioText.setText( "" );
		fimText.setText( "" );
		motivoButton.setText( "Motivo" );
		enableButtons();
	}
	
	protected void enableButtons()
	{
		String estado = null;
		Integer motivo = null;
		boolean consultasPorRealizar = false;
		boolean ecdsPorRealizar = false;
		if( processo != null )
		{
			Integer id = ( Integer ) processo.get( TrabalhadoresProcessoData.ID );
			estado = ( String ) processo.get( TrabalhadoresProcessoData.ESTADO );
			motivo = ( Integer ) processo.get( TrabalhadoresProcessoData.MOTIVO );
			try
			{
				if( id != null )
				{
					consultasPorRealizar = provider.getProcessoTemConsultasPorRealizar( id );
					ecdsPorRealizar = provider.getProcessoTemECDsPorRealizar( id );
				}
			}
			catch( Exception ex )
			{
				ex.printStackTrace();
			}
		}
//		novoECDButton.setEnabled( processo != null && motivo != null );
		novoECDButton.setEnabled( false );
		novaConsultaButton.setEnabled( processo != null && motivo != null && !consultasPorRealizar );
		emitirFAButton.setEnabled( processo != null && motivo != null );
		fecharButton.setEnabled( processo != null && motivo != null && PROCESSO_ABERTO_CODE.equals( estado ) );
		motivoButton.setEnabled( processo != null );
	}
		
	public void addProcessoListener( ProcessoListener listener )
	{
		PROCESSO_LISTENERS.add( listener );
	}
	
	public void removeProcessoListener( ProcessoListener listener )
	{
		PROCESSO_LISTENERS.remove( listener );
	}
	
	public Icon getIcon( String path )
	{
		try
		{
			return ImageIconLoader.loadImageIcon( getClass(), path );
		}
		catch( Exception ex )
		{
			ex.printStackTrace();
			return null;
		}
	}
	
	public Object save()
	{
		return null;
	}
	
	public void enableComponents( boolean enable )
	{
		
	}
	
	public void fill( Object value )
	{
		clear();
		if( trabalhadorID == null )
		{
			return;
		}
		if( value != null )
		{
			try
			{
				processo = provider.getProcessoByID( ( Integer ) value );
				if( processo == null )
				{
					processo = new TrabalhadoresProcessoData();
					processo.set( TrabalhadoresProcessoData.TRABALHADOR_ID, trabalhadorID );
				}
			}
			catch( Exception ex )
			{
				DialogException.showExceptionMessage( ex, "Erro a carregar dados do processo", true );
			}
		}
		reload();
	}
	
	public void reload()
	{
		enableButtons();
		if( processo != null )
		{
			String estado = null;
			Date dataInicio = ( Date ) processo.get( TrabalhadoresProcessoData.DATA_INICIO );
			if( dataInicio != null )
			{
				inicioText.setText( D_F.format( dataInicio ) );
			}
			Date dataFim = ( Date ) processo.get( TrabalhadoresProcessoData.DATA_FIM );
			if( dataFim != null )
			{
				fimText.setText( D_F.format( dataFim ) );
			}
			estado = ( String ) processo.get( TrabalhadoresProcessoData.ESTADO );
			if( estado == null )
			{
				estadoText.setText( ProcessoDataProvider.PROCESSO_POR_ABRIR_DESCRIPTION );
			}
			else
			{
				estadoText.setText( ProcessoDataProvider.ESTADO_PROCESSO_BY_CODE.get( estado ) );
			}
			Integer motivo = ( Integer ) processo.get( TrabalhadoresProcessoData.MOTIVO );
			Integer subMotivo = ( Integer ) processo.get( TrabalhadoresProcessoData.SUB_MOTIVO );
			String motivoStr = "Motivo";
			if( motivo != null )
			{
				motivoStr = MedicinaDataProvider.MOTIVOS_BY_ID.get( motivo );
				if( subMotivo != null )
				{
					motivoStr += " > " + MedicinaDataProvider.SUB_MOTIVOS_BY_ID.get( subMotivo );
				}
			}
			motivoButton.setText( motivoStr );
		}
	}
	
	public void setTrabalhadorID( Integer trabalhadorID )
	{
		this.trabalhadorID = trabalhadorID;
	}
	
	public void exameSaved( Integer trabalhadorID, Integer exameID )
	{
		if( trabalhadorID.equals( this.trabalhadorID ) )
		{
			processo.set( TrabalhadoresProcessoData.ESTADO, PROCESSO_FECHADO_CODE );
			processo.set( TrabalhadoresProcessoData.DATA_FIM, new Date() );
			if( gravarProcesso() )
			{
				enableButtons();
				notifyListeners( ProcessoEvent.ACCAO_EMITIR_FA );
				reload();
			}
			System.out.println( "NOTIFIED EXAME: " + exameID );
		}
	}
	
	protected void notifyListeners( int accao )
	{
		HashMap<Integer,Integer> ids = new HashMap<Integer,Integer>();
		ids.put( ProcessoEvent.TIPO_PROCESSO, ( Integer ) processo.get( TrabalhadoresProcessoData.ID ) );
		ProcessoEvent event = new ProcessoEvent( this, accao, ids );
		for( int n = 0; n < PROCESSO_LISTENERS.size(); n++ )
		{
			PROCESSO_LISTENERS.get( n ).processoStateChanged( event );
		}
	}
}
