package com.ejie.ab04b.util;

import java.util.List;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesNum;
import com.ejie.ab04b.model.ApartadoAnexoI;
import com.ejie.ab04b.model.ApartadoAnexoII;
import com.ejie.ab04b.model.ClaseCentroTrabajo;
import com.ejie.ab04b.model.CnaeJ73;
import com.ejie.ab04b.model.EmpresaAuditora;
import com.ejie.ab04b.model.EmpresaServicioPrevencion;
import com.ejie.ab04b.model.EntidadGestoraColaboradora;
import com.ejie.ab04b.model.ModalidadOrganizacionPreventiva;
import com.ejie.ab04b.model.SeccionJ73;
import com.ejie.ab04b.model.TipoObra;
import com.ejie.ab04b.model.nora.Calle;
import com.ejie.ab04b.model.nora.Localidad;
import com.ejie.ab04b.model.nora.Municipio;
import com.ejie.ab04b.model.nora.Pais;
import com.ejie.ab04b.model.nora.Provincia;
import com.ejie.ab04b.parse.MessageUnparser;
import com.ejie.r02s.xml.Parameter;
import com.ejie.r02s.xml.Parameters;

/**
 * @author GFI-NORTE
 * 
 */
public final class ToolkitParameterUtils {

	private static ToolkitParameterUtils instance;

	private static String PARAMETERS_TAB_BEGIN = "<parameters>";
	private static String PARAMETERS_TAB_END = "</parameters>";
	private static String PARAMETERS_XML_DEFINITION = "<\\?xml version=\"1.0\" encoding=\"ISO\\-8859-1\" standalone=\"yes\"\\?>\n";
	private static String PARAMETERS_XML_NAMESPACE = " xmlns=\"com/ejie/r02s/xml\"";

	/**
	 * Constructor privado.
	 */
	private ToolkitParameterUtils() {

	}

	/**
	 * Gets the single instance of ToolkitParameterUtils.
	 * 
	 *  ToolkitParameterUtils
	 *
	 * @return single instance of ToolkitParameterUtils
	 */
	public static ToolkitParameterUtils getInstance() {
		if (ToolkitParameterUtils.instance == null) {
			ToolkitParameterUtils.instance = new ToolkitParameterUtils();
		}
		return ToolkitParameterUtils.instance;
	}

	/**
	 * Construye un objeto de tipo Parameter.
	 * 
	 *  value
	 *            String
	 *  descEs
	 *            String
	 *  descEu
	 *            String
	 *  Parameter
	 *
	 * @param value the value
	 * @param descEs the desc es
	 * @param descEu the desc eu
	 * @return the parameter
	 */
	public Parameter construirParameter(String value, String descEs,
			String descEu) {
		Parameter parameter = new Parameter();
		parameter.getValue().add(value);
		parameter.getValue().add(descEs);
		parameter.getValue().add(descEu);
		return parameter;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de TipoObra.
	 * 
	 *  listaTipoObra
	 *            List<TipoObra>
	 *  Parameters
	 *
	 * @param listaTipoObra the lista tipo obra
	 * @return the parameters
	 */
	public Parameters construirParametersListaTipoObra(
			List<TipoObra> listaTipoObra) {

		Parameters parameters = new Parameters();
		for (TipoObra tipoObra : listaTipoObra) {
			Parameter parameter = this.construirParameter(
					tipoObra.getTipobr070(), tipoObra.getDesobrEs070(),
					tipoObra.getDesobrEu070());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * ApartadoAnexoI.
	 * 
	 *  listaApartadoAnexoI
	 *            List<ApartadoAnexoI>
	 *  Parameters
	 *
	 * @param listaApartadoAnexoI the lista apartado anexo I
	 * @return the parameters
	 */
	public Parameters construirParametersListaApartadoAnexoI(
			List<ApartadoAnexoI> listaApartadoAnexoI) {

		Parameters parameters = new Parameters();
		for (ApartadoAnexoI apartadoAnexoI : listaApartadoAnexoI) {
			Parameter parameter = this.construirParameter(
					apartadoAnexoI.getApdoanx073(),
					apartadoAnexoI.getDesanxEs073(),
					apartadoAnexoI.getDesanxEu073());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * ApartadoAnexoII.
	 * 
	 *  listaApartadoAnexoII
	 *            List<ApartadoAnexoII>
	 *  Parameters
	 *
	 * @param listaApartadoAnexoII the lista apartado anexo II
	 * @return the parameters
	 */
	public Parameters construirParametersListaApartadoAnexoII(
			List<ApartadoAnexoII> listaApartadoAnexoII) {

		Parameters parameters = new Parameters();
		for (ApartadoAnexoII apartadoAnexoII : listaApartadoAnexoII) {
			Parameter parameter = this.construirParameter(
					apartadoAnexoII.getApdoanx2086(),
					apartadoAnexoII.getDesanx2Es086(),
					apartadoAnexoII.getDesanx2Eu086());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * ClaseCentroTrabajo.
	 * 
	 *  listaClaseCentroTrabajo
	 *            List<ClaseCentroTrabajo>
	 *  Parameters
	 *
	 * @param listaClaseCentroTrabajo the lista clase centro trabajo
	 * @return the parameters
	 */
	public Parameters construirParametersListaClaseCentroTrabajo(
			List<ClaseCentroTrabajo> listaClaseCentroTrabajo) {

		Parameters parameters = new Parameters();
		for (ClaseCentroTrabajo apartadoAnexoII : listaClaseCentroTrabajo) {
			Parameter parameter = this.construirParameter(
					apartadoAnexoII.getClasctr072(),
					apartadoAnexoII.getDesclasEs072(),
					apartadoAnexoII.getDesclasEu072());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * EntidadGestoraColaboradora.
	 * 
	 *  listaEntidadGestoraColaboradora
	 *            List<EntidadGestoraColaboradora>
	 *  Parameters
	 *
	 * @param listaEntidadGestoraColaboradora the lista entidad gestora colaboradora
	 * @return the parameters
	 */
	public Parameters construirParametersListaEntidadGestoraColaboradora(
			List<EntidadGestoraColaboradora> listaEntidadGestoraColaboradora) {

		Parameters parameters = new Parameters();
		for (EntidadGestoraColaboradora entidadGestoraColaboradora : listaEntidadGestoraColaboradora) {
			Parameter parameter = this.construirParameter(
					entidadGestoraColaboradora.getCodentiat078(),
					entidadGestoraColaboradora.getDesentiatEs078(),
					entidadGestoraColaboradora.getDesentiatEu078());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * ModalidadOrganizacionPreventiva.
	 * 
	 *  listaModalidadOrganizacionPreventiva
	 *            List<ModalidadOrganizacionPreventiva>
	 *  Parameters
	 *
	 * @param listaModalidadOrganizacionPreventiva the lista modalidad organizacion preventiva
	 * @return the parameters
	 */
	public Parameters construirParametersListaModalidadOrganizacionPreventiva(
			List<ModalidadOrganizacionPreventiva> listaModalidadOrganizacionPreventiva) {

		Parameters parameters = new Parameters();
		for (ModalidadOrganizacionPreventiva modalidadOrganizacionPreventiva : listaModalidadOrganizacionPreventiva) {
			Parameter parameter = this.construirParameter(
					modalidadOrganizacionPreventiva.getTipmpr074(),
					modalidadOrganizacionPreventiva.getDesmprEs074(),
					modalidadOrganizacionPreventiva.getDesmprEu074());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * EmpresaAuditora.
	 * 
	 *  listaEmpresaAuditora
	 *            List<EmpresaAuditora>
	 *  Parameters
	 *
	 * @param listaEmpresaAuditora the lista empresa auditora
	 * @return the parameters
	 */
	public Parameters construirParametersListaEmpresaAuditora(
			List<EmpresaAuditora> listaEmpresaAuditora) {

		Parameters parameters = new Parameters();
		for (EmpresaAuditora empresaAuditora : listaEmpresaAuditora) {
			Parameter parameter = this.construirParameter(
					empresaAuditora.getCodempaud079(),
					empresaAuditora.getDesempaudEs079(),
					empresaAuditora.getDesempaudEu079());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * EmpresaServicioPrevencion.
	 * 
	 *  listaEmpresaServicioPrevencion
	 *            List<EmpresaServicioPrevencion>
	 *  Parameters
	 *
	 * @param listaEmpresaServicioPrevencion the lista empresa servicio prevencion
	 * @return the parameters
	 */
	public Parameters construirParametersListaEmpresaServicioPrevencion(
			List<EmpresaServicioPrevencion> listaEmpresaServicioPrevencion) {

		Parameters parameters = new Parameters();
		for (EmpresaServicioPrevencion empresaServicioPrevencion : listaEmpresaServicioPrevencion) {
			Parameter parameter = this.construirParameter(
					empresaServicioPrevencion.getCodprev080(),
					empresaServicioPrevencion.getDesprevEs080(),
					empresaServicioPrevencion.getDesprevEu080());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de Pais.
	 * 
	 *  listaPais
	 *            List<Pais>
	 *  Parameters
	 *
	 * @param listaPais the lista pais
	 * @return the parameters
	 */
	public Parameters construirParametersListaPais(List<Pais> listaPais) {

		Parameters parameters = new Parameters();
		for (Pais provincia : listaPais) {
			Parameter parameter = this.construirParameter(provincia.getId(),
					provincia.getDsO(), provincia.getDsO());
			parameters.getParameter().add(parameter);
		}

		this.priorizarElementoLista(parameters, Constantes.ID_PAIS_ESPANA);

		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * Provincia.
	 * 
	 *  listaProvincia
	 *            List<Provincia>
	 *  Parameters
	 *
	 * @param listaProvincia the lista provincia
	 * @return the parameters
	 */
	public Parameters construirParametersListaProvincia(
			List<Provincia> listaProvincia) {

		Parameters parameters = new Parameters();
		for (Provincia provincia : listaProvincia) {
			Parameter parameter = this.construirParameter(
					provincia.getCodProvincia(), provincia.getDescripcion(),
					provincia.getDescripcion());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * Municipio.
	 * 
	 *  listaMunicipio
	 *            List<Municipio>
	 *  Parameters
	 *
	 * @param listaMunicipio the lista municipio
	 * @return the parameters
	 */
	public Parameters construirParametersListaMunicipio(
			List<Municipio> listaMunicipio) {

		Parameters parameters = new Parameters();
		for (Municipio municipio : listaMunicipio) {
			Parameter parameter = this.construirParameter(
					municipio.getCodMunicipio(), municipio.getDescripcion(),
					municipio.getDescripcion());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de
	 * Localidad.
	 * 
	 *  listaLocalidad
	 *            List<Localidad>
	 *  Parameters
	 *
	 * @param listaLocalidad the lista localidad
	 * @return the parameters
	 */
	public Parameters construirParametersListaLocalidad(
			List<Localidad> listaLocalidad) {

		Parameters parameters = new Parameters();
		for (Localidad localidad : listaLocalidad) {
			Parameter parameter = this.construirParameter(localidad
					.getCodLocalidad().toString(), localidad.getDescripcion(),
					localidad.getDescripcion());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de Calle.
	 * 
	 *  listaCalle
	 *            List<Calle>
	 *  Parameters
	 *
	 * @param listaCalle the lista calle
	 * @return the parameters
	 */
	public Parameters construirParametersListaCalle(List<Calle> listaCalle) {

		Parameters parameters = new Parameters();
		for (Calle calle : listaCalle) {
			Parameter parameter = this
					.construirParameter(calle.getCodCalle().toString(),
							calle.getDescripcion(), calle.getDescripcion());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de Seccion.
	 * 
	 *  listaSecciones
	 *            List<Seccion>
	 *  Parameters
	 *
	 * @param listaSecciones the lista secciones
	 * @return the parameters
	 */
	public Parameters construirParametersListaSeccion(
			List<SeccionJ73> listaSecciones) {

		Parameters parameters = new Parameters();
		for (SeccionJ73 seccion : listaSecciones) {
			Parameter parameter = this.construirParameter(seccion.getSecc004(),
					seccion.getDesc004(), seccion.getDesc004());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Construye un objeto de tipo Parameters a partir de una lista de CnaeJ73.
	 * 
	 *  listaCnae
	 *            List<CnaeJ73>
	 *  Parameters
	 *
	 * @param listaCnae the lista cnae
	 * @return the parameters
	 */
	public Parameters construirParametersListaCnae(List<CnaeJ73> listaCnae) {

		Parameters parameters = new Parameters();
		for (CnaeJ73 cnae : listaCnae) {
			Parameter parameter = this.construirParameter(cnae.getCnae003(),
					cnae.getDesc003(), cnae.getDesc003());
			parameters.getParameter().add(parameter);
		}
		return parameters;
	}

	/**
	 * Devuelve un XML con un objeto Parameters vacío.
	 * 
	 *  String
	 *
	 * @return the string
	 */
	public String construirParametersListaVacia() {
		StringBuilder sb = new StringBuilder();
		sb.append(ToolkitParameterUtils.PARAMETERS_TAB_BEGIN);
		sb.append(ToolkitParameterUtils.PARAMETERS_TAB_END);
		return sb.toString();
	}

	/**
	 * Convierte un objeto Parameters a String.
	 * 
	 *  parameters
	 *            Parameters
	 *  String
	 *
	 * @param parameters the parameters
	 * @return the string
	 */
	public String unparseParametersToString(Parameters parameters) {
		String sparameters = "";
		try {
			MessageUnparser<Parameters> unparser = new MessageUnparser<Parameters>();
			sparameters = unparser.parse(parameters);
			sparameters = sparameters.replaceAll(
					ToolkitParameterUtils.PARAMETERS_XML_DEFINITION, "");
			sparameters = sparameters.replaceAll(
					ToolkitParameterUtils.PARAMETERS_XML_NAMESPACE, "");
		} catch (Exception ioe) {
			sparameters = ToolkitParameterUtils.getInstance()
					.construirParametersListaVacia();
		}
		return sparameters;
	}

	/**
	 * En una lista de Parameters para el toolkit, busca el elemento codigo,
	 * modifica sus textos a mayúsculas y lo coloca en primera posición.
	 * 
	 *  parameters
	 *            Parameters
	 *  codigo
	 *            String
	 *  Parameters
	 *
	 * @param parameters the parameters
	 * @param codigo the codigo
	 * @return the parameters
	 */
	public Parameters priorizarElementoLista(Parameters parameters,
			String codigo) {

		if (parameters != null && parameters.getParameter() != null
				&& !parameters.getParameter().isEmpty()) {
			boolean encontrado = false;
			for (int i = 0; i < parameters.getParameter().size() && !encontrado; i++) {
				Parameter parameter = parameters.getParameter().get(i);
				if (codigo.equals(parameter.getValue().get(0))) {
					// Ponemos a mayúsculas la primera descripción
					// (obligatoria)
					parameter.getValue().set(1,
							parameter.getValue().get(1).toUpperCase());
					if (parameter.getValue().get(ConstantesNum.NUM_2) != null) {
						// Ponemos a mayúsculas la segunda descripción
						// (opcional)
						parameter.getValue().set(
								ConstantesNum.NUM_2,
								parameter.getValue().get(ConstantesNum.NUM_2)
										.toUpperCase());
					}
					// Borramos el elemento de la lista en su posición
					// actual
					parameters.getParameter().remove(i);
					// Añadimos el elemento en primera posición
					parameters.getParameter().add(0, parameter);
					encontrado = true;
				}
			}
		}
		return parameters;
	}

}
