/*
 * ExamePanel.java
 *
 * Created on 29 de Marco de 2004, 11:57
 */

package siprp.ficha;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionListener;

import siprp.FichaDataProvider;
import siprp.MedicinaConstants;
import siprp.SingletonConstants;
import siprp.data.DisableDeleteHandler;
import siprp.data.ExameData;
import siprp.data.Marcacao;
import siprp.data.MarcacaoTrabalhadorData;

import com.evolute.utils.Singleton;
import com.evolute.utils.data.IDObject;
import com.evolute.utils.data.MappableObject;
import com.evolute.utils.dataui.ComponentController;
import com.evolute.utils.dataui.ComponentsHashtable;
import com.evolute.utils.dataui.ControllableComponent;
import com.evolute.utils.documents.MaximumLengthDocument;
import com.evolute.utils.jdo.JDOProvider;
import com.evolute.utils.ui.button.BetterButtonGroup;
import com.evolute.utils.ui.calendar.JCalendarPanel;
import com.evolute.utils.ui.panel.RadioButtonFixedPanel;
import com.evolute.utils.ui.text.CopyPasteHandler;
/**
 *
 * @author  fpalma
 */
public class ExamePanel extends JPanel
	implements ChangeListener, ControllableComponent, ListSelectionListener
{
	static
	{
		ExameData.registerOperationHandlerForClass( DisableDeleteHandler.INSTANCE, ExameData.class );
	}
	private JDOProvider JDO;
	
	
	private JCalendarPanel dataExamePanel;
	private BetterButtonGroup tipoGroup;
	private JRadioButton admissaoRadio;
	private JRadioButton periodicoRadio;
	private JRadioButton ocasionalRadio;
//	private JRadioButton outroRadio;
	private RadioButtonFixedPanel ocasionalPanel;
	private JTextField especificarText;
	private RadioButtonFixedPanel tipoProximoPanel;
	private JCalendarPanel proximoExamePanel;
	private RadioButtonFixedPanel resultadoPanel;
	private JTextField outrasFuncoesTexts[];
	private JTextArea recomendacoesText;
	
	private FichaDataProvider provider;
	private ComponentsHashtable components;
	
	private Integer trabalhadorID;
	private MarcacaoTrabalhadorData marcacao; 
	
	/** Creates a new instance of ExamePanel */
	public ExamePanel()
		throws Exception
	{
		provider = (FichaDataProvider)FichaDataProvider.getProvider();
		JDO = ( JDOProvider ) Singleton.getInstance( Singleton.DEFAULT_JDO_PROVIDER );
		setupComponents();
		setupComponentsHashtable();
	}
	
	private void setupComponents()
	{
		setBorder( BorderFactory.createTitledBorder(
					BorderFactory.createEtchedBorder(),
					"Exame M\u00e9dico" ) );
		
		JPanel leftPanel = new JPanel();
		JPanel rightPanel = new JPanel();
		JPanel dataExameOuterPanel = new JPanel();
		JLabel dataExameLabel = new JLabel( "Data do Exame" );
		dataExamePanel = new JCalendarPanel( null );
		JPanel tipoPanel = new JPanel();
		tipoPanel.setBorder( BorderFactory.createTitledBorder( 
				BorderFactory.createEtchedBorder(), "Tipo" ) );
		tipoGroup = new BetterButtonGroup( false );
		admissaoRadio = new JRadioButton( "Admiss\u00e3o" );
		tipoGroup.add( admissaoRadio );
		periodicoRadio = new JRadioButton( "Peri\u00f3dico" );
		tipoGroup.add( periodicoRadio );
		ocasionalRadio = new JRadioButton( "Ocasional" );
		tipoGroup.add( ocasionalRadio );
		ocasionalRadio.addChangeListener( this );
//		outroRadio = new JRadioButton( "Outro" );
//		tipoGroup.add( outroRadio );
//		outroRadio.addChangeListener( this );
		ocasionalPanel = new RadioButtonFixedPanel(  
			new IDObject[]{ new MappableObject( new Integer( 1 ), "Ap\u00f3s doen\u00e7a" ), 
							new MappableObject( new Integer( 2 ), "Ap\u00f3s acidente" ),
							new MappableObject( new Integer( 3 ), "A pedido do trabalhador" ), 
							new MappableObject( new Integer( 4 ), "A pedido do servi\u00e7o" ),
							new MappableObject( new Integer( 5 ), "Por mudan\u00e7a de fun\u00e7\u00e3o" ),
							new MappableObject( new Integer( 6 ), "Por altera\u00e7\u00e3o das condi\u00e7\u00f5es de trabalho" ),
							new MappableObject( new Integer( 10 ), "Outro" ) },
			false );
		ocasionalPanel.addListSelectionListener( this );
		ocasionalPanel.setEnabled( false );
		especificarText = new JTextField();
		especificarText.setEnabled( false );
		JPanel proximoExameOuterPanel = new JPanel();
		proximoExameOuterPanel.setBorder( BorderFactory.createTitledBorder( 
					BorderFactory.createEtchedBorder(), "Pr\u00f3ximo Exame" ) );
		proximoExamePanel = new JCalendarPanel( null );
		tipoProximoPanel =  new RadioButtonFixedPanel(  
			new IDObject[]{ new MappableObject( new Integer( 2 ), "Peri\u00f3dico" ),
							new MappableObject( new Integer( 3 ), "Ocasional" ) },
			RadioButtonFixedPanel.ORIENTATION_HORIZONTAL, 1, 2, false );
//		JLabel proximoExameLabel = new JLabel( "Pr\u00f3ximo Exame" );
		
		JPanel resultadoOuterPanel = new JPanel();
		resultadoOuterPanel.setBorder( BorderFactory.createTitledBorder( 
				BorderFactory.createEtchedBorder(), "Resultado" ) );
		resultadoPanel = new RadioButtonFixedPanel(  
			new IDObject[]{ new MappableObject( new Integer( 1 ), "Apto" ), 
							new MappableObject( new Integer( 2 ), "Apto condicionalmente" ),
							new MappableObject( new Integer( 3 ), "Inapto temporariamente" ), 
							new MappableObject( new Integer( 4 ), "Inapto definitivamente" ) },
			false );
		JLabel outrasFuncoesLabel = new JLabel( "Outras fun\u00e7\u00f5es que pode desempenhar", JLabel.CENTER );
		JPanel outrasFuncoesPanel = new JPanel();
		JLabel outrasFuncoesLabels[] = new JLabel[ 4 ];
		outrasFuncoesTexts = new JTextField[ 4 ];
		for( int n = 0; n < 4; n++ )
		{
			outrasFuncoesLabels[ n ] = new JLabel( "" + ( n + 1 ) );
			outrasFuncoesTexts[ n ] = new JTextField();
		}
		JScrollPane recomendacoesScp = new JScrollPane();
		recomendacoesScp.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
		recomendacoesScp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
		recomendacoesText = new JTextArea();
		recomendacoesText.setLineWrap( true );
		recomendacoesText.setWrapStyleWord( true );
		recomendacoesText.setDocument( new MaximumLengthDocument( 300 ) );
		recomendacoesScp.setViewportView( recomendacoesText );
		recomendacoesScp.setBorder( BorderFactory.createTitledBorder( 
									BorderFactory.createEtchedBorder(),
									"Outras recomenda\u00e7\u00f5es" ) );
				
		setLayout( new GridLayout( 1, 2 ) );
		add( leftPanel );
		add( rightPanel );
		
		leftPanel.setLayout( new BorderLayout() );
		
		dataExameOuterPanel.setLayout( new BorderLayout() );
		dataExameOuterPanel.add( dataExameLabel, BorderLayout.WEST );
		dataExameOuterPanel.add( dataExamePanel, BorderLayout.CENTER );
		leftPanel.add( dataExameOuterPanel, BorderLayout.NORTH );
		leftPanel.add( tipoPanel, BorderLayout.CENTER );
		proximoExameOuterPanel.setLayout( new BorderLayout() );
//		proximoExameOuterPanel.add( proximoExameLabel, BorderLayout.WEST );
		proximoExameOuterPanel.add( proximoExamePanel, BorderLayout.CENTER );
		proximoExameOuterPanel.add( tipoProximoPanel, BorderLayout.SOUTH );
		if( ( ( Boolean ) Singleton.getInstance( SingletonConstants.FICHA_MARCA_EXAMES ) ).booleanValue() )
		{
			leftPanel.add( proximoExameOuterPanel, BorderLayout.SOUTH );
		}
		
		GridBagLayout gridbag = new GridBagLayout();
		tipoPanel.setLayout( gridbag );
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = new Insets( 0, 1, 0, 1 );
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.weighty = 0;
		constraints.gridheight = 1;
		constraints.weightx = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		
		gridbag.setConstraints( admissaoRadio, constraints );
		tipoPanel.add( admissaoRadio );
		
		gridbag.setConstraints( periodicoRadio, constraints );
		tipoPanel.add( periodicoRadio );
		
		gridbag.setConstraints( ocasionalRadio, constraints );
		tipoPanel.add( ocasionalRadio );
		
		constraints.weightx = 0.1;
		constraints.gridwidth = 1;
		JPanel pad = new JPanel();
		gridbag.setConstraints( pad, constraints );
		tipoPanel.add( pad );
		
		constraints.weightx = 0.9;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		gridbag.setConstraints( ocasionalPanel, constraints );
		tipoPanel.add( ocasionalPanel );
		
//		constraints.weightx = 0;
//		constraints.gridwidth = 1;
//		gridbag.setConstraints( outroRadio, constraints );
//		tipoPanel.add( outroRadio );
		
		constraints.weightx = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		gridbag.setConstraints( especificarText, constraints );
		tipoPanel.add( especificarText );
		
		
		gridbag = new GridBagLayout();
		rightPanel.setLayout( gridbag );
		constraints.fill = GridBagConstraints.BOTH;
		constraints.weightx = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.gridheight = 1;
		constraints.weighty = 0;
		
		gridbag.setConstraints( resultadoOuterPanel, constraints );
		rightPanel.add( resultadoOuterPanel );
		
		constraints.weightx = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		//constraints.gridheight = GridBagConstraints.REMAINDER;
		constraints.weighty = 1;
//		JPanel recomendacoesOuterPanel = new JPanel();
//		recomendacoesOuterPanel.setLayout( new GridLayout( 1, 1 ) );
//		recomendacoesOuterPanel.add( recomendacoesScp );
		gridbag.setConstraints( recomendacoesScp, constraints );
		rightPanel.add( recomendacoesScp );
		
		gridbag = new GridBagLayout();
		resultadoOuterPanel.setLayout( gridbag );
		constraints.weightx = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.gridheight = 1;
		constraints.weighty = 0;
		
		gridbag.setConstraints( resultadoPanel, constraints );
		resultadoOuterPanel.add( resultadoPanel );
		
		gridbag.setConstraints( outrasFuncoesLabel, constraints );
		resultadoOuterPanel.add( outrasFuncoesLabel );
		
		gridbag.setConstraints( outrasFuncoesPanel, constraints );
		resultadoOuterPanel.add( outrasFuncoesPanel );
		
		for( int n = 0; n < outrasFuncoesTexts.length; n++ )
		{
			constraints.weightx = 0.1;
			constraints.gridwidth = 1;
			pad = new JPanel();
			gridbag.setConstraints( pad, constraints );
			resultadoOuterPanel.add( pad );

			constraints.weightx = 0;
			gridbag.setConstraints( outrasFuncoesLabels[ n ], constraints );
			resultadoOuterPanel.add( outrasFuncoesLabels[ n ] );

			constraints.weightx = 1;
			constraints.gridwidth = GridBagConstraints.REMAINDER;
			gridbag.setConstraints( outrasFuncoesTexts[ n ], constraints );
			resultadoOuterPanel.add( outrasFuncoesTexts[ n ] );
			new CopyPasteHandler( outrasFuncoesTexts[ n ] );
		}
		
		new CopyPasteHandler( especificarText );
		new CopyPasteHandler( recomendacoesText );
	}
	
	private void setupComponentsHashtable()
	{
		components = new ComponentsHashtable();
		components.putDummy( ExameData.TIPO );
		components.putComponent( ExameData.DATA, dataExamePanel );
		components.putComponent( ExameData.OCASIONAL, ocasionalPanel );
		components.putComponent( ExameData.OUTRO_TIPO, especificarText );
		components.putComponent( ExameData.PROXIMO_EXAME, proximoExamePanel );
		components.putComponent( ExameData.RESULTADO, resultadoPanel );
		components.putComponent( ExameData.OUTRA_FUNCAO_1, outrasFuncoesTexts[ 0 ] );
		components.putComponent( ExameData.OUTRA_FUNCAO_2, outrasFuncoesTexts[ 1 ] );
		components.putComponent( ExameData.OUTRA_FUNCAO_3, outrasFuncoesTexts[ 2 ] );
		components.putComponent( ExameData.OUTRA_FUNCAO_4, outrasFuncoesTexts[ 3 ] );
		components.putComponent( ExameData.OUTRAS_RECOMENDACOES, recomendacoesText );
		components.putDummy( ExameData.INACTIVO );
		components.putDummy( ExameData.TRABALHADOR );
		components.putDummy( ExameData.MEDICO );
		components.putDummy( ExameData.PDF );
		components.putDummy( ExameData.FO );
	}
	
	public void stateChanged( ChangeEvent e ) 
	{
		if( e.getSource().equals( ocasionalRadio ) )
		{
			ocasionalPanel.setEnabled( ocasionalRadio.isSelected() && ocasionalRadio.isEnabled() ) ;
		}
//		else if( e.getSource().equals( outroRadio ) )
//		{
//			especificarText.setEnabled( outroRadio.isSelected() && outroRadio.isEnabled() );
//		}
	}
	
	
	public void fill( Object value )
	{
		clear();
		trabalhadorID = ( Integer ) value;
		if( trabalhadorID == null )
		{
			return;
		}
		try
		{
			Integer marcacaoID = provider.getMarcacaoIDByTrabalhador( trabalhadorID );
			
			if( marcacaoID != null )
			{
				marcacao = ( MarcacaoTrabalhadorData ) JDO.load( MarcacaoTrabalhadorData.class, marcacaoID );
				proximoExamePanel.setDate( (Date) marcacao.get( Marcacao.DATA ) );
			}
			Object dadosMarcacao[] = provider.getDadosUltimaMarcacao( trabalhadorID );
			if( dadosMarcacao != null )
			{
				dataExamePanel.setDate( ( Date ) dadosMarcacao[ 0 ] );
				Integer tipo = ( Integer ) dadosMarcacao[ 1 ];
				int tipoValue = tipo != null ? tipo.intValue() : 0;
				tipoGroup.setIntSelected( tipoValue > 0 ? tipoValue - 1 : 0 );
			}
			
		}
		catch( Exception ex )
		{
			ex.printStackTrace();
			return;
		}
		
//		Integer trabID = (Integer) value;
//		if( trabID == null )
//		{
//			return;
//		}
//		try
//		{
//			Integer id = provider.getLastExameIDForTrabalhador( trabID );
//			if( id == null )
//			{
//				return;
//			}
//			MetaObject exame = provider.load( provider.EXAMES, new DBKey( id ) );
//			byte pdf[] = (byte []) exame.getProperty( provider.PDF );
//			if( pdf != null )
//			{
//				FileOutputStream fos = new FileOutputStream( "C:\\teste.pdf" );
//				fos.write( pdf );
//				fos.close();
//			}
//		}
//		catch( Exception ex )
//		{
//			ex.printStackTrace();
//			return;
//		}
	}
	
	public Object save()
	{
		StringBuffer msg = new StringBuffer();
		boolean hasMsg = false;
		boolean hasData = false;
		ExameData exame;
		Date dataExame = dataExamePanel.getDate();
		if( dataExame == null )
		{
			dataExame = new Date();
		}
		Calendar cal = Calendar.getInstance();
		cal.add( Calendar.DAY_OF_MONTH, 1 );
		if( !cal.getTime().after( dataExame ) )
		{
			throw new ValuesException( "N\u00E3o \u00E9 poss\u00EDvel gravar exames com datas futuras." );
		}
		try
		{
			String recomendacoes = recomendacoesText.getText();
			String linhas[] = recomendacoes.split( "\\n" );
			Vector linhasV = new Vector();
			for( int n = 0; n < linhas.length; n++ )
			{
				if( linhas[ n ].trim().length() > 0 )
				{
					linhasV.add( linhas[ n ] );
				}
			}
			if( linhasV.size() > 0 )
			{
				linhas = ( String[] ) linhasV.toArray( new String[0] );
				boolean compress = false;
				if( linhas.length == 2 )
				{
					linhas[ 0 ] += " ";
				}
				recomendacoes = "";
				for( int n = 0; n < linhas.length; n++ )
				{
					recomendacoes += linhas[ n ];
				}
			}
			recomendacoesText.setText( recomendacoes.trim() );
			
//			exame = provider.createObject( FichaDataProvider.EXAMES );
			exame = new ExameData();
//			DBField fields[] = FichaDataProvider.EXAMES.getInsertFields();
//			String exameFields[] = new String[ fields.length ];
//			for( int i = 0; i < exameFields.length; ++i )
//			{
//				exameFields[ i ] = fields[ i ].FULL_NAME;
//			}
//			Hashtable hash = new Hashtable();
//			ComponentController.save( exameFields, hash, components );
//			hash.put( FichaDataProvider.T_EXAMES + "." + FichaDataProvider.INACTIVO, "n" );
//			Enumeration enum = hash.keys();
//			while( enum.hasMoreElements() )
//			{
//				String name = ( String )enum.nextElement();
//				exame.setProperty( name, hash.get( name ) );
//			}
			String names[] = exame.getFieldNames();
			Hashtable hash = new Hashtable();
			ComponentController.save( names, hash, components );
			exame.setHashData( hash );
			
			int tipo = 0;
			if( admissaoRadio.isSelected() )
			{
				tipo = 1;
			}
			else if( periodicoRadio.isSelected() )
			{
				tipo = 2;
			}
			else if( ocasionalRadio.isSelected() )
			{
				tipo = 3;
			}
//			else if( outroRadio.isSelected() )
//			{
//				tipo = 4;
//			}
//			exame.setProperty( FichaDataProvider.TIPO, new Integer( tipo ) );
			exame.set( ExameData.TIPO, new Integer( tipo ) );
			if( tipo != 3 )
			{
//				exame.setProperty( FichaDataProvider.EXAMES.getFieldByName( FichaDataProvider.OCASIONAL ).FULL_NAME, null );
				exame.set( ExameData.OCASIONAL, null );
//				exame.setProperty( FichaDataProvider.EXAMES.getFieldByName( FichaDataProvider.OUTRO_TIPO ).FULL_NAME, "" );
				exame.set( ExameData.OUTRO_TIPO, "" );
			}
			else
			{
				Integer ocasionalID = ( Integer )ocasionalPanel.save();
				if( ocasionalID == null || ocasionalID.intValue() != 10 )
				{
//					exame.setProperty( FichaDataProvider.EXAMES.getFieldByName( FichaDataProvider.OUTRO_TIPO ).FULL_NAME, "" );
					exame.set( ExameData.OUTRO_TIPO, "" );
				}
			}
		}
		catch( Exception ex )
		{
			ex.printStackTrace();
			return null;
		}
		if( hasMsg )
		{
			throw new ValuesException( msg.toString() );
		}
		return exame;
	}
	
	public void clear()
	{
		String names[] = (String[])components.keySet().toArray( new String[0] );
		ComponentController.clear( names, components );
		tipoGroup.setIntSelected( 0 );
		dataExamePanel.setDate( new Date() );
		tipoProximoPanel.setSelected( new Integer( 2 ) );
		marcacao = null;
	}

	public void setEnabled( boolean enable )
	{
		String names[] = (String[])components.keySet().toArray( new String[0] );
		ComponentController.setEnabled( names, enable, components );
		admissaoRadio.setEnabled( enable );
		periodicoRadio.setEnabled( enable );
		ocasionalRadio.setEnabled( enable );
//		outroRadio.setEnabled( enable );
		ocasionalPanel.setEnabled( ocasionalRadio.isSelected() && ocasionalRadio.isEnabled() ) ;
//		especificarText.setEnabled( outroRadio.isSelected() && outroRadio.isEnabled() );
		setEspecificarState();
	}
	
	public void valueChanged(javax.swing.event.ListSelectionEvent listSelectionEvent)
	{
		setEspecificarState();
	}
	
	public void setEspecificarState()
	{
		Integer id = ( Integer )ocasionalPanel.save();
		if( id != null && id.intValue() == 10 )
		{
			especificarText.setEnabled( ocasionalRadio.isSelected() && ocasionalRadio.isEnabled() );
		}
		else
		{
			especificarText.setEnabled( false );
		}
	}
	
	public Integer getMotivoProximoExame()
	{
		return tipoProximoPanel.getSelected();
	}
	
	public void setup( Date fichaDate, Integer motivoProcesso )
	{
		if( fichaDate != null )
		{
			dataExamePanel.setDate( fichaDate );
			Calendar proximo = Calendar.getInstance();
			proximo.setTime( fichaDate );
			proximo.add( Calendar.YEAR,  2 );
			proximoExamePanel.setDate( proximo.getTime() );
		}
		if( motivoProcesso != null )
		{
			switch( motivoProcesso.intValue() )
			{
			case MedicinaConstants.MOTIVO_ADMISSAO:
				admissaoRadio.setSelected( true );
				break;
			case MedicinaConstants.MOTIVO_PERIODICO:
				periodicoRadio.setSelected( true );
				break;
			case MedicinaConstants.MOTIVO_PERIODICO_INICIAL:
				periodicoRadio.setSelected( true );
				break;
			case MedicinaConstants.MOTIVO_OCASIONAL:
				ocasionalRadio.setSelected( true );
				break;
			}
		}
	}
}
