package siprp.planoactuacao.print;

import java.util.Date;
import java.util.Vector;

import siprp.planoactuacao.SingletonConstants;
import siprp.planoactuacao.db.PlanoActuacaoDBInit;

import com.evolute.utils.Singleton;
import com.evolute.utils.arrays.Virtual2DArray;
import com.evolute.utils.data.Mappable;
import com.evolute.utils.data.MappableObject;
import com.evolute.utils.db.DBManager;
import com.evolute.utils.db.Executer;
import com.evolute.utils.sql.Assignment;
import com.evolute.utils.sql.BlobUpdate;
import com.evolute.utils.sql.Expression;
import com.evolute.utils.sql.Field;
import com.evolute.utils.sql.Select;
import com.evolute.utils.sql.Select2;
import com.evolute.utils.sql.Update;


public class PlanoActuacaoPrintDataProvider
{
	private static final Object LOCK = new Object();
	private static PlanoActuacaoPrintDataProvider instance = null;
	
	protected final Executer WEB_EXECUTER;
	protected final Executer LOCAL_EXECUTER;
	
	public PlanoActuacaoPrintDataProvider()
		throws Exception
	{
		if( Singleton.getInstance( SingletonConstants.WEB_DBMANAGER ) == null )
		{
			PlanoActuacaoDBInit.initDB();
		}
		DBManager WEB_DBMANAGER = ( DBManager ) Singleton.getInstance( SingletonConstants.WEB_DBMANAGER );
		WEB_EXECUTER = WEB_DBMANAGER.getSharedExecuter( this );
		DBManager LOCAL_DBMANAGER = ( DBManager ) Singleton.getInstance( SingletonConstants.LOCAL_DBMANAGER );
		LOCAL_EXECUTER = LOCAL_DBMANAGER.getSharedExecuter( this );
	}
	
	public static PlanoActuacaoPrintDataProvider getProvider()
		throws Exception
	{
		synchronized( LOCK )
		{
			if( instance == null )
			{
				instance = new PlanoActuacaoPrintDataProvider();
			}
		}
		return instance;
	}
	
	public PlanoActuacaoToPrint getPlanoToPrint( Integer id )
		throws Exception
	{
		
		Select select = 
			new Select2( 
				new String[]{ "planos_actuacao" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "empresa_id", "nome_empresa", 
						"estabelecimento_id", "nome_estabelecimento", 
						"data_relatorio", "data_visita", "observacoes_dl", 
						"observacoes_dns", "validacao_director_loja", 
						"validacao_dns" },
				new Field( "id" ).isEqual( id ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = WEB_EXECUTER.executeQuery( select );
		Integer empresaId = ( Integer ) array.get( 0, 0 );
		String nomeEmpresa = ( String ) array.get( 0, 1 );
		Integer estabelecimentoId = ( Integer ) array.get( 0, 2 );
		String nomeEstabelecimento = ( String ) array.get( 0, 3 );
		Integer logoId = getLogotipoIdForEmpresaId( empresaId );
		Date dataRelatorio = ( Date ) array.get( 0, 4 );
		Date dataVisita = ( Date ) array.get( 0, 5 );
		String observacoesDl = ( String ) array.get( 0, 6 );
		String observacoesDns = ( String ) array.get( 0, 7 );
		Boolean validacaoDl = ( Boolean ) array.get( 0, 8 );
		Boolean validacaoDns = ( Boolean ) array.get( 0, 9 );
		EmpresaToPrint empresa = new EmpresaToPrint( nomeEmpresa,
				"http://www.evolute.pt:13080/SIPRPImages/image?id=" + logoId,
//				"http://apdp/siprp/auchan_jumbo_lado.jpg",
				nomeEstabelecimento );
		PlanoActuacaoToPrint plano = 
			new PlanoActuacaoToPrint( 
				empresa, 
				dataRelatorio != null ? new DataToPrint( "data-relatorio", dataRelatorio ) : null, 
				dataVisita != null ? new DataToPrint( "data-hs", dataVisita ) : null, 
				getLegislacaoAplicavel( empresaId, estabelecimentoId ), 
				getAreasToPrintByPlanoId( id, validacaoDl, validacaoDns ),
				observacoesDl,
				observacoesDns );
		return plano; 
	}
	
	public Integer getLogotipoIdForEmpresaId( Integer empresaId )
		throws Exception
	{
		Select select = 
			new Select2(
				new String[]{ "empresas" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "empresa_logo_id" },
				new Field( "id" ).isEqual( empresaId ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = LOCAL_EXECUTER.executeQuery( select );
		return ( Integer ) array.get( 0, 0 );
	}
	
	public LegislacaoAplicavelToPrint getLegislacaoAplicavel( Integer empresaId, Integer estabelecimentoId )
		throws Exception
	{
		LegislacaoAplicavelToPrint legislacao = new LegislacaoAplicavelToPrint( new Vector<String>() );
		return legislacao;
	}
	
	public Vector<AreaToPrint> getAreasToPrintByPlanoId( Integer planoId, boolean validacaoDl, boolean validacaoDns )
		throws Exception
	{
		Vector<AreaToPrint> areas = new Vector<AreaToPrint>();
		Select select = 
			new Select2( 
				new String[]{ "plano_areas" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id", "descricao" },
				new Field( "plano_id" ).isEqual( planoId ),
				new String[]{ "id" },
				null,
				null,
				null );
		Virtual2DArray array = WEB_EXECUTER.executeQuery( select );
		for( int n = 0; n < array.columnLength(); n++ )
		{
			Integer areaId = ( Integer ) array.get( n, 0 );
			String areaDescricao = ( String ) array.get( n, 1 );
			areas.add( new AreaToPrint( areaDescricao, getRiscosToPrintByAreaId( areaId, validacaoDl, validacaoDns ) ) );
		}
		return areas;
	}
	
	public Vector<RiscoToPrint> getRiscosToPrintByAreaId( Integer areaId, boolean validacaoDl, boolean validacaoDns )
		throws Exception
	{
		Vector<RiscoToPrint> riscos = new Vector<RiscoToPrint>();
		Select select = 
			new Select2( 
				new String[]{ "plano_riscos" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id", "descricao", "valor", "responsavel_execucao",
						"recursos_necessarios", "data_inicio", "data_fim",
						"parecer_dl", "parecer_dns", "verificacao_siprp"},
				new Field( "area_id" ).isEqual( areaId ).and( 
					new Field( "activo" ).isEqual( "y" ) ),
				new String[]{ "id" },
				null,
				null,
				null );
		Virtual2DArray array = WEB_EXECUTER.executeQuery( select );
		for( int n = 0; n < array.columnLength(); n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String descricao = ( String ) array.get( n, 1 );
			Integer valor = ( Integer ) array.get( n, 2 );
			String responsavelExecucao = ( String ) array.get( n, 3 );
			String recursosNecessarios = ( String ) array.get( n, 4 );
			Date dataInicio = ( Date ) array.get( n, 5 );
			Date dataFim = ( Date ) array.get( n, 6 );
			String parecerDl = ( String ) array.get( n, 7 );
			if( ( parecerDl == null || parecerDl.trim().length() == 0 )
					&& validacaoDl )
			{
				parecerDl = "De acordo";
			}
			String parecerDns = ( String ) array.get( n, 8 );
			if( ( parecerDns == null || parecerDns.trim().length() == 0 )
					&& validacaoDns )
			{
				parecerDns = "De acordo";
			}
			String verificacaoSiprp = ( String ) array.get( n, 9 );
			riscos.add(
				new RiscoToPrint( 
					descricao, 
					valor,
					getMedidasToPrintByRiscoId( id ), 
					responsavelExecucao, 
					recursosNecessarios,
					dataInicio != null ? new DataToPrint( "data-prevista-inicio", dataInicio ) : null, 
					dataFim != null ? new DataToPrint( "data-prevista-conclusao", dataFim ) : null,
					parecerDl, 
					parecerDns, 
					verificacaoSiprp ) );
		}
		return riscos;
	}
	
	public Vector<MedidaToPrint> getMedidasToPrintByRiscoId( Integer riscoId )
		throws Exception
	{
		Vector<MedidaToPrint> medidas = new Vector<MedidaToPrint>();
		Select select = 
			new Select2(
				new String[]{ "plano_medidas" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id", "descricao" },
				new Field( "risco_id" ).isEqual( riscoId ),
				new String[]{ "id" },
				null,
				null,
				null );
		Virtual2DArray array = WEB_EXECUTER.executeQuery( select );
		for( int n = 0; n < array.columnLength(); n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String descricao = ( String ) array.get( n, 1 );
			medidas.add( 
				new MedidaToPrint( 
					descricao,
					getPostosToPrintByMedidaId( id ) ) );
		}
		return medidas;
	}
	
	public Vector<PostoToPrint> getPostosToPrintByMedidaId( Integer medidaId )
		throws Exception
	{
		Vector<PostoToPrint> postos = new Vector<PostoToPrint>();
		Select select = 
			new Select2( 
				new String[]{ "plano_postos_trabalho" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id", "descricao" },
				new Field( "medida_id" ).isEqual( medidaId ),
				new String[]{ "id" },
				null,
				null,
				null );
		Virtual2DArray array = WEB_EXECUTER.executeQuery( select );
		for( int n = 0; n < array.columnLength(); n++ )
		{
			String descricao = ( String ) array.get( n, 1 );
			postos.add( new PostoToPrint( descricao ) );
		}
		return postos;
	}
	
	/**
	 * Para fazer dump dos logotipos para converter para jpeg
	 */
	public Mappable[] getLogotipos()
		throws Exception
	{
		Select select = 
			new Select2( 
				new String[]{ "image" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id", "image_data" },
				null, 
				null,
				null,
				null,
				null );
		Virtual2DArray array = LOCAL_EXECUTER.executeQuery( select );
		Mappable logotipos[] = new Mappable[ array.columnLength() ];
		for( int n = 0; n < logotipos.length; n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			byte data[] = ( byte[] ) array.get( n, 1 );
			logotipos[ n ] = 
				new MappableObject( id, data );
		}
		return logotipos;
	}
	
	/**
	 * Para fazer import dos logotipos convertidos para jpeg
	 */
	public void updateLogotipo( Integer id, byte[] data )
		throws Exception
	{
		BlobUpdate update = 
			new BlobUpdate( "image", "image_data", data, new Field( "id" ).isEqual( id ) );
		LOCAL_EXECUTER.executeQuery( update );
	}
}
