package com.ejie.ab39a.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFRegionUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import com.ejie.ab39a.constantes.Constantes;
import com.ejie.ab39a.model.AccionesPg;
import com.ejie.ab39a.model.ElementosArbol;
import com.ejie.ab39a.model.ElementosPe;
import com.ejie.ab39a.model.ElementosPg;
import com.ejie.ab39a.model.PlanesEstrategicos;
import com.ejie.ab39a.model.PlanesGestion;
import com.ejie.ab39a.utils.UtilProperties;
import com.gfi.utils.UtilDate;
import com.gfi.utils.Utilities;

/**
 * Eje.
 * 
 *  
 */
@Service(value = "excelService")
public class ExcelServiceImpl implements ExcelService {

	/**
	 * Generar excel pe
	 * 
	 * @param appMessageSource
	 *            ReloadableResourceBundleMessageSource appMessageSource
	 * @param plan
	 *            PlanesEstrategicos plan
	 * @param lista
	 *            List<ElementosArbol> lista
	 * @param response
	 *            HttpServletResponse response
	 * @throws FileNotFoundException
	 *             e e
	 * @throws IOException
	 *             e e
	 */
	public void generarExcelPE(ReloadableResourceBundleMessageSource appMessageSource, PlanesEstrategicos plan,
			List<ElementosArbol> lista, HttpServletResponse response) throws FileNotFoundException, IOException {

		HSSFWorkbook workbook;
		Object[] params = {};
		Locale locale = LocaleContextHolder.getLocale();

		String rutaxlscopia = UtilProperties.Props.ruta_plantilla_temporal.getValue()
				+ UtilDate.formateaFechaDDMMYYYYMILI(UtilDate.currentDate()) + Constantes.NOMBRE_EXCEL;
		String rutaplantilla = UtilProperties.Props.excel_plantilla.getValue() + Constantes.EXCEL_PLANTILLA_PE
				+ Constantes.EXTENSION_EXCEL;

		Utilities.copiarFichero(rutaplantilla, rutaxlscopia);

		workbook = new HSSFWorkbook(new FileInputStream(rutaxlscopia.toString()));
		Integer numeroFila = 0;
		Sheet hoja = workbook.getSheetAt(Constantes.NUM_CERO);
		Row fila = hoja.createRow(0);
		Cell celda = null;
		anyadirColoresPaleta(workbook);

		CellStyle estiloCabeceras = workbook.createCellStyle();
		estiloCeldaCabeceras(workbook, estiloCabeceras);
		CellStyle estiloNegrita = workbook.createCellStyle();
		estiloCeldaNegrita(workbook, estiloNegrita);
		CellStyle estiloEjes = workbook.createCellStyle();
		estiloCeldaEjes(workbook, estiloEjes);

		fila = hoja.createRow(Constantes.NUM_UNO);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.nombrePlan", params, locale));
		celda.setCellStyle(estiloNegrita);
		fila.createCell(Constantes.NUM_UNO).setCellValue(plan.getNombreEsEu());
		fila = hoja.createRow(Constantes.NUM_DOS);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.anyoInicio", params, locale));
		celda.setCellStyle(estiloNegrita);
		fila.createCell(Constantes.NUM_UNO).setCellValue(plan.getAnyoinicio());
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellValue(appMessageSource.getMessage("excel.anyoFin", params, locale));
		celda.setCellStyle(estiloNegrita);
		fila.createCell(Constantes.NUM_CUATRO).setCellValue(plan.getAnyofin());
		fila = hoja.createRow(Constantes.NUM_TRES);
		if (plan.getEntidad().getTipoEntidad() == Constantes.ADMINISTRACION_PUBLICA) {
			celda = fila.createCell(Constantes.NUM_CERO);
			celda.setCellValue(appMessageSource.getMessage("excel.indice", params, locale));
			celda.setCellStyle(estiloNegrita);
			fila.createCell(Constantes.NUM_UNO).setCellValue(plan.getIndiceObligat());

			celda = fila.createCell(Constantes.NUM_TRES);
			celda.setCellValue(appMessageSource.getMessage("excel.nivelCumpl", params, locale));
			celda.setCellStyle(estiloNegrita);
			fila.createCell(Constantes.NUM_CUATRO).setCellValue(plan.getNivelCumplimientoReqeus());
		}
		fila = hoja.createRow(Constantes.NUM_CUATRO);
		if (plan.getEntidad().getTipoEntidad() == Constantes.ENTIDAD_PRIVADA
				|| plan.getEntidad().getTipoEntidad() == Constantes.SOCIEDAD_PUBLICA) {
			celda = fila.createCell(Constantes.NUM_CERO);
			celda.setCellValue(appMessageSource.getMessage("excel.porcentaje", params, locale));
			celda.setCellStyle(estiloNegrita);
			fila.createCell(Constantes.NUM_UNO).setCellValue(plan.getPorcentajeBiling());
		}
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellValue(appMessageSource.getMessage("excel.fechaAcep", params, locale));
		celda.setCellStyle(estiloNegrita);
		fila.createCell(Constantes.NUM_CUATRO).setCellValue(plan.getFechaAceptacionPlanStr());

		combinarCeldas(hoja, Constantes.NUM_SIETE, Constantes.NUM_CERO, Constantes.NUM_TRES);
		combinarCeldas(hoja, Constantes.NUM_SEIS, Constantes.NUM_CUATRO, Constantes.NUM_SIETE);
		combinarCeldas(hoja, Constantes.NUM_SEIS, Constantes.NUM_OCHO, Constantes.NUM_ONCE);
		combinarCeldas(hoja, Constantes.NUM_SEIS, Constantes.NUM_DOCE, Constantes.NUM_QUINCE);

		fila = hoja.createRow(Constantes.NUM_SEIS);
		celda = fila.createCell(Constantes.NUM_CUATRO);
		celda.setCellValue(appMessageSource.getMessage("excel.hasiera", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CINCO);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SEIS);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SIETE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_OCHO);
		celda.setCellValue(appMessageSource.getMessage("excel.aurre", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_NUEVE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIEZ);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_ONCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOCE);
		celda.setCellValue(appMessageSource.getMessage("excel.amai", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRECE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CATORCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_QUINCE);
		celda.setCellStyle(estiloCabeceras);
		fila = hoja.createRow(Constantes.NUM_SIETE);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.nombre", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_UNO);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOS);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_QUINCE);
		celda.setCellValue(appMessageSource.getMessage("excel.sino", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CATORCE);
		celda.setCellValue(appMessageSource.getMessage("excel.valor", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRECE);
		celda.setCellValue(appMessageSource.getMessage("excel.elebi", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOCE);
		celda.setCellValue(appMessageSource.getMessage("excel.eus", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_ONCE);
		celda.setCellValue(appMessageSource.getMessage("excel.sino", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIEZ);
		celda.setCellValue(appMessageSource.getMessage("excel.valor", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_NUEVE);
		celda.setCellValue(appMessageSource.getMessage("excel.elebi", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_OCHO);
		celda.setCellValue(appMessageSource.getMessage("excel.eus", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SIETE);
		celda.setCellValue(appMessageSource.getMessage("excel.sino", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SEIS);
		celda.setCellValue(appMessageSource.getMessage("excel.valor", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CINCO);
		celda.setCellValue(appMessageSource.getMessage("excel.elebi", params, locale));
		celda.setCellStyle(estiloCabeceras);

		celda = fila.createCell(Constantes.NUM_CUATRO);
		celda.setCellValue(appMessageSource.getMessage("excel.eus", params, locale));
		celda.setCellStyle(estiloCabeceras);

		CellStyle estiloObj = workbook.createCellStyle();
		estiloCeldaElemNivelObj(workbook, estiloObj);

		numeroFila = Constantes.NUM_OCHO;
		List<ElementosArbol> elementoArbol = lista.get(0).getHijosArbol();
		for (int i = 0; i < elementoArbol.size(); i++) {
			fila = hoja.createRow(numeroFila);
			fila.setHeight((short) Constantes.NUM_SEISCIENTOS_OCHENTA);
			combinarCeldas(hoja, numeroFila, Constantes.NUM_CERO, Constantes.NUM_TRES);
			combinarCeldas(hoja, numeroFila, Constantes.NUM_CUATRO, Constantes.NUM_QUINCE);
			celda = fila.createCell(Constantes.NUM_CERO);
			celda.setCellStyle(estiloEjes);
			celda.setCellValue(elementoArbol.get(i).getNombreEsEu());
			pintarBordeCeldasCombinadas(hoja, workbook, numeroFila, 0, Constantes.NUM_CUATRO);
			pintarBordeCeldasCombinadas(hoja, workbook, numeroFila, Constantes.NUM_CUATRO, Constantes.NUM_QUINCE);
			celda = fila.createCell(Constantes.NUM_CUATRO);
			celda.setCellValue("   " + appMessageSource.getMessage("excel.obj", params, locale) + " "
					+ elementoArbol.get(i).getHelburuEsEu());
			celda.setCellStyle(estiloObj);

			numeroFila = pintaHijos(hoja, numeroFila, elementoArbol.get(i).getHijosArbol(), locale, workbook,
					appMessageSource);
		}

		FileOutputStream filePlanEstr = new FileOutputStream(rutaxlscopia);
		workbook.write(filePlanEstr);

		filePlanEstr.close();

		FileInputStream fichero = new FileInputStream(rutaxlscopia);

		Utilities.downloadDocument(response,
				"ExcelPlanes" + UtilDate.formateaFechaDDMMYYYY(UtilDate.currentDate()) + Constantes.EXTENSION_EXCEL,
				fichero);
		fichero.close();
		File ficherolocal = new File(rutaxlscopia);
		ficherolocal.delete();

	}

	/**
	 * Generar excel pg
	 * 
	 * @param appMessageSource
	 *            ReloadableResourceBundleMessageSource appMessageSource
	 * @param acciones
	 *            Map<String, List<AccionesPg>> acciones
	 * @param lista
	 *            List<ElementosArbol> lista
	 * @param plan
	 *            PlanesGestion plan
	 * @param response
	 *            HttpServletResponse response
	 * @throws FileNotFoundException
	 *             e e
	 * @throws IOException
	 *             e e
	 */
	public void generarExcelPG(ReloadableResourceBundleMessageSource appMessageSource,
			Map<String, List<AccionesPg>> acciones, List<ElementosArbol> lista, PlanesGestion plan,
			HttpServletResponse response) throws FileNotFoundException, IOException {

		HSSFWorkbook workbook;
		Locale locale = LocaleContextHolder.getLocale();

		String rutaxlscopia = UtilProperties.Props.ruta_plantilla_temporal.getValue()
				+ UtilDate.formateaFechaDDMMYYYYMILI(UtilDate.currentDate()) + Constantes.NOMBRE_EXCEL;

		Object[] params = {};
		Cell celda = null;
		String rutaplantilla = UtilProperties.Props.excel_plantilla.getValue() + Constantes.EXCEL_PLANTILLA_PG
				+ Constantes.EXTENSION_EXCEL;

		Utilities.copiarFichero(rutaplantilla, rutaxlscopia);

		Integer numeroFila = 0;
		workbook = new HSSFWorkbook(new FileInputStream(rutaxlscopia.toString()));

		CellStyle estiloEjes = workbook.createCellStyle();
		estiloCeldaEjes(workbook, estiloEjes);
		CellStyle estiloNegrita = workbook.createCellStyle();
		estiloCeldaNegrita(workbook, estiloNegrita);
		CellStyle estiloCabeceras = workbook.createCellStyle();
		estiloCeldaCabeceras(workbook, estiloCabeceras);

		anyadirColoresPaleta(workbook);
		Sheet hoja = workbook.getSheetAt(Constantes.NUM_CERO);
		Row fila = hoja.createRow(0);

		fila = hoja.createRow(Constantes.NUM_CERO);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.planEstr", params, locale));
		celda.setCellStyle(estiloNegrita);
		celda = fila.createCell(Constantes.NUM_UNO);
		celda.setCellValue(
				plan.getPlanesEstrategicos().getAnyoinicio() + " - " + plan.getPlanesEstrategicos().getAnyofin());

		CellStyle estiloAlignIzq = workbook.createCellStyle();
		combinarCeldas(hoja, Constantes.NUM_CERO, Constantes.NUM_TRES, Constantes.NUM_CUATRO);
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellValue(appMessageSource.getMessage("excel.nombrePlanE", params, locale));
		celda.setCellStyle(estiloNegrita);
		celda = fila.createCell(Constantes.NUM_CINCO);
		estiloAlignIzq.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		celda.setCellValue(plan.getPlanesEstrategicos().getNombreEsEu());
		celda.setCellStyle(estiloAlignIzq);

		fila = hoja.createRow(Constantes.NUM_UNO);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.anyo", params, locale));
		celda.setCellStyle(estiloNegrita);
		celda = fila.createCell(Constantes.NUM_UNO);
		estiloAlignIzq.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		celda.setCellValue(plan.getAnyo());
		celda.setCellStyle(estiloAlignIzq);

		combinarCeldas(hoja, Constantes.NUM_UNO, Constantes.NUM_TRES, Constantes.NUM_CUATRO);
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellValue(appMessageSource.getMessage("excel.nombrePlan", params, locale));
		celda.setCellStyle(estiloNegrita);
		celda = fila.createCell(Constantes.NUM_CINCO);
		estiloAlignIzq.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		celda.setCellValue(plan.getNombreEsEu());
		celda.setCellStyle(estiloAlignIzq);

		combinarCeldas(hoja, Constantes.NUM_CUATRO, Constantes.NUM_CERO, Constantes.NUM_CUATRO);
		combinarCeldas(hoja, Constantes.NUM_TRES, Constantes.NUM_CINCO, Constantes.NUM_DIECISEIS);

		fila = hoja.createRow(Constantes.NUM_TRES);
		celda = fila.createCell(Constantes.NUM_CINCO);
		celda.setCellValue(appMessageSource.getMessage("excel.acciones", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SEIS);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SIETE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_OCHO);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_NUEVE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIEZ);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_ONCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRECE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CATORCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_QUINCE);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIECISEIS);
		celda.setCellStyle(estiloCabeceras);

		fila = hoja.createRow(Constantes.NUM_CUATRO);
		celda = fila.createCell(Constantes.NUM_CERO);
		celda.setCellValue(appMessageSource.getMessage("excel.nombre", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_UNO);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOS);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRES);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CUATRO);
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CINCO);
		celda.setCellValue(appMessageSource.getMessage("excel.desc", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SEIS);
		celda.setCellValue(appMessageSource.getMessage("excel.responsable", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_SIETE);
		celda.setCellValue(appMessageSource.getMessage("excel.fechaPrev", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_OCHO);
		celda.setCellValue(appMessageSource.getMessage("excel.tipoRecep", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_NUEVE);
		celda.setCellValue(appMessageSource.getMessage("excel.numRecep", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIEZ);
		celda.setCellValue(appMessageSource.getMessage("excel.numRecepH", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_ONCE);
		celda.setCellValue(appMessageSource.getMessage("excel.numRecepM", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DOCE);
		celda.setCellValue(appMessageSource.getMessage("excel.situacion", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_TRECE);
		celda.setCellValue(appMessageSource.getMessage("excel.razon", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_CATORCE);
		celda.setCellValue(appMessageSource.getMessage("excel.nuevaFechaPrev", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_QUINCE);
		celda.setCellValue(appMessageSource.getMessage("excel.motivoCanc", params, locale));
		celda.setCellStyle(estiloCabeceras);
		celda = fila.createCell(Constantes.NUM_DIECISEIS);
		celda.setCellValue(appMessageSource.getMessage("excel.observ", params, locale));
		celda.setCellStyle(estiloCabeceras);

		numeroFila = Constantes.NUM_CINCO;

		CellStyle estiloObj = workbook.createCellStyle();
		estiloCeldaElemNivelObj(workbook, estiloObj);

		List<ElementosArbol> elementoArbol = lista.get(0).getHijosArbol();
		for (int i = 0; i < elementoArbol.size(); i++) {
			fila = hoja.createRow(numeroFila);
			fila.setHeight((short) Constantes.NUM_SEISCIENTOS_OCHENTA);
			combinarCeldas(hoja, numeroFila, Constantes.NUM_CERO, Constantes.NUM_CUATRO);

			pintarBordeCeldasCombinadas(hoja, workbook, numeroFila, 0, Constantes.NUM_CUATRO);
			celda = fila.createCell(Constantes.NUM_CERO);
			celda.setCellStyle(estiloEjes);
			celda.setCellValue(elementoArbol.get(i).getNombreEsEu());

			numeroFila = pintaHijosPG(hoja, numeroFila, elementoArbol.get(i).getHijosArbol(), locale, workbook,
					acciones, appMessageSource);
		}

		FileOutputStream filePlanEstr = new FileOutputStream(rutaxlscopia);
		workbook.write(filePlanEstr);

		filePlanEstr.close();

		FileInputStream fichero = new FileInputStream(rutaxlscopia);

		Utilities.downloadDocument(response,
				"ExcelPlanes" + UtilDate.formateaFechaDDMMYYYY(UtilDate.currentDate()) + Constantes.EXTENSION_EXCEL,
				fichero);
		fichero.close();
		File ficherolocal = new File(rutaxlscopia);
		ficherolocal.delete();
	}

	/**
	 * Pinta los hijos del arbol
	 * 
	 * @param hoja
	 *            Sheet hoja
	 * @param numeroFila
	 *            Integer numeroFila
	 * @param elementoArbol
	 *            List<ElementosArbol> lista elementos
	 * @param locale
	 *            Locale locale
	 * @param workbook
	 *            Workbook workbook
	 * @param appMessageSource
	 *            ReloadableResourceBundleMessageSource appMessageSource
	 * @return Integer numero fila
	 */
	public Integer pintaHijos(Sheet hoja, Integer numeroFila, List<ElementosArbol> elementoArbol, Locale locale,
			HSSFWorkbook workbook, ReloadableResourceBundleMessageSource appMessageSource) {
		Row fila = null;
		Cell celda = null;
		Integer numFila = numeroFila;
		numFila = numFila + 1;
		Object[] params = {};

		for (int x = 0; x < elementoArbol.size(); x++) {
			fila = hoja.createRow(numFila);
			ElementosPe elemPe = (ElementosPe) elementoArbol.get(x);
			combinarCeldas(hoja, numFila, Constantes.NUM_CERO, Constantes.NUM_TRES);
			pintarBordeCeldasCombinadas(hoja, workbook, numFila, 0, Constantes.NUM_CUATRO);
			celda = fila.createCell(Constantes.NUM_CERO);

			CellStyle estiloObj = workbook.createCellStyle();
			estiloCeldaElemNivelObj(workbook, estiloObj);
			CellStyle estiloValores = workbook.createCellStyle();
			estiloCeldaElemNivelValores(workbook, estiloValores);
			pintarSegunElem(elemPe.getNivelA(), elemPe.getNombreEsEu(), fila, celda, workbook);

			if (elemPe.getNivelA() != Constantes.ELEMENTO_NIVEL_3) {
				pintarBordeCeldasCombinadas(hoja, workbook, numFila, Constantes.NUM_CUATRO, Constantes.NUM_QUINCE);
				combinarCeldas(hoja, numFila, Constantes.NUM_CUATRO, Constantes.NUM_QUINCE);
				celda = fila.createCell(Constantes.NUM_CUATRO);
				celda.setCellValue("   " + appMessageSource.getMessage("excel.obj", params, locale) + " "
						+ elemPe.getHelburuEsEu());
				celda.setCellStyle(estiloObj);
			}
			if (elemPe.getNivelA() == Constantes.ELEMENTO_NIVEL_3) {
				celda = fila.createCell(Constantes.NUM_CUATRO);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1 || elemPe.getTieneEus() == 1) {
					celda.setCellValue(elemPe.getHasEus().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_CINCO);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1) {
					celda.setCellValue(elemPe.getHasElebi().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_SEIS);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneValor() == 1) {
					celda.setCellValue(elemPe.getHasValor().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_SIETE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneSiNo() == 1) {
					celda.setCellValue(
							elemPe.getHasSiNo() == 0 ? appMessageSource.getMessage("excel.no", params, locale)
									: appMessageSource.getMessage("excel.si", params, locale));
				}
				celda = fila.createCell(Constantes.NUM_OCHO);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1 || elemPe.getTieneEus() == 1) {
					celda.setCellValue(elemPe.getAurreEus().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_NUEVE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1) {
					celda.setCellValue(elemPe.getAurreElebi().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_DIEZ);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneValor() == 1) {
					celda.setCellValue(elemPe.getAurreValor().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_ONCE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneSiNo() == 1) {
					celda.setCellValue(
							elemPe.getAurreSiNo() == 0 ? appMessageSource.getMessage("excel.no", params, locale)
									: appMessageSource.getMessage("excel.si", params, locale));
				}
				celda = fila.createCell(Constantes.NUM_DOCE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1 || elemPe.getTieneEus() == 1) {
					celda.setCellValue(elemPe.getAmaiEus().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_TRECE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneElebi() == 1) {
					celda.setCellValue(elemPe.getAmaiElebi().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_CATORCE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneValor() == 1) {
					celda.setCellValue(elemPe.getAmaiValor().doubleValue());
				}
				celda = fila.createCell(Constantes.NUM_QUINCE);
				celda.setCellStyle(estiloValores);
				if (elemPe.getTieneSiNo() == 1) {
					celda.setCellValue(
							elemPe.getAmaiSiNo() == 0 ? appMessageSource.getMessage("excel.no", params, locale)
									: appMessageSource.getMessage("excel.si", params, locale));
				}
			}
			numFila = pintaHijos(hoja, numFila, elemPe.getHijosArbol(), locale, workbook, appMessageSource);
		}
		return numFila;
	}

	/**
	 * Pinta los hijos del arbol
	 * 
	 * @param hoja
	 *            Sheet hoja
	 * @param numeroFila
	 *            Integer numeroFila
	 * @param elementoArbol
	 *            List<ElementosArbol> lista elementos
	 * @param locale
	 *            Locale locale
	 * @param workbook
	 *            Workbook workbook
	 * @param acciones
	 *            List<AccionesPg>> lista de acciones
	 * @param appMessageSource
	 *            ReloadableResourceBundleMessageSource appMessageSource
	 * @return Integer numero fila
	 */
	public Integer pintaHijosPG(Sheet hoja, Integer numeroFila, List<ElementosArbol> elementoArbol, Locale locale,
			HSSFWorkbook workbook, Map<String, List<AccionesPg>> acciones,
			ReloadableResourceBundleMessageSource appMessageSource) {
		Row fila = null;
		Cell celda = null;
		Integer numFila = numeroFila;
		numFila = numFila + 1;

		for (int x = 0; x < elementoArbol.size(); x++) {
			fila = hoja.createRow(numFila);
			ElementosPg elemPe = (ElementosPg) elementoArbol.get(x);
			combinarCeldas(hoja, numFila, Constantes.NUM_CERO, Constantes.NUM_CUATRO);
			pintarBordeCeldasCombinadas(hoja, workbook, numFila, 0, Constantes.NUM_CUATRO);
			celda = fila.createCell(Constantes.NUM_CERO);
			// Estilos celda segun nivel del elemento
			pintarSegunElem(elemPe.getNivelA(), elemPe.getNombreEsEu(), fila, celda, workbook);

			if (elemPe.getNivelA() == Constantes.NUM_CUATRO || elemPe.getNivelA() == Constantes.NUM_TRES) {
				numFila = pintaAcciones(hoja, numFila, elemPe.getIdElementoA(), locale, workbook, acciones);
			}
			numFila = pintaHijosPG(hoja, numFila, elemPe.getHijosArbol(), locale, workbook, acciones, appMessageSource);
		}
		return numFila;
	}

	/**
	 * pintar Segun Elem
	 * 
	 * @param nivel
	 *            Long nivel
	 * @param nombre
	 *            String nombre
	 * 
	 * @param fila
	 *            Row fila
	 * @param celda
	 *            Cell celda
	 * @param workbook
	 *            HSSFWorkbook workbook
	 */
	public void pintarSegunElem(Long nivel, String nombre, Row fila, Cell celda, HSSFWorkbook workbook) {
		CellStyle estilo1 = workbook.createCellStyle();
		estiloCeldaElemNivel1(workbook, estilo1);
		CellStyle estilo2 = workbook.createCellStyle();
		estiloCeldaElemNivel2(workbook, estilo2);
		CellStyle estilo3 = workbook.createCellStyle();
		estiloCeldaElemNivel3(workbook, estilo3);
		CellStyle estilo4 = workbook.createCellStyle();
		estiloCeldaElemNivel4(workbook, estilo4);

		if (nivel == Constantes.NUM_UNO) {
			fila.setHeight((short) Constantes.NUM_SEISCIENTOS);
			celda.setCellValue("    " + nombre);
			celda.setCellStyle(estilo1);
		} else if (nivel == Constantes.NUM_DOS) {
			fila.setHeight((short) Constantes.NUM_CUATROCIENTOS);
			celda.setCellValue("        " + nombre);
			celda.setCellStyle(estilo2);
		} else if (nivel == Constantes.NUM_TRES) {
			celda.setCellValue("            " + nombre);
			celda.setCellStyle(estilo3);
		} else if (nivel == Constantes.NUM_CUATRO) {
			celda.setCellValue("                " + nombre);
			celda.setCellStyle(estilo4);
		}
	}

	/**
	 * Pinta las acciones
	 * 
	 * @param hoja
	 *            Sheet hoja
	 * @param numeroFila
	 *            Integer numeroFila
	 * @param idElemento
	 *            Long idElemento
	 * @param locale
	 *            Locale locale
	 * @param workbook
	 *            Workbook workbook
	 * @param acciones
	 *            Map<String, List<AccionesPg>> acciones
	 * @return Integer Integer
	 */
	public Integer pintaAcciones(Sheet hoja, Integer numeroFila, Long idElemento, Locale locale, HSSFWorkbook workbook,
			Map<String, List<AccionesPg>> acciones) {

		Row fila = null;
		Cell celda = null;
		CellStyle estilo5 = workbook.createCellStyle();
		estiloCeldaElemNivel5(workbook, estilo5);
		Integer numFila = numeroFila;
		if (acciones != null) {
			List<AccionesPg> listaAcciones = acciones.get(idElemento.toString());
			if (listaAcciones != null) {
				for (int x = 0; x < listaAcciones.size(); x++) {
					numFila++;
					fila = hoja.createRow(numFila);
					AccionesPg accion = (AccionesPg) listaAcciones.get(x);
					combinarCeldas(hoja, numFila, Constantes.NUM_CERO, Constantes.NUM_CUATRO);
					pintarBordeCeldasCombinadas(hoja, workbook, numFila, 0, Constantes.NUM_CUATRO);

					celda = fila.createCell(Constantes.NUM_CERO);
					celda.setCellValue("                    " + accion.getNombreEsEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_CINCO);
					celda.setCellValue(accion.getDescripcionEsEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_SEIS);
					celda.setCellValue(accion.getResponsable());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_SIETE);
					celda.setCellValue(accion.getFechaprevStr());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_OCHO);
					celda.setCellValue(locale.getLanguage().equals(Constantes.IDIOMA_ES) ? accion.getTiporeceptorEs()
							: accion.getTiporeceptorEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_NUEVE);
					celda.setCellValue(accion.getNumreceptores());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_DIEZ);
					celda.setCellValue(accion.getNumreceph());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_ONCE);
					celda.setCellValue(accion.getNumrecepm());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_DOCE);
					celda.setCellValue(locale.getLanguage().equals(Constantes.IDIOMA_ES) ? accion.getSituacionEs()
							: accion.getSituacionEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_TRECE);
					celda.setCellValue(accion.getRazonAplazaEsEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_CATORCE);
					celda.setCellValue(accion.getNuevafechaprevStr());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_QUINCE);
					celda.setCellValue(accion.getMotivoCancelaEsEu());
					celda.setCellStyle(estilo5);
					celda = fila.createCell(Constantes.NUM_DIECISEIS);
					celda.setCellValue(accion.getObservacionesEsEu());
					celda.setCellStyle(estilo5);
				}
			}
		}
		return numFila++;
	}

	/**
	 * Combinar celdas del excel
	 * 
	 * @param hoja
	 *            Sheet hoja
	 * @param numFila
	 *            Integer numero de fila
	 * @param numColIni
	 *            Integer columna inicio
	 * @param numColFin
	 *            Integer columna final
	 */
	public void combinarCeldas(Sheet hoja, Integer numFila, Integer numColIni, Integer numColFin) {
		hoja.addMergedRegion(new CellRangeAddress(numFila, numFila, numColIni, numColFin));
	}

	/**
	 * Crea el color de las celdas nivel1
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivel1(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		cellFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		estilo.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		ponerTipoLetra(cellFont, Constantes.NUM_DOCE);
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_TRES, workbook);
		estilo.setFont(cellFont);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas nivel2
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivel2(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFontElem1 = workbook.createFont();
		estilo.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		cellFontElem1.setBoldweight(Font.BOLDWEIGHT_BOLD);
		ponerTipoLetra(cellFontElem1, Constantes.NUM_ONCE);
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_TRES, workbook);
		estilo.setFont(cellFontElem1);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas nivel3
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivel3(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_UNO, workbook);
		ponerTipoLetra(cellFont, Constantes.NUM_ONCE);
		estilo.setFont(cellFont);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas nivel4
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivel4(HSSFWorkbook workbook, CellStyle estilo) {
		ponerColorFondo(estilo, Constantes.NUM_SESENTA, workbook);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas nivel5
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivel5(HSSFWorkbook workbook, CellStyle estilo) {
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_DOS, workbook);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas Valores
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivelValores(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		ponerTipoLetra(cellFont, Constantes.NUM_ONCE);
		estilo.setFont(cellFont);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas Objetivos
	 * 
	 * @param workbook
	 *            Workbook workbook
	 * @param estilo
	 *            CellStyle CellStyle
	 */
	public void estiloCeldaElemNivelObj(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		estilo.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_TRES, workbook);
		ponerTipoLetra(cellFont, Constantes.NUM_DIEZ);
		estilo.setFont(cellFont);
		estilo.setWrapText(true);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas segun el nivel del elemento para pe
	 * 
	 * @param estilo
	 *            CellStyle estilo
	 * @param workbook
	 *            Workbook workbook
	 */
	public void estiloCeldaCabeceras(HSSFWorkbook workbook, CellStyle estilo) {
		ponerColorFondo(estilo, Constantes.NUM_CINCUENTA_Y_NUEVE, workbook);
		estilo.setAlignment(CellStyle.ALIGN_CENTER);
		ponerBorde(estilo);
	}

	/**
	 * Crea el color de las celdas segun el nivel del elemento para pe
	 * 
	 * @param estilo
	 *            CellStyle estilo
	 * @param workbook
	 *            Workbook workbook
	 */
	public void estiloCeldaNegrita(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		cellFont = workbook.createFont();
		cellFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		estilo.setFont(cellFont);
	}

	/**
	 * Crea el color de las celdas segun el nivel del elemento para pe
	 * 
	 * @param estilo
	 *            CellStyle estilo
	 * @param workbook
	 *            Workbook workbook
	 */
	public void estiloCeldaEjes(HSSFWorkbook workbook, CellStyle estilo) {
		Font cellFont = workbook.createFont();
		cellFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		ponerTipoLetra(cellFont, Constantes.NUM_TRECE);
		estilo.setFont(cellFont);
		estilo.setAlignment(CellStyle.ALIGN_CENTER);
		estilo.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		ponerColorFondo(estilo, Constantes.NUM_SESENTA_Y_TRES, workbook);
		ponerBorde(estilo);

	}

	/**
	 * Poner color de fondo a las celdas
	 * 
	 * @param estilo
	 *            CellStyle estilo
	 * @param num
	 *            int numero color
	 * @param workbook
	 *            HSSFWorkbook workbook
	 */
	public void ponerColorFondo(CellStyle estilo, int num, HSSFWorkbook workbook) {
		HSSFPalette palette = workbook.getCustomPalette();
		estilo.setFillForegroundColor(palette.getColor(num).getIndex());
		estilo.setFillPattern(CellStyle.SOLID_FOREGROUND);
	}

	/**
	 * Poner borde a las celdas
	 * 
	 * @param estilo
	 *            CellStyle estilo
	 */
	public void ponerBorde(CellStyle estilo) {
		estilo.setBorderTop(CellStyle.BORDER_THIN);
		estilo.setTopBorderColor((short) Constantes.NUM_OCHO);
		estilo.setBorderBottom(CellStyle.BORDER_THIN);
		estilo.setBottomBorderColor((short) Constantes.NUM_OCHO);
		estilo.setBorderRight(CellStyle.BORDER_THIN);
		estilo.setRightBorderColor((short) Constantes.NUM_OCHO);
		estilo.setBorderLeft(CellStyle.BORDER_THIN);
		estilo.setLeftBorderColor((short) Constantes.NUM_OCHO);
	}

	/**
	 * Poner el tipo de letra a la celda
	 * 
	 * @param cellFont
	 *            Font fuente
	 * @param tamanyo
	 *            int tamaño
	 */
	public void ponerTipoLetra(Font cellFont, int tamanyo) {
		cellFont.setFontName("Calibri");
		cellFont.setFontHeightInPoints((short) tamanyo);
	}

	/**
	 * Añade colores
	 * 
	 * @param workbook
	 *            HSSFWorkbook workbook
	 */
	public void anyadirColoresPaleta(HSSFWorkbook workbook) {
		HSSFPalette palette = workbook.getCustomPalette();
		palette.setColorAtIndex((short) Constantes.NUM_CINCUENTA_Y_NUEVE, (byte) Constantes.NUM_CIENTO_CINCUENTA_Y_SEIS,
				(byte) Constantes.NUM_CIENTO_OCHENTA_Y_SEIS, (byte) Constantes.NUM_DOSCIENTOS_TREINTA_Y_OCHO);
		palette.setColorAtIndex((short) Constantes.NUM_SESENTA, (byte) Constantes.NUM_DOSCIENTOS_VEINTITRES,
				(byte) Constantes.NUM_DOSCIENTOS_TREINTA_Y_SIETE, (byte) Constantes.NUM_DOSCIENTOS_CINCUENTA);
		palette.setColorAtIndex((short) Constantes.NUM_SESENTA_Y_UNO,
				(byte) Constantes.NUM_DOSCIENTOS_CINCUENTA_Y_CUATRO, (byte) Constantes.NUM_DOSCIENTOS_CUARENTA_Y_TRES,
				(byte) Constantes.NUM_DOSCIENTOS_VEINTISEIS);
		palette.setColorAtIndex((short) Constantes.NUM_SESENTA_Y_DOS, (byte) Constantes.NUM_CIENTO_OCHENTA_Y_UNO,
				(byte) Constantes.NUM_DOSCIENTOS_SEIS, (byte) Constantes.NUM_DOSCIENTOS_VEINTISEIS);
		palette.setColorAtIndex((short) Constantes.NUM_SESENTA_Y_TRES, (byte) Constantes.NUM_CIENTO_OCHENTA_Y_TRES,
				(byte) Constantes.NUM_DOSCIENTOS_CINCO, (byte) Constantes.NUM_DOSCIENTOS_VEINTISEIS);
	}

	/**
	 * Pinta los bordes de las celdas combinadas
	 * 
	 * @param hoja
	 *            Sheet hoja
	 * @param workbook
	 *            HSSFWorkbook workbook
	 * @param numFila
	 *            Integer numFila
	 * @param colIni
	 *            Integer colIni
	 * @param colFin
	 *            Integer colFin
	 */
	public void pintarBordeCeldasCombinadas(Sheet hoja, HSSFWorkbook workbook, Integer numFila, Integer colIni,
			Integer colFin) {
		CellRangeAddress cellRangeAddress = new CellRangeAddress(numFila, numFila, colIni, colFin);
		HSSFRegionUtil.setBorderTop(CellStyle.BORDER_THIN, cellRangeAddress, (HSSFSheet) hoja, workbook);
		HSSFRegionUtil.setBorderLeft(CellStyle.BORDER_THIN, cellRangeAddress, (HSSFSheet) hoja, workbook);
		HSSFRegionUtil.setBorderRight(CellStyle.BORDER_THIN, cellRangeAddress, (HSSFSheet) hoja, workbook);
		HSSFRegionUtil.setBorderBottom(CellStyle.BORDER_THIN, cellRangeAddress, (HSSFSheet) hoja, workbook);
	}

}
