/*
 * doGetListaTrabalhadoresPendentes.java
 *
 * Created on 22 de Abril de 2005, 15:56
 */

package siprp.pagina;

import java.io.*;
import java.lang.reflect.Array;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import java.util.*;

import org.apache.velocity.*;
import org.apache.velocity.app.*;

import com.evolute.utils.arrays.*;
import com.evolute.utils.data.*;
import com.evolute.utils.db.*;
import com.evolute.utils.sql.*;
import com.evolute.utils.strings.*;

/**
 *
 * @author  fpalma
 */
public class doGetListaTrabalhadoresPendentes
	extends siprpServlet
{
	private static final long TRES_MESES = 3L * 30L * 24L * 60L * 60L * 1000L;
	private static final long CATORZE_DIAS = 14L * 24L * 60L * 60L * 1000L;
	
	protected static final int ESTADO_NAO_APLICAVEL = 0;
	protected static final int ESTADO_PENDENTE = 1;
	protected static final int ESTADO_MARCADO = 2;
	protected static final int ESTADO_TRATADO = 3;
	
	protected static int MOTIVO_ADMISSAO = 1;
	protected static int MOTIVO_PERIODICA = 2;
	protected static int MOTIVO_OCASIONAL = 3;
	protected static int MOTIVO_PERIODICA_INICIAL = 5;
	
	protected static final Hashtable CORES_ESTADOS = new Hashtable();
	protected static final Hashtable TEXTOS_ESTADOS = new Hashtable();
	static
	{
		CORES_ESTADOS.put( new Integer( ESTADO_NAO_APLICAVEL ), "white" );
		CORES_ESTADOS.put( new Integer( ESTADO_PENDENTE ), "red" );
		CORES_ESTADOS.put( new Integer( ESTADO_MARCADO ), "yellow" );
		CORES_ESTADOS.put( new Integer( ESTADO_TRATADO ), "green" );
		
		TEXTOS_ESTADOS.put( new Integer( ESTADO_NAO_APLICAVEL ), "n.a." );
		TEXTOS_ESTADOS.put( new Integer( ESTADO_PENDENTE ), "pendente" );
		TEXTOS_ESTADOS.put( new Integer( ESTADO_MARCADO ), "pendente" );
//		TEXTOS_ESTADOS.put( new Integer( ESTADO_TRATADO ), "green" );
	}
	
	protected java.sql.Date today;
	protected long todayMillis;

	/** Creates a new instance of doGetListaTrabalhadores */
//	public doGetListaTrabalhadoresPendentes(HttpServletRequest req, HttpServletResponse res, boolean print)
//		throws IOException
//	{
//		ServletOutputStream out = res.getOutputStream();
//		Connection con = null ;
//		Statement stmt = null ;
//		ResultSet2DArray rs;
//		StringBuffer dbQuery, sBuffer;
//		String userRole, empresaId, estabelecimentoId, temp;
//		HttpSession session = req.getSession(false);
//		Vector links = new Vector();
//		Vector desc = new Vector();
//		Vector descAdicional = new Vector();
////		today = new java.util.Date();
////		todayMillis = today.getTime();
//
//		try
//		{   
//			stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
//			rs = new ResultSet2DArray( stmt.executeQuery( "SELECT CURRENT_DATE" ) );
//			today = ( java.sql.Date ) rs.get( 0, 0 );
//			stmt.close();
//			todayMillis = today.getTime();
//					
//			userRole = (String)session.getAttribute(super.sessionUserRole);
//			empresaId = (String)session.getAttribute(super.sessionEmpresaId);
//			estabelecimentoId = (String)session.getAttribute(super.sessionEstabelecimentoId);
//
//			if ( userRole.equals ( super.superUserRole ) || userRole.equals ( empresaId )  )
//			{
//				Class.forName(super.bdDriver);
//				con = DriverManager.getConnection( bdLocalUrl, bdLocalUsername, bdLocalPassword );   
//				if ( super.verificaEstabelecimento(con, empresaId, estabelecimentoId) ) // estabelecimento pertence a empresa ??
//				{
//					//Class.forName(super.bdDriver);
//					//con = DriverManager.getConnection( super.bdUrl, super.bdUsername, super.bdPassword );   
//					dbQuery = new StringBuffer();
//					dbQuery.append( "SELECT trabalhadores.id, trabalhadores.nome, "
//					+ "marcacoes_trabalhador.tipo, marcacoes_trabalhador.data, marcacoes_trabalhador.estado, "
//					+ " trabalhadores.nome_plain, marcacoes_trabalhador.motivo "
//					+ "FROM trabalhadores LEFT JOIN marcacoes_trabalhador ON (  marcacoes_trabalhador.trabalhador_id = trabalhadores.id )"
//					+ "WHERE estabelecimento_id = " + estabelecimentoId
//					+ " AND trabalhadores.inactivo <> 'y' AND data_demissao IS NULL "
//					+ " AND marcacoes_trabalhador.estado NOT IN ( 3, 4, 5) "
//					+ "ORDER BY 6, 3, 4 DESC " );
//					//                        dbQuery.append( "SELECT id, nome, ( ultima_consulta IS NOT NULL AND realizada = 'y' ),"
//					//										+ " ( ultimo_exame IS NOT NULL AND realizado = 'y' ),"
//					//										+ " proxima_consulta IS NOT NULL, proximo_exame IS NOT NULL, "
//					//										+ " ( proxima_consulta IS NOT NULL AND proxima_consulta - current_date <= 14 ), "
//					//										+ " ( proximo_exame IS NOT NULL AND proximo_exame - current_date <= 14 )"
//					//										+ " FROM trabalhadores "
//					//										+ " WHERE estabelecimento_id = '"+estabelecimentoId+"'"
//					//										+ " AND ( ultima_consulta IS NULL OR realizada = 'n' OR"
//					//										+ " ( proxima_consulta IS NOT NULL AND proxima_consulta - current_date <= 14 )"
//					//										+ " OR ( proximo_exame IS NOT NULL AND proximo_exame - current_date <= 14 ) )"
//					//										+ " ORDER BY nome" );
//					stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
//					rs = new ResultSet2DArray( stmt.executeQuery( dbQuery.toString()) );
//
//					int index=0;
//					int max = rs.columnLength();
//
//					Integer trabalhadorID = new Integer( -1 );
//					String nomeTrabalhador = "";
//					Vector consultas = new Vector();
//					Vector exames = new Vector();
//
//					for ( index = 0; index <= max; index++ )
//					{
//						Integer id = index < max ? ( Integer ) rs.get( index, 0 ) : new Integer( -1 );
//						if( !id.equals( trabalhadorID ) )
//						{
//							Object listaConsultas[][] = ( Object[][] ) consultas.toArray( new Object[consultas.size()][3] );
//							Object listaExames[][] = ( Object[][] ) exames.toArray( new Object[exames.size()][3] );
//							if( trabalhadorID.intValue() > -1 &&
//								verificarTrabalhador( listaConsultas, listaExames ) )
//							{
//								temp=""+rs.get(index - 1,0); // converter de int para String
//								dbQuery = new StringBuffer();
//								dbQuery.append("/"+super.servletName+"/?"+empresaId+"/"+estabelecimentoId+"/"+temp); // contruir url
//								links.add(dbQuery.toString());
//								desc.add( criarDadosTrabalhador( con, trabalhadorID, nomeTrabalhador, listaConsultas, listaExames ) );
//							}
//							exames.clear();
//							consultas.clear();
//						}
//						if( index == max )
//						{
//							break;
//						}
//						Integer tipo = ( Integer ) rs.get( index, 2 );
//
//						String nome = ( String ) rs.get( index, 1 );
//						java.util.Date data = ( java.util.Date ) rs.get( index, 3 );
//						Integer estado = ( Integer ) rs.get( index, 4 );
//						Integer motivo = ( Integer ) rs.get( index, 6 );
//						trabalhadorID = id;
//						nomeTrabalhador = nome;
//						Object marcacao[] = new Object[]{ data, estado, motivo };
//						if( tipo == null )
//						{
//							continue;
//						}
//						switch( tipo.intValue() )
//						{
//							case TIPO_MARCACAO_EXAMES:
//							exames.add( marcacao );
//							break;
//
//							case TIPO_MARCACAO_CONSULTA:
//							consultas.add( marcacao );
//							break;
//						}
//					}
//					stmt.close();
//
//					sBuffer = new StringBuffer();
//					sBuffer.append("<b>"+super.nomeEmpresa(con,empresaId)+"</b><br><br><i>"
//					+super.nomeEstabelecimento(con, estabelecimentoId)+"</i>" );
//
//					HashMap hmValues = new HashMap();
//					hmValues.put( "empresa_nome", session.getAttribute( sessionCompanyName ) );
//					hmValues.put( "empresa_id", session.getAttribute( sessionEmpresaId ) );
//					hmValues.put( "estabelecimento_nome", super.nomeEstabelecimento( con, estabelecimentoId ) );
//					hmValues.put( "estabelecimento_id", estabelecimentoId );
//					hmValues.put( "userRole", userRole );
//					hmValues.put( "userName", session.getAttribute( sessionUser ) );
//					hmValues.put( msgTemplate , sBuffer.toString() ) ;
//					hmValues.put( templateUserRole, userRole);
//					hmValues.put( templateQuery, "trabalhadores_pendentes" );
//					hmValues.put( templateVector1,links);
//					hmValues.put( templateVector2,desc);
//					hmValues.put( templateVector3,null);
//					if( !print )
//					{
//						out.println( mergeTemplate( hmValues, super.authenticatedUserTemplate));  
//					}
//					else
//					{
//						out.println( mergeTemplate( hmValues, super.authenticatedUserPrintTemplate));  
//					}
////						out.println( mergeTemplate( sBuffer.toString(), userRole, super.queryStringTrabalhadores, links, desc, null, super.authenticatedUserTemplate) ); 
//				}
//				else  // est nao pertence 'a empresa
//				{
//					out.println( mergeTemplate( super.msgLinkFormatError , userRole, super.errorTemplate) );
//				}
//				con.close();
//			}
//			else // Role nao permite ver esta informacao
//			{
//				out.println( mergeTemplate( super.msgAcessoNegado , userRole,  super.errorTemplate) );
//			}
//		}
//		catch ( SQLException e )
//		{
//			e.printStackTrace();
//			out.println( mergeTemplate( super.msgErroBd , super.errorTemplate) );
//		}
//		catch ( Exception e )
//		{
//			e.printStackTrace();
//			out.println( mergeTemplate( super.msgGenericError , super.errorTemplate) );
//		}
//	}
	
	public doGetListaTrabalhadoresPendentes(HttpServletRequest req, HttpServletResponse res, boolean print )
		throws IOException
	{
		ServletOutputStream out = res.getOutputStream();
		String userRole, empresaId, estabelecimentoId;
		HttpSession session = req.getSession(false);
		Vector links = new Vector();
		Vector desc = new Vector();
		Vector descAdicional = new Vector();
//		today = new java.util.Date();
//		todayMillis = today.getTime();

		try
		{
			Executer executer = getExecuter();
			Virtual2DArray array = executer.executeQuery( new Select( "SELECT CURRENT_DATE" ) );
			today = ( java.sql.Date ) array.get( 0, 0 );
			todayMillis = today.getTime();
					
			userRole = (String)session.getAttribute(sessionUserRole);
			empresaId = (String)session.getAttribute(sessionEmpresaId);
			estabelecimentoId = (String)session.getAttribute(sessionEstabelecimentoId);

			if ( userRole.equals ( superUserRole ) || userRole.equals ( empresaId )  )
			{
				if ( verificaEstabelecimento(null, empresaId, estabelecimentoId) ) // estabelecimento pertence 'a empresa ??
				{
					//Class.forName(super.bdDriver);
					//con = DriverManager.getConnection( super.bdUrl, super.bdUsername, super.bdPassword );   
					String query = "( SELECT trabalhadores.id, trabalhadores.nome, "
						+ "marcacoes_trabalhador.tipo, marcacoes_trabalhador.data, marcacoes_trabalhador.estado, "
						+ " trabalhadores.nome_plain, marcacoes_trabalhador.motivo, marcacoes_trabalhador.data "
						+ "FROM trabalhadores LEFT JOIN marcacoes_trabalhador ON (  marcacoes_trabalhador.trabalhador_id = trabalhadores.id ) "
						+ "WHERE estabelecimento_id = " + estabelecimentoId
						+ " AND trabalhadores.inactivo <> 'y' AND data_demissao IS NULL "
						+ " AND marcacoes_trabalhador.estado NOT IN ( 3, 4, 5) "
						+ " AND marcacoes_trabalhador.tipo = " + TIPO_MARCACAO_CONSULTA
						+ " AND marcacoes_trabalhador.motivo <> " + MOTIVO_OCASIONAL + " )"
						+ " UNION "	
						+ "( SELECT trabalhadores.id, trabalhadores.nome, "
						+ "marcacoes_trabalhador.tipo, marcacoes_trabalhador.data, marcacoes_trabalhador.estado, "
						+ " trabalhadores.nome_plain, marcacoes_trabalhador.motivo, marcacoes_trabalhador.data + 90 "
						+ "FROM trabalhadores LEFT JOIN marcacoes_trabalhador ON (  marcacoes_trabalhador.trabalhador_id = trabalhadores.id ) "
						+ "WHERE estabelecimento_id = " + estabelecimentoId
						+ " AND trabalhadores.inactivo <> 'y' AND data_demissao IS NULL "
						+ " AND marcacoes_trabalhador.estado NOT IN ( 3, 4, 5) "
						+ " AND marcacoes_trabalhador.tipo = " + TIPO_MARCACAO_EXAMES + " )"
						+ "ORDER BY 6, 8, 3 DESC ";
					array = executer.executeQuery( new Select( query ) );

					query = "SELECT trabalhadores.id, trabalhadores.nome, "
						+ "marcacoes_trabalhador.tipo, marcacoes_trabalhador.data, marcacoes_trabalhador.estado, "
						+ " trabalhadores.nome_plain, marcacoes_trabalhador.motivo, marcacoes_trabalhador.data "
						+ "FROM trabalhadores LEFT JOIN marcacoes_trabalhador ON (  marcacoes_trabalhador.trabalhador_id = trabalhadores.id ) "
						+ "WHERE estabelecimento_id = " + estabelecimentoId
						+ " AND trabalhadores.inactivo <> 'y' AND data_demissao IS NULL "
						+ " AND marcacoes_trabalhador.estado NOT IN ( 3, 4, 5) "
						+ " AND marcacoes_trabalhador.tipo = " + TIPO_MARCACAO_CONSULTA
						+ " AND marcacoes_trabalhador.motivo = " + MOTIVO_OCASIONAL
						+ " ORDER BY 6, 8, 3 DESC";
					Virtual2DArray ocasionaisArray = executer.executeQuery( new Select( query ) );
					
					query = "SELECT trabalhadores.id, trabalhadores.nome "
							+ "FROM trabalhadores "
							+ "WHERE estabelecimento_id = " + estabelecimentoId
							+ " AND trabalhadores.inactivo <> 'y' AND data_demissao IS NULL;";
					Virtual2DArray trabalhadoresArray = executer.executeQuery( new Select( query ) );
					
					Hashtable marcacoesPorID = new Hashtable();
					Hashtable ocasionaisPorID = new Hashtable();
					Hashtable nomesPorID = new Hashtable();
					for( int n = 0; n < trabalhadoresArray.columnLength(); n++ )
					{
						nomesPorID.put( trabalhadoresArray.get( n, 0 ), trabalhadoresArray.get( n, 1 ) );
					}

					preencherMarcacoes( array, nomesPorID, marcacoesPorID );
					preencherMarcacoes( ocasionaisArray, nomesPorID, ocasionaisPorID );
					
					Integer ids[] = ( Integer[] ) nomesPorID.keySet().toArray( new Integer[0] );
					IDObject trabalhadores[] = new IDObject[ ids.length ];
					for( int n = 0; n < ids.length; n++ )
					{
						trabalhadores[ n ] = new MappableObject( ids[ n ], nomesPorID.get( ids[ n ] ) );
					}
					Arrays.sort( trabalhadores, new Comparator(){
						public int compare( Object o1, Object o2 )
						{
							String nome1 = StringPlainer.convertString( o1.toString() );
							String nome2 = StringPlainer.convertString( o2.toString() );
							return nome1.compareTo( nome2 );
						}
					} );
					
					for( int n = 0; n < trabalhadores.length; n++ )
					{
						Object marcacoes[][];
						if( marcacoesPorID.containsKey( trabalhadores[ n ].getID() ) )
						{
							marcacoes = ( Object[][] ) ( ( Vector )marcacoesPorID.get( trabalhadores[ n ].getID() ) ).toArray( new Object[ 0 ][] );
						}
						else
						{
							marcacoes = new Object[0][];
						}
						Object ocasionais[][];
						if( ocasionaisPorID.containsKey( trabalhadores[ n ].getID() ) )
						{
							ocasionais = ( Object[][] ) ( ( Vector )ocasionaisPorID.get( trabalhadores[ n ].getID() ) ).toArray( new Object[ 0 ][] );
						}
						else
						{
							ocasionais = new Object[ 0 ][];
						}
						Object agrupadas[][] = agruparMarcacoes( marcacoes, ocasionais );
						acrescentarTrabalhador( empresaId, estabelecimentoId,
												trabalhadores[ n ], null, 
												agrupadas, links, desc,
												perfilTemConsultas( trabalhadores[ n ].getID(), new Integer( empresaId ) ), 
												perfilTemExames( trabalhadores[ n ].getID(), new Integer( empresaId ) ) );
					}
										
					HashMap hmValues = new HashMap();
					hmValues.put( "empresa_nome", session.getAttribute( sessionCompanyName ) );
					hmValues.put( "empresa_id", session.getAttribute( sessionEmpresaId ) );
					hmValues.put( "estabelecimento_nome", nomeEstabelecimento( null, estabelecimentoId ) );
					hmValues.put( "estabelecimento_id", estabelecimentoId );
					hmValues.put( "userRole", userRole );
					hmValues.put( "userName", session.getAttribute( sessionUser ) );
					hmValues.put( msgTemplate , "<b>"+nomeEmpresa(null,empresaId)+"</b><br><br><i>"
						+nomeEstabelecimento(null, estabelecimentoId)+"</i>"  ) ;
					hmValues.put( templateUserRole, userRole);
					hmValues.put( templateQuery, "trabalhadores_pendentes" );
					hmValues.put( templateVector1,links);
					hmValues.put( templateVector2,desc);
					hmValues.put( templateVector3,null);
					if( !print )
					{
						out.println( mergeTemplate( hmValues, super.authenticatedUserTemplate));  
					}
					else
					{
						out.println( mergeTemplate( hmValues, super.authenticatedUserPrintTemplate));  
					}
//						out.println( mergeTemplate( sBuffer.toString(), userRole, super.queryStringTrabalhadores, links, desc, null, super.authenticatedUserTemplate) ); 
				}
				else  // est nao pertence 'a empresa
				{
					out.println( mergeTemplate( super.msgLinkFormatError , userRole, super.errorTemplate) );
				}
			}
			else // Role nao permite ver esta informacao
			{
				out.println( mergeTemplate( super.msgAcessoNegado , userRole,  super.errorTemplate) );
			}
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			out.println( mergeTemplate( super.msgErroBd , super.errorTemplate) );
		}
		catch ( Exception e )
		{
			e.printStackTrace();
			out.println( mergeTemplate( super.msgGenericError , super.errorTemplate) );
		}
	}
	
	protected void preencherMarcacoes( Virtual2DArray array, Hashtable nomesPorID, Hashtable marcacoesPorID )
	{
		int max = array.columnLength();
		for( int index = 0; index < max; index++ )
		{
			Integer id = index < max ? ( Integer ) array.get( index, 0 ) : new Integer( -1 );
			Integer tipo = ( Integer ) array.get( index, 2 );
			String nome = ( String ) array.get( index, 1 );
			java.util.Date data = ( java.util.Date ) array.get( index, 3 );
			Integer estado = ( Integer ) array.get( index, 4 );
			Integer motivo = ( Integer ) array.get( index, 6 );
			if( !marcacoesPorID.containsKey( id ) )
			{
				nomesPorID.put( id, nome );
				marcacoesPorID.put( id, new Vector() );
			}
			if( data != null )
			{
				Object marcacao[] = new Object[]{ data, estado, motivo, tipo };
				( ( Vector ) marcacoesPorID.get( id ) ).add( marcacao );
			}
		}
	}
	
	protected Object[][] agruparMarcacoes( Object marcacoes[][], Object ocasionais[][] )
	{
		long tresMeses = TRES_MESES;
		java.util.Date dataExame = null;
		Integer estadoExame = null;
		java.util.Date dataConsulta = null;
		Integer motivoConsulta = null;
		Integer estadoConsulta = null;
		Object grupo[] = null;
		Vector grupos = new Vector();
		
		if( marcacoes != null )
		{
			for( int n = 0; n < marcacoes.length; n++ )
			{
				if( grupo == null )
				{
					grupo = new Object[ 5 ];
					dataExame = null;
					estadoExame = null;
					dataConsulta = null;
					motivoConsulta = null;
					estadoConsulta = null;
					grupos.add( grupo );
				}

				java.util.Date data = ( java.util.Date ) marcacoes[ n ][ 0 ];
				Integer estado = ( Integer ) marcacoes[ n ][ 1 ];
				Integer motivo = ( Integer ) marcacoes[ n ][ 2 ];
				Integer tipo = ( Integer ) marcacoes[ n ][ 3 ];
				switch( tipo.intValue() )
				{
					case TIPO_MARCACAO_EXAMES:
						if( dataConsulta == null && 
								( dataExame == null || estadoExame.intValue() < 2 ) )
						{
							dataExame = data;
							estadoExame = estado;
						}
						else if( dataConsulta != null && Math.abs( dataConsulta.getTime() - data.getTime() ) < tresMeses )
						{
							dataExame = data;
							estadoExame = estado;
						}
						else
						{
							grupo = null;
							n--;
						}
						if( grupo != null )
						{
							grupo[ 3 ] = dataExame;
							grupo[ 4 ] = estadoExame;
						}
						break;

					case TIPO_MARCACAO_CONSULTA:
						if( dataExame == null || Math.abs( dataExame.getTime() - data.getTime() ) < tresMeses )
						{
							dataConsulta = data;
							estadoConsulta = estado;
							motivoConsulta = motivo;
						}
						else
						{
							grupo = null;
							n--;
						}
						if( grupo != null )
						{
							grupo[ 0 ] = dataConsulta;
							grupo[ 1 ] = estadoConsulta;
							grupo[ 2 ] = motivoConsulta;
						}
						break;
				}
			}
		}
		if( ocasionais != null )
		{
			for( int n = 0; n < ocasionais.length; n++ )
			{
				grupo = new Object[ 5 ];
				for( int i = 0; i < 3; i++ )
				{
					grupo[ i ] = ocasionais[ n ][ i ];
				}
				grupos.add( grupo );
			}
		}
		
		Object agrupadas[][] = ( Object[][] ) grupos.toArray( new Object[ grupos.size() ][] );
		Arrays.sort( agrupadas, new Comparator(){
			public int compare( Object o1, Object o2 )
			{
				Object g1[] = ( Object[] ) o1;
				Object g2[] = ( Object[] ) o2;
				java.util.Date d1 = ( java.util.Date ) ( g1[ 0 ] != null ? g1[ 0 ] : g1[ 3 ] );
				java.util.Date d2 = ( java.util.Date ) ( g2[ 0 ] != null ? g2[ 0 ] : g2[ 3 ] );
				return d2.compareTo( d1 );
			} 
		} );
		return agrupadas;
	}
	
	protected void acrescentarTrabalhador( String empresaID, String estabelecimentoID,
											IDObject trabalhador, java.util.Date dataFicha, 
											Object marcacoes[][], Vector links, Vector dados,
											boolean perfilConsultas, boolean perfilExames )
	{
		int estado[] = new int[ 2 ];
		int index = 0;
		boolean pendente = false;
		if( marcacoes.length == 0 )
		{
			estado[ 0 ] = perfilConsultas ? ESTADO_PENDENTE : ESTADO_NAO_APLICAVEL;
			estado[ 1 ] = perfilExames ? ESTADO_PENDENTE : ESTADO_NAO_APLICAVEL;
		}
		else
		{
			java.util.Date dataConsulta;
			java.util.Date dataExame;
			index = -1;
			for( ; index + 1 < marcacoes.length; index++ )
			{
				int n = index + 1;
				dataConsulta = ( java.util.Date ) marcacoes[ n ][ 0 ];
				dataExame = ( java.util.Date ) marcacoes[ n ][ 3 ];
				boolean temConsulta = dataConsulta != null;
				boolean consultaAntiga = temConsulta && dataConsulta.before( today );
				boolean temExame = dataExame != null;
				boolean exameAntigo = temExame && dataExame.before( today );
				
				if( ( temConsulta && consultaAntiga && temExame && exameAntigo ) ||
						( temConsulta && consultaAntiga && !temExame && !exameAntigo ) ||
						( !temConsulta && !consultaAntiga && temExame && exameAntigo ) )
				{
					break;
				}
			}
			if( index == -1 )
			{
				index = 0;
			}
//			else if( index < marcacoes.length - 1 )
//			{
//				index = 0;
//			}
			for( ; index < marcacoes.length; index++ )
			{
				dataConsulta = ( java.util.Date ) marcacoes[ index ][ 0 ];
				dataExame = ( java.util.Date ) marcacoes[ index ][ 3 ];
				boolean temConsulta = dataConsulta != null;
				long diffConsulta = temConsulta ? dataConsulta.getTime() - today.getTime() : 0;
				boolean temExame = dataExame != null;
				long diffExame = temExame ? dataExame.getTime() - today.getTime() : 0;
				if( ( temConsulta && diffConsulta < CATORZE_DIAS ) || ( temExame && diffExame < CATORZE_DIAS ) )
				{
					break;
				}
			}
			if( index >= marcacoes.length )
			{
				index = marcacoes.length - 1;
			}
			else
			{
				if( marcacoes.length > 1 )
				{
					dataConsulta = ( java.util.Date ) marcacoes[ index ][ 0 ];
					dataExame = ( java.util.Date ) marcacoes[ index ][ 3 ];
					Calendar calToday = Calendar.getInstance();
					calToday.setTime( today );
					calToday.add( Calendar.YEAR, -2 );
					if( ( dataConsulta != null && dataConsulta.before( calToday.getTime() ) )
							|| ( dataConsulta == null && dataExame != null && dataExame.before( calToday.getTime() ) ) )
					{
						if( index > 0 )
						{
							index--;
						}
						else
						{
							pendente = true;
						}
					}
				}
			}
			dataConsulta = ( java.util.Date ) marcacoes[ index ][ 0 ];
			Integer estadoConsulta = ( Integer ) marcacoes[ index ][ 1 ];
			Integer motivoConsulta = ( Integer ) marcacoes[ index ][ 2 ];
			dataExame = ( java.util.Date ) marcacoes[ index ][ 3 ];
			Integer estadoExame = ( Integer ) marcacoes[ index ][ 4 ];
			if( perfilConsultas )
			{
				if( dataConsulta == null || pendente )
				{
					estado[ 0 ] = ESTADO_PENDENTE;
				}
				else if( estadoConsulta == null || estadoConsulta.intValue() != 2 )
				{
					estado[ 0 ] = ESTADO_MARCADO;
				}
				else
				{
					estado[ 0 ] = ESTADO_TRATADO;
				}
			}
			else
			{
				estado[ 0 ] = ESTADO_NAO_APLICAVEL;
			}
			if( perfilExames )
			{
				if( dataExame == null || pendente )
				{
					if( motivoConsulta != null && motivoConsulta.intValue() != MOTIVO_OCASIONAL )
					{
						estado[ 1 ] = ESTADO_PENDENTE;
					}
					else
					{
						estado[ 1 ] = ESTADO_NAO_APLICAVEL;
					}
				}
				else if( estadoExame == null || estadoExame.intValue() != 2 )
				{
					estado[ 1 ] = ESTADO_MARCADO;
				}
				else
				{
					estado[ 1 ] = ESTADO_TRATADO;
				}
			}
			else
			{
				estado[ 1 ] = ESTADO_NAO_APLICAVEL;
			}
		}
		if( estado[ 0 ] == 1 || estado[ 0 ] == 2 ||
				estado[ 1 ] == 1 || estado[ 1 ] == 2 )
		{
			links.add( "/"+servletName+"/?"+empresaID+"/"+estabelecimentoID+"/"+trabalhador.getID() );
			HashMap dadosTrabalhador = new HashMap();
			dadosTrabalhador.put( "Nome", trabalhador.toString() );
			dadosTrabalhador.put( "Consulta", CORES_ESTADOS.get( new Integer( estado[ 0 ] ) ) );
			Object text = TEXTOS_ESTADOS.get( new Integer( estado[ 0 ] ) );
			dadosTrabalhador.put( "Consulta_estado", text != null ? text : marcacoes[ index ][ 0 ] );
			dadosTrabalhador.put( "Exame", CORES_ESTADOS.get( new Integer( estado[ 1 ] ) ) );
			text = TEXTOS_ESTADOS.get( new Integer( estado[ 1 ] ) );
			dadosTrabalhador.put( "Exame_estado", text != null ? text : marcacoes[ index ][ 3 ] );
			dados.add( dadosTrabalhador );
		}
	}
	
	protected boolean perfilTemConsultas( Integer trabalhadorID, Integer empresaID )
		throws Exception
	{
		Executer executer = getExecuter();
		String query = "SELECT a_consultas, b_consultas FROM empresas WHERE id = " + empresaID;
		Virtual2DArray array = executer.executeQuery( new Select( query ) );
		boolean consultas[] = new boolean[]{ "y".equals( array.get( 0, 0 ) ), "n".equals( array.get( 0, 0 ) ) };
		query = "SELECT perfil FROM trabalhadores WHERE id = " + trabalhadorID;
		array = executer.executeQuery( new Select( query ) );
		Integer perfil = ( Integer )array.get( 0, 0 );
		if( perfil != null )
		{
			return consultas[ perfil.intValue() - 1 ];
		}
		else
		{
			return false;
		}
	}
	
	protected boolean perfilTemExames( Integer trabalhadorID, Integer empresaID )
		throws Exception
	{
		Executer executer = getExecuter();
		String query = "SELECT a_exames, b_exames FROM empresas WHERE id = " + empresaID;
		Virtual2DArray array = executer.executeQuery( new Select( query ) );
		boolean consultas[] = new boolean[]{ "y".equals( array.get( 0, 0 ) ), "n".equals( array.get( 0, 0 ) ) };
		query = "SELECT perfil FROM trabalhadores WHERE id = " + trabalhadorID;
		array = executer.executeQuery( new Select( query ) );
		Integer perfil = ( Integer )array.get( 0, 0 );
		if( perfil != null )
		{
			return consultas[ perfil.intValue() - 1 ];
		}
		else
		{
			return false;
		}
	}
	
//	protected boolean verificarTrabalhador( Object consultas[][], Object exames[][] )
//	{
//		boolean estadoConsultas = false;
//		boolean estadoExames = ( exames.length == 0 ) || ( ( java.util.Date )exames[ 0 ][ 0 ] ).before(today) ||
//		( ( ( ( java.util.Date )exames[ 0 ][ 0 ] ).getTime() - todayMillis ) / 86400000 > 14 );
//		if( consultas.length > 0 )
//		{
//			int anterior;
//			int proxima;
//			if( ( (java.util.Date) consultas[ 0 ][ 0 ] ).after( today ) )
//			{
//				proxima = 0;
//				if( consultas.length >= 2 )
//				{
//					anterior = 1;
//				}
//				else
//				{
//					anterior = -1;
//				}
//			}
//			else
//			{
//				proxima = -1;
//				anterior = 0;
//			}
//			estadoConsultas = anterior >= 0 && "y".equals( consultas[ anterior ][ 1 ] ) &&
//			( proxima == -1 || ( ( ( java.util.Date )consultas[ proxima ][ 0 ] ).getTime() - todayMillis ) / 86400000 > 14 );
//		}
//		return !(estadoConsultas && estadoExames);
//	}

//	protected HashMap criarDadosTrabalhador( Integer id, String nome, 
//												Object consultas[][], Object exames[][] )
//		throws Exception
//	{
////		dbQuery.append( "SELECT id, nome, ( ultima_consulta IS NOT NULL AND realizada = 'y' ),"
////							+ " ( ultimo_exame IS NOT NULL AND realizado = 'y' ),"
////							+ " proxima_consulta IS NOT NULL, proximo_exame IS NOT NULL, "
////							+ " ( proxima_consulta IS NOT NULL AND proxima_consulta - current_date <= 14 ), "
////							+ " ( proximo_exame IS NOT NULL AND proximo_exame - current_date <= 14 )"
////							+ " FROM trabalhadores "
////							+ " WHERE estabelecimento_id = '"+estabelecimentoId+"'"
////							+ " AND ( ultima_consulta IS NULL OR realizada = 'n' OR"
////							+ " ( proxima_consulta IS NOT NULL AND proxima_consulta - current_date <= 14 )"
////							+ " OR ( proximo_exame IS NOT NULL AND proximo_exame - current_date <= 14 ) )"
////							+ " ORDER BY nome" );
//		HashMap trabalhador = new HashMap();
//		trabalhador.put( "Nome", nome );
//		boolean  uc = false;
//		boolean  ue = false;
//		boolean  pc = false;
//		boolean  pe = false;
//		boolean quase_c = false;
//		boolean quase_e = false;
//		java.util.Date consultaAnterior = null;
//		java.util.Date exameAnterior = null;
//		if( consultas.length > 0 )
//		{
//			int anterior;
//			int proxima;
//			if( ( (java.util.Date) consultas[ 0 ][ 0 ] ).after( today ) )
//			{
//				proxima = 0;
//				if( consultas.length >= 2 )
//				{
//					anterior = 1;
//				}
//				else
//				{
//					anterior = -1;
//				}
//			}
//			else
//			{
//				proxima = -1;
//				anterior = 0;
//			}
//			long diff = proxima > -1 ? ( ( ( java.util.Date )consultas[ proxima ][ 0 ] ).getTime() - todayMillis ) / 86400000 : 15;
//			uc = anterior > -1 && "y".equals( consultas[ anterior ][ 1 ] );
//			if( uc )
//			{
//				consultaAnterior = ( java.util.Date ) consultas[ anterior ][ 0 ];
//			}
//			pc = proxima > -1;
//			quase_c = pc && diff <= 14;
//		}
//
//		if( exames.length > 0 )
//		{
//			int anterior;
//			int proximo;
//			if( ( (java.util.Date) exames[ 0 ][ 0 ] ).after( today ) )
//			{
//				proximo = 0;
//				if( exames.length >= 2 )
//				{
//					anterior = 1;
//				}
//				else
//				{
//					anterior = -1;
//				}
//			}
//			else
//			{
//				proximo = -1;
//				anterior = 0;
//			}
//			long diff = proximo > -1 ? ( ( ( java.util.Date )exames[ proximo ][ 0 ] ).getTime() - todayMillis ) / 86400000 : 15;
//			ue = anterior > -1 && "y".equals( exames[ anterior ][ 1 ] );
//			if( ue )
//			{
//				exameAnterior = ( java.util.Date ) exames[ anterior ][ 0 ];
//			}
//			pe = proximo > -1;
//			quase_e = pe && diff <= 14;
//		}
//
//		if( quase_c )
//		{
//			trabalhador.put( "Consulta", "yellow" );
//			trabalhador.put( "Consulta_estado", "pendente" );
//		}
//		else if( uc )
//		{
//			trabalhador.put( "Consulta", "green" );
//			trabalhador.put( "Consulta_estado", consultaAnterior );
//		}
//		else if( pc )
//		{
//			trabalhador.put( "Consulta", "yellow" );
//			trabalhador.put( "Consulta_estado", "pendente" );
//		}
//		else
//		{
//			trabalhador.put( "Consulta", "red" );
//			trabalhador.put( "Consulta_estado", "pendente" );
//		}
//
//		if( quase_e )
//		{
//			trabalhador.put( "Exame", "yellow" );
//			trabalhador.put( "Exame_estado", "pendente" );
//		}
//		else if( ue )
//		{
//			trabalhador.put( "Exame", "green" );
//			trabalhador.put( "Exame_estado", exameAnterior );
//		}
//		else if( pe )
//		{
//			trabalhador.put( "Exame", "yellow" );
//			trabalhador.put( "Exame_estado", "pendente" );
//		}
//		else
//		{
//			trabalhador.put( "Exame", "red" );
//			trabalhador.put( "Exame_estado", "pendente" );
//		}
//		return trabalhador;
//	}
}
