/*
 * MedicinaWindow.java
 *
 * Created on 17 de Janeiro de 2006, 19:43
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package siprp.medicina;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
import java.util.*;

import com.evolute.utils.*;
import com.evolute.utils.arrays.*;
import com.evolute.utils.data.*;
import com.evolute.utils.jdo.*;
import com.evolute.utils.ui.*;
import com.evolute.utils.ui.panel.*;
import com.evolute.utils.ui.search.*;
import com.evolute.utils.ui.text.*;
import com.evolute.utils.ui.window.*;

import siprp.*;
import siprp.clientes.*;
import siprp.data.*;
/**
 *
 * @author fpalma
 */
public class MedicinaWindow extends TabbedWindow
		implements ActionListener, ListSelectionListener
{
	private static int iPermissionArray[][] = 
		new int[][]{ {},
						{ NEW_INDEX, EDIT_INDEX, SAVE_INDEX, DELETE_INDEX, CANCEL_INDEX },
						{ NEW_INDEX, EDIT_INDEX, SAVE_INDEX, DELETE_INDEX, CANCEL_INDEX } };
					
	private static final int TAB_CONSULTA = 0;
	private static final int TAB_EXAME = 1;
	
	private static final int INDEX_MAIN = 0;
	private static final int INDEX_CONSULTA = 1;
	private static final int INDEX_EXAME = 2;
	
	private static final String tabNames[] = 
		new String[]{ "Consultas", "Exames" };
	
	private static final DateFormat DATE_FORMAT =
			DateFormat.getDateInstance( DateFormat.SHORT, new Locale( "PT", "pt" ) );
				
	protected MedicinaDataProvider provider;
	protected FichaDataProvider fichaProvider;
	protected JDOProvider JDO;
	protected SIPRPTracker tracker;
	
	protected MedicinaUpperPanel upperPanel;
	protected MarcacaoConsultaPanel marcacaoConsultaPanel;
	protected TableEditorPanel marcacaoConsultaEditorPanel;
	protected MarcacaoExamePanel marcacaoExamePanel;
	protected TableEditorPanel marcacaoExameEditorPanel;
	protected CheckBoxPanel detalhesExamePanel;
	
	protected Integer empresaID;
	protected String empresa;
	protected Integer estabelecimentoID;
	protected String estabelecimento;
	protected Integer trabalhadorID;
	protected TrabalhadorData trabalhador;
	protected boolean estado[] = new boolean[]{ false, false };

	/** Creates a new instance of MedicinaWindow */
	public MedicinaWindow()
		throws Exception
	{
		super( new MedicinaUpperPanel(), tabNames, 0.7, createPermissions( iPermissionArray ) );
		upperPanel = ( MedicinaUpperPanel ) getUpperPanel();
		provider = ( MedicinaDataProvider ) MedicinaDataProvider.getProvider();
		fichaProvider = ( FichaDataProvider ) FichaDataProvider.getProvider();
		JDO = ( JDOProvider ) Singleton.getInstance( Singleton.DEFAULT_JDO_PROVIDER );
		setupComponents();
		maximizeOnNextActivate();
	}
	
	private void setupComponents()
		throws Exception
	{
		setTitle( "Medicina" );
		setupConsultaComponents();
		setupExameComponents();
		upperPanel.addListSelectionListener( this );
	}
	
	private void setupConsultaComponents()
	{
		JPanel panel = getTab( TAB_CONSULTA );
		
		panel.setBorder( 
			BorderFactory.createTitledBorder( 
				BorderFactory.createEtchedBorder(), "Consultas" ) );

		changeGroupName( INDEX_CONSULTA, "Consultas" );
		setActionName( INDEX_CONSULTA, NEW_INDEX, "Nova" );
		setActionTooltip( INDEX_CONSULTA, NEW_INDEX, "Nova" );
		JPanel toolbar = getToolbarPanel( INDEX_CONSULTA );
		
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints constraints = new GridBagConstraints();
		panel.setLayout( gridbag );
		constraints.insets = new Insets( 2, 2, 2, 2 );
		constraints.fill = GridBagConstraints.BOTH;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.weightx = 1.0;
		
		gridbag.setConstraints( toolbar, constraints );
		panel.add( toolbar );
		
		constraints.gridheight = 1;
		constraints.weighty = 1.0;
		try
		{
			marcacaoConsultaEditorPanel = 
				new TableEditorPanel( new String[]{ "Data", 
					"Estado" },
					new int[]{0,2}, new int[]{0,0},
						0.0, 1.0, new Dimension( 350, 100 ) );
			marcacaoConsultaPanel = new MarcacaoConsultaPanel();
			new CopyPasteHandler( marcacaoConsultaPanel.getObservacoesText() );
			marcacaoConsultaEditorPanel.addComponent( marcacaoConsultaPanel, 
					new int[]{0,2}, new int[]{1,2},
					1.0, 1.0 );
			marcacaoConsultaEditorPanel.addListSelectionListener( new ListSelectionListener(){
				public void valueChanged(javax.swing.event.ListSelectionEvent listSelectionEvent)
				{
					if( marcacaoConsultaEditorPanel.getID() != null )
					{
						reload(INDEX_CONSULTA);
						select(INDEX_CONSULTA);
					}
					else
					{
						clear( INDEX_CONSULTA );
					}
				}
			});
		}catch( Exception ex )
		{
			DialogException.showException( ex );
			return;
		}
		gridbag.setConstraints( marcacaoConsultaEditorPanel, constraints );
		panel.add( marcacaoConsultaEditorPanel );
		marcacaoConsultaPanel.getEmailButton().addActionListener( this );
	}
	
	private void setupExameComponents()
	{
		JPanel panel = getTab( TAB_EXAME );
		
		panel.setBorder( 
			BorderFactory.createTitledBorder( 
				BorderFactory.createEtchedBorder(), "Exames" ) );

		changeGroupName( INDEX_EXAME, "Exames" );
		JPanel toolbar = getToolbarPanel( INDEX_EXAME );
		
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints constraints = new GridBagConstraints();
		panel.setLayout( gridbag );
		constraints.insets = new Insets( 2, 2, 2, 2 );
		constraints.fill = GridBagConstraints.BOTH;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.weightx = 1.0;
		
		gridbag.setConstraints( toolbar, constraints );
		panel.add( toolbar );
		
		constraints.gridheight = 1;
		constraints.weighty = 1.0;
		try
		{
			marcacaoExameEditorPanel = 
				new TableEditorPanel( new String[]{ "Data", 
					"Estado" },
					new int[]{0,2}, new int[]{0,0},
						0.0, 1.0, new Dimension( 350, 100 ) );
			marcacaoExamePanel = new MarcacaoExamePanel();
			new CopyPasteHandler( marcacaoExamePanel.getObservacoesText() );
			marcacaoExameEditorPanel.addComponent( marcacaoExamePanel, 
					new int[]{0,2}, new int[]{1,2},
					1.0, 1.0 );
			marcacaoExameEditorPanel.addListSelectionListener( new ListSelectionListener(){
				public void valueChanged(javax.swing.event.ListSelectionEvent listSelectionEvent)
				{
					if( marcacaoExameEditorPanel.getID() != null )
					{
						reload(INDEX_EXAME);
						select(INDEX_EXAME);
					}
					else
					{
						clear( INDEX_EXAME );
					}
				}
			});
		}catch( Exception ex )
		{
			DialogException.showException( ex );
			return;
		}
		gridbag.setConstraints( marcacaoExameEditorPanel, constraints );
		panel.add( marcacaoExameEditorPanel );
		marcacaoExamePanel.getEmailButton().addActionListener( this );
	}

	public boolean save(int index)
	{
		Date data;
		switch( index )
		{
			case INDEX_EXAME:
				MarcacaoTrabalhadorData exame = ( MarcacaoTrabalhadorData ) marcacaoExamePanel.save();
				data = ( Date ) exame.get( MarcacaoTrabalhadorData.DATA );
				if( data == null )
				{
					JOptionPane.showMessageDialog( this, "Tem de preencher uma data para os exames.",
						"Erro", JOptionPane.ERROR_MESSAGE );
					return false;
				}
				exame.set( MarcacaoTrabalhadorData.TIPO, 
							new Integer( Marcacao.TIPO_MARCACAO_TRABALHADOR_EXAMES ) );
				exame.set( MarcacaoTrabalhadorData.TRABALHADOR, trabalhador );	
				try
				{
					exame.set( MarcacaoTrabalhadorData.REALIZADA,
								( ( Integer )exame.get( MarcacaoTrabalhadorData.ESTADO ) ).intValue() ==
									provider.ESTADO_REALIZADO ? "y" : "n" );
					exame.save();
					Integer exameID = ( Integer ) exame.get( MarcacaoTrabalhadorData.ID );
					Integer detalhesRealizados[] = detalhesExamePanel.getSelected();
					provider.setDetalhesRealziadosForMarcacao( exameID, detalhesRealizados );
				}
				catch( Exception ex )
				{
					DialogException.showExceptionMessage( ex, "Erro a gravar", true );
					return false;
				}
				
				break;
				
			case INDEX_CONSULTA:
				MarcacaoTrabalhadorData consulta = ( MarcacaoTrabalhadorData ) marcacaoConsultaPanel.save();
				data = ( Date ) consulta.get( MarcacaoTrabalhadorData.DATA );
				if( data == null )
				{
					JOptionPane.showMessageDialog( this, "Tem de preencher uma data para a consulta.",
						"Erro", JOptionPane.ERROR_MESSAGE );
					return false;
				}
				consulta.set( MarcacaoTrabalhadorData.TIPO, 
								new Integer( Marcacao.TIPO_MARCACAO_TRABALHADOR_CONSULTA ) );
				consulta.set( MarcacaoTrabalhadorData.TRABALHADOR, trabalhador );	
				try
				{
					consulta.set( MarcacaoTrabalhadorData.REALIZADA,
								( ( Integer )consulta.get( MarcacaoTrabalhadorData.ESTADO ) ).intValue() ==
									provider.ESTADO_REALIZADO ? "y" : "n" );
					consulta.save();
				}
				catch( Exception ex )
				{
					DialogException.showExceptionMessage( ex, "Erro a gravar", true );
					return false;
				}
				break;
		}
		reload( INDEX_MAIN );
		return true;
	}

	public boolean delete(int index)
	{
		int option = JOptionPane.showConfirmDialog( this, "Tem a certeza que quer apagar a marca\u00e7\u00e3o?",
									"Apagar", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE );
		if( option == 0 )
		{
			switch( index )
			{
				case INDEX_CONSULTA:
					MarcacaoTrabalhadorData consulta = ( MarcacaoTrabalhadorData ) marcacaoConsultaPanel.save();
					try
					{
						consulta.delete();
					}
					catch( Exception ex )
					{
						DialogException.showExceptionMessage( ex, "Erro a apagar.", true );
						return false;
					}
					break;
					
				case INDEX_EXAME:
					MarcacaoTrabalhadorData exame = ( MarcacaoTrabalhadorData ) marcacaoExamePanel.save();
					try
					{
						exame.delete();
					}
					catch( Exception ex )
					{
						DialogException.showExceptionMessage( ex, "Erro a apagar.", true );
						return false;
					}
					break;
			}
			reload( INDEX_MAIN );
			return true;
		}
		return false;
	}

	public void clear(int index)
	{
		switch( index )
		{
			case INDEX_MAIN:
				empresaID = null;
				empresa = null;
				estabelecimentoID = null;
				estabelecimento = null;
				trabalhadorID = null;
				trabalhador = null;
				upperPanel.clear();
				marcacaoExameEditorPanel.clear();
				marcacaoConsultaEditorPanel.clear();
//				marcacaoExamePanel.getDetalhesPanel().removeAll();
				detalhesExamePanel = null;
				break;
				
			case INDEX_CONSULTA:
				marcacaoConsultaPanel.clear();
				marcacaoConsultaPanel.getEmailButton().setText( "Enviar email" );
				break;
				
			case INDEX_EXAME:
				marcacaoExamePanel.clear();
				marcacaoExamePanel.getEmailButton().setText( "Enviar email" );
				if( detalhesExamePanel != null )
				{
					detalhesExamePanel.clear();
				}
				break;
		}
	}

	public void enableComponents(int index, boolean enable)
	{
		switch( index )
		{
			case INDEX_MAIN:
				
				break;
			
			case INDEX_EXAME:
				marcacaoExamePanel.setEnabled( enable );
				marcacaoExamePanel.getEmailButton().setEnabled( enable );
				if( detalhesExamePanel != null )
				{
					detalhesExamePanel.setEnabled( enable );
				}
				upperPanel.setEnabled( !enable );
				estado[ 0 ] = enable;
				break;
				
			case INDEX_CONSULTA:
				marcacaoConsultaPanel.setEnabled( enable );
				marcacaoConsultaPanel.getEmailButton().setEnabled( enable );
				upperPanel.setEnabled( !enable );
				estado[ 1 ] = enable;
				break;
		}
		if( tracker != null )
		{
			tracker.getAvisosPanel().setEnabled( (!estado[ 0 ]) && (!estado[1]),
													AvisoConstants.TIPO_TRABALHADOR );
		}
	}

//	public boolean searchByName()
//	{
//		fichaProvider.setSearch( FichaDataProvider.SEARCH_EMPRESAS );
//		SearchDialog search;
//		
//		search = new SearchDialog( fichaProvider, null, false, null, true );
//		empresaID = ( Integer )search.getSelected();
//		
//		if( empresaID == null )
//		{
//			return false;
//		}
//
//		fichaProvider.setSearch( FichaDataProvider.SEARCH_ESTABELECIMENTOS );
//		fichaProvider.setSearchID( FichaDataProvider.SEARCH_EMPRESAS, empresaID.intValue() );
//
//		search = new SearchDialog( fichaProvider, null, false, null, true );
//		estabelecimentoID = ( Integer )search.getSelected();
//
//		if( estabelecimentoID == null )
//		{
//			return false;
//		}
//
//		fichaProvider.setSearch( FichaDataProvider.SEARCH_TRABALHADORES );
//		fichaProvider.setSearchID( FichaDataProvider.SEARCH_ESTABELECIMENTOS, estabelecimentoID.intValue() );
//		search = new SearchDialog( fichaProvider, null, false, null, true );
//		trabalhadorID = ( Integer )search.getSelected();
//
//		if( trabalhadorID == null )
//		{
//			return false;
//		}
//		reload(0);
//		return true;
//	}
	
	protected void enableSelect( int index, boolean select )
	{
		switch( index )
		{
			case INDEX_EXAME:
				marcacaoExameEditorPanel.setEnabled( select );
				break;
				
			case INDEX_CONSULTA:
				marcacaoConsultaEditorPanel.setEnabled( select );
				break;		
		}
	}
	
	public void reload( int index )
	{
		switch( index )
		{
			case INDEX_MAIN:
				try
				{
					String nomes[] = 
							provider.getEmpresaEstabelecimento( empresaID, estabelecimentoID );
					empresa = nomes[ 0 ];
					estabelecimento = nomes[ 1 ];
					trabalhador = ( TrabalhadorData ) JDO.load( TrabalhadorData.class, trabalhadorID );
//					upperPanel.getEmpresaText().setText( empresa );
//					upperPanel.getEstabelecimentoText().setText( estabelecimento );
//					upperPanel.getTrabalhadorText().setText( ( String ) trabalhador.get( TrabalhadorData.NOME ) );
					IDObject detalhesExame[] = provider.getDetalhesValidosTrabalhador( empresaID, trabalhadorID );
					detalhesExamePanel = new CheckBoxPanel( detalhesExame );
					JPanel detalhesExameOuterPanel = marcacaoExamePanel.getDetalhesPanel();
					detalhesExameOuterPanel.setLayout( new GridLayout( 1, 1 ) );
					detalhesExameOuterPanel.removeAll();
					detalhesExameOuterPanel.add( detalhesExamePanel );
					detalhesExameOuterPanel.validate();
					Object examesTrabalhador[][] = provider.getExamesTrabalhador( trabalhadorID );
					Object consultasTrabalhador[][] = provider.getConsultasTrabalhador( trabalhadorID );
					if( examesTrabalhador.length > 0 )
					{
						marcacaoExameEditorPanel.setData( new Object2DArray( examesTrabalhador ) );
					}
					else
					{
						marcacaoExameEditorPanel.clear();
					}
					if( consultasTrabalhador.length > 0 )
					{
						marcacaoConsultaEditorPanel.setData( new Object2DArray( consultasTrabalhador ) );
					}
					else
					{
						marcacaoConsultaEditorPanel.clear();
					}
				}
				catch( Exception ex )
				{
					DialogException.showExceptionMessage( ex, "Erro a carregar os dados.", true );
				}
				break;
				
			case INDEX_EXAME:
				Integer exameID = marcacaoExameEditorPanel.getID();
				if( exameID == null )
				{
					return;
				}
				try
				{
					MarcacaoTrabalhadorData exame = 
							( MarcacaoTrabalhadorData ) JDO.load( MarcacaoTrabalhadorData.class, exameID );			
					marcacaoExamePanel.fill( exame );
					Date dataEmailExame = ( Date ) exame.get( MarcacaoTrabalhadorData.DATA_EMAIL );
					if( dataEmailExame != null )
					{
						marcacaoExamePanel.getEmailButton().setText( "Enviar email (" + DATE_FORMAT.format( dataEmailExame ) + ")" );
					}
					else
					{
						marcacaoExamePanel.getEmailButton().setText( "Enviar email" );
					}
					Integer detalhesRealizados[] = provider.getDetalhesRealizadosForMarcacao( exameID );
					detalhesExamePanel.setSelected( detalhesRealizados );
				}
				catch( Exception ex )
				{
					DialogException.showExceptionMessage( ex, "Erro a carregar os dados do exame.", true );
				}
				break;
				
			case INDEX_CONSULTA:
				Integer consultaID = marcacaoConsultaEditorPanel.getID();
				if( consultaID == null )
				{
					return;
				}
				try
				{
					MarcacaoTrabalhadorData consulta = 
							( MarcacaoTrabalhadorData ) JDO.load( MarcacaoTrabalhadorData.class, consultaID );			
					marcacaoConsultaPanel.fill( consulta );
					Date dataEmailConsulta = ( Date ) consulta.get( MarcacaoTrabalhadorData.DATA_EMAIL );
					if( dataEmailConsulta != null )
					{
						marcacaoConsultaPanel.getEmailButton().setText( "Enviar email (" + DATE_FORMAT.format( dataEmailConsulta ) + ")" );
					}
					else
					{
						marcacaoConsultaPanel.getEmailButton().setText( "Enviar email" );
					}
				}
				catch( Exception ex )
				{
					DialogException.showExceptionMessage( ex, "Erro a carregar os dados da consulta.", true );
				}
				break;
		}
	}
	
	public void actionPerformed( ActionEvent e )
	{
		Object source = e.getSource();
		if( source.equals( marcacaoExamePanel.getEmailButton() ) )
		{
			enviarEmailExame();
		}
		else if( source.equals( marcacaoConsultaPanel.getEmailButton() ) )
		{
			enviarEmailConsulta();
		}
	}
	
	protected void enviarEmailConsulta()
	{
		MarcacaoTrabalhadorData consulta = ( MarcacaoTrabalhadorData ) marcacaoConsultaPanel.save();

		String subject = ( String ) Singleton.getInstance( SingletonConstants.SUBJECT_CONSULTA );
		String texto = ( String ) Singleton.getInstance( SingletonConstants.LETTER_CONSULTA );
		
		Date today = new Date();
		marcacaoConsultaPanel.getEmailButton().setText( "Enviar email (" + DATE_FORMAT.format( today ) + ")" );
		
		try
		{
			enviarEmail( subject, texto, ( Date )consulta.get( MarcacaoTrabalhadorData.DATA ) );
			consulta.set( Marcacao.DATA_EMAIL, today );
		}
		catch( Exception ex )
		{
			DialogException.showExceptionMessage( ex, "Erro a enviar mail", true );
		}
	}
	
	protected void enviarEmailExame()
	{
		MarcacaoTrabalhadorData exame = ( MarcacaoTrabalhadorData ) marcacaoExamePanel.save();
		
		String subject = ( String ) Singleton.getInstance( SingletonConstants.SUBJECT_EXAMES );
		String texto = ( String ) Singleton.getInstance( SingletonConstants.LETTER_EXAMES );
		
		Date today = new Date();
		marcacaoExamePanel.getEmailButton().setText( "Enviar email (" + DATE_FORMAT.format( today ) + ")" );
		
		try
		{
			enviarEmail( subject, texto, ( Date )exame.get( MarcacaoTrabalhadorData.DATA ) );
			exame.set( Marcacao.DATA_EMAIL, today );
		}
		catch( Exception ex )
		{
			DialogException.showExceptionMessage( ex, "Erro a enviar mail", true );
		}
	}
	
	protected void enviarEmail( String subject, String texto, Date data )
		throws Exception
	{
		String nome = ( String ) trabalhador.get( TrabalhadorData.NOME );
		String dataStr = DATE_FORMAT.format( data );
		
		subject = subject.replaceAll( CompanyDataLoader.NOME, nome );
		texto = texto.replaceAll( CompanyDataLoader.DATA, dataStr );
		texto = texto.replaceAll( CompanyDataLoader.NOME, nome );
		
		EstabelecimentoData estabelecimento = 
				( EstabelecimentoData ) JDO.load( EstabelecimentoData.class, estabelecimentoID );
		ContactoData contacto = ( ContactoData )estabelecimento.get( EstabelecimentoData.CONTACTO );
		String mail = "";
		if( contacto != null )
		{
			mail = ( String )contacto.get( ContactoData.EMAIL );
		}
		
		if( System.getProperty( "os.name" ).startsWith( "Windows" ) )
		{
			mail = mail.replaceAll( " ", "%20" );
			subject = subject.replaceAll( " ", "%20" );
			texto = texto.replaceAll( " ", "%20" );
			Process proc = Runtime.getRuntime().exec( "cmd.exe /c start mailto:\"" + mail 
				+ "?subject=" + subject + "&body="

				+ texto
				 );
		}
		else
		{
			mail = mail.replaceAll( " ", "%20" );
			subject = subject.replaceAll( " ", "%20" );
			texto = texto.replaceAll( " ", "%20" );

			Process proc = Runtime.getRuntime().exec( new String[]{ "/usr/bin/open", "/Applications/Mail.app", "mailto:" + mail 
				+ "?subject=" + subject + "&body="
				+ texto } );
		}
	}
	
	public void valueChanged( ListSelectionEvent e )
	{
		Object source = e.getSource();
		if( source.equals( upperPanel ) )
		{
			Integer ids[] = ( Integer [] ) upperPanel.save();
			empresaID = ids[ 0 ];
			estabelecimentoID = ids[ 1 ];
			trabalhadorID = ids[ 2 ];
			if( ids[ 2 ] == null )
			{
				clear( INDEX_MAIN );
				unselect( INDEX_MAIN ); 
			}
			else
			{
				reload( INDEX_MAIN );
				select( INDEX_MAIN );
			}
		}
	}
	
	public void setEmpresaAndEstabelecimentoAndTrabalhador( Integer empresaID, Integer estabelecimentoID, Integer trabalhadorID )
	{
		if( upperPanel.editing )
		{
			JOptionPane.showMessageDialog( this, "Esta janela est\u00e1 em edi\u00e7\u00e3o.", "Erro...",
					JOptionPane.ERROR_MESSAGE );
		}
		else
		{
			upperPanel.fill( new Integer[]{ empresaID, estabelecimentoID, trabalhadorID } );
		}
	}
	
	public void setTracker( SIPRPTracker tracker )
	{
		this.tracker = tracker;
	}
}
