package com.ejie.aa94a.control;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.ejie.aa94a.constantes.Constantes;
import com.ejie.aa94a.constantes.ConstantesPDF;
import com.ejie.aa94a.model.calculo.Bobina;
import com.ejie.aa94a.model.calculo.Estiba;
import com.ejie.aa94a.model.calculo.Mensaje;
import com.ejie.aa94a.model.calculo.Resultado;
import com.ejie.aa94a.model.calculo.Transporte;
import com.ejie.aa94a.model.config.Configuracion;
import com.ejie.aa94a.model.config.Densidad;
import com.ejie.aa94a.model.config.Solucion;
import com.ejie.aa94a.model.config.TipoSujecion;
import com.ejie.aa94a.model.config.Vehiculo;
import com.ejie.aa94a.utils.HelpperHtml;
import com.ejie.aa94a.utils.ResultadoPDF;
import com.ejie.aa94a.utils.UtilSolucion;
import com.ejie.aa94a.utils.Utilidades;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * CalculadorController generated by UDA, 30-dic-2015 13:55:11.
 * 
 * @author UDA
 */

@Controller
@RequestMapping(value = "/calculador")
public class CalculadorController {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(CalculadorController.class);

	@Autowired
	private Properties appConfiguration;

	@Autowired
	private ReloadableResourceBundleMessageSource messageSource;

	private final static String INDICADOR_WEB_MOVIL = "M";

	/**
	 * Inicia el calculador
	 * 
	 * @param model
	 *            Model
	 * @param request
	 *            HttpServletRequest
	 * @return String
	 * @throws IOException
	 *             e
	 * @throws JsonMappingException
	 *             e
	 * @throws JsonGenerationException
	 *             e
	 */
	@RequestMapping(value = "inicio", method = RequestMethod.GET)
	public String inicioCalculador(Model model, HttpServletRequest request)
			throws JsonGenerationException, JsonMappingException, IOException {
		CalculadorController.LOGGER.info("[inicioCalculador - Inicio]");
		List<Vehiculo> vehiculos = Configuracion.vehiculos;
		List<TipoSujecion> tiposSujecion = Configuracion.tiposSujecion;
		List<Densidad> densidades = Configuracion.densidades;
		ObjectMapper mapper = new ObjectMapper();
		model.addAttribute("bobinaJson",
				mapper.writeValueAsString(Configuracion.bobina));
		model.addAttribute("flejeJson",
				mapper.writeValueAsString(Configuracion.fleje));

		model.addAttribute("arrayTipoSujeccionJson",
				mapper.writeValueAsString(tiposSujecion));

		model.addAttribute("vehiculos", vehiculos);
		model.addAttribute("tiposSujecion", tiposSujecion);
		model.addAttribute("densidades", densidades);
		boolean esMovil = (request.getContextPath().toUpperCase()
				.indexOf(CalculadorController.INDICADOR_WEB_MOVIL) != -1) ? true
				: false;
		model.addAttribute("idiomaMovil", esMovil);
		CalculadorController.LOGGER.info("[inicioCalculador - Fin]");
		return esMovil ? "ayuda_transporte_movil" : "ayuda_transporte";
	}

	/**
	 * Obtiene el peso estimado de la bobina en función de sus características
	 * 
	 * @param bobina
	 *            Bobina
	 * @return String
	 */
	@RequestMapping(value = "pesoEstimado", method = RequestMethod.POST)
	public @ResponseBody
	String pesoEstimado(@RequestBody Bobina bobina) {
		CalculadorController.LOGGER.info("[pesoEstimado - Inicio]");
		// //////////////////////////
		String resultado = "";
		// Validación de la bobina
		if (!this.validaBobina(bobina)) {
			return resultado;
		}
		resultado = this.calcularPesoEstimado(bobina);
		CalculadorController.LOGGER.info("[pesoEstimado - Fin]");
		return resultado;
	}

	/**
	 * Valida la bobina para poder obtener el peso estimado
	 * 
	 * @param bobina
	 *            Bobina
	 * @return boolean
	 */
	private boolean validaBobina(Bobina bobina) {
		return true;
	}

	/**
	 * Obtiene el peso estimado de la bobina
	 * 
	 * @param bobina
	 *            Bobina
	 * @return String
	 */
	private String calcularPesoEstimado(Bobina bobina) {
		String resultado = "";
		final int numDecimales = 4;
		final int constFormula = 4;
		final int constMil = 1000;
		BigDecimal resul = null;
		BigDecimal result = null;
		Integer dexterior = bobina.getDiametroExt();
		Double diametroext = dexterior.doubleValue() / constMil;
		Integer dinterior = bobina.getDiametroInt();
		Double diametroint = dinterior.doubleValue() / constMil;
		Integer abobina = bobina.getAnchura();
		Double anchurab = abobina.doubleValue() / constMil;
		Densidad densidadb = Configuracion.getDensidad(String.valueOf(bobina
				.getDensidad().getCodigo()));
		BigDecimal vdensidad = densidadb.getValor();
		BigDecimal densidad = BigDecimal.valueOf(vdensidad.doubleValue()
				* constMil);

		resul = BigDecimal.valueOf(((diametroext.doubleValue()
				* diametroext.doubleValue() - diametroint.doubleValue()
				* diametroint.doubleValue())
				* Math.PI * anchurab.doubleValue() * densidad.doubleValue())
				/ constFormula);
		result = BigDecimal.valueOf(resul.doubleValue() / constMil);

		resultado = (Utilidades.format(result, numDecimales));
		return resultado;
	}

	/**
	 * Realiza la validación de
	 * 
	 * @param transporte
	 *            Transporte
	 * @return Solucion
	 */
	@RequestMapping(value = "simular", method = RequestMethod.POST)
	public @ResponseBody
	Resultado realizarSimulacion(@RequestBody Transporte transporte) {
		CalculadorController.LOGGER.info("[realizarSimulacion - Inicio]");
		// //////////////////////////
		Resultado resultado = new Resultado();
		// Validación del transporte
		List<Mensaje> mensajes = this.validarTransporte(transporte);
		resultado.setMensajes(mensajes);
		if (mensajes != null && !mensajes.isEmpty()) {
			return resultado;
		}
		resultado = this.obtenerResultado(transporte);
		if (resultado.getSolucion() == null) {
			// Mensaje de solucion no encontrada
			mensajes.add(UtilSolucion.getMensajeSinSolucion());
		}
		resultado.setMensajes(mensajes);

		CalculadorController.LOGGER.info("[realizarSimulacion - Fin]");
		return resultado;
	}

	/**
	 * Prepara los datos para la generación del documento
	 * 
	 * @param model
	 *            Model
	 * @param transporte
	 *            Transporte
	 * @param session
	 *            HttpSession
	 * @return String
	 */
	@RequestMapping(value = "preparaDatos", method = RequestMethod.POST)
	public @ResponseBody
	String preparaExcel(Model model, @RequestBody Transporte transporte,
			HttpSession session) {
		CalculadorController.LOGGER.info("[preparaExcel - Inicio]");
		// //////////////////////////
		Resultado resultado = this.obtenerResultado(transporte);
		session.setAttribute(Constantes.SESSION_RESULTADO, resultado);
		CalculadorController.LOGGER.info("[preparaExcel - Fin]");
		return "OK";
	}

	/**
	 * Obtiene el resultado de la solución
	 * 
	 * @param transporte
	 *            Transporte
	 * @return Resultado
	 */
	private Resultado obtenerResultado(Transporte transporte) {
		CalculadorController.LOGGER.info("[obtenerResultado - Inicio]");
		// //////////////////////////
		Resultado resultado = new Resultado();
		// Ordena las bobinas por peso en descendente
		Collections.sort(transporte.getBobinas());
		// Realización del cálculo de la solución
		Solucion solucion = UtilSolucion.obtenerSolucion(transporte);
		resultado.setSolucion(solucion);
		// Introduce las bobinas, identificándolas y posicionando en la
		// solución
		if (solucion != null) {
			resultado.setUbicaciones(transporte.getBobinas());
		}
		transporte.setVehiculo(Configuracion.getVehiculo(transporte
				.getVehiculo().getCodigo()));
		transporte.setTipoSujecion(Configuracion.getTipoSujecion(transporte
				.getTipoSujecion().getCodigo()));
		resultado.setTransporte(transporte);
		CalculadorController.LOGGER.info("[obtenerResultado - Fin]");
		return resultado;
	}

	/**
	 * Genera un documento excel con el resultado de la solución
	 * 
	 * @param mostrarGraficos
	 *            boolean
	 * @param model
	 *            Model
	 * @param response
	 *            HttpServletResponse
	 * @param request
	 *            HttpServletRequest
	 * @param session
	 *            HttpSession
	 * @return ModelAndView
	 */
	@RequestMapping(value = "generarExcel", method = RequestMethod.GET)
	public ModelAndView generarExcel(
			@RequestParam(value = "mostrarGraficos", required = true) boolean mostrarGraficos,
			Model model, HttpServletResponse response,
			HttpServletRequest request, HttpSession session) {
		CalculadorController.LOGGER.info("[generarExcel - Inicio]");

		Resultado resultado = (Resultado) session
				.getAttribute(Constantes.SESSION_RESULTADO);
		resultado.setMostrarGraficos(mostrarGraficos);
		session.removeAttribute(Constantes.SESSION_RESULTADO);
		model.addAttribute("messageSource", messageSource);
		model.addAttribute("resultado", resultado);
		model.addAttribute("appConfiguration", appConfiguration);
		CalculadorController.LOGGER.info("[generarExcel - Fin]");
		return new ModelAndView("ResultadoExcel", "model", model);
	}

	/**
	 * Genera un documento excel con el resultado de la solución
	 * 
	 * @param mostrarGraficos
	 *            boolean
	 * @param model
	 *            Model
	 * @param response
	 *            HttpServletResponse
	 * @param request
	 *            HttpServletRequest
	 * @param session
	 *            HttpSession
	 * @return ModelAndView
	 */
	@RequestMapping(value = "generarHtml", method = RequestMethod.GET)
	public ModelAndView generarHtml(
			@RequestParam(value = "mostrarGraficos", required = true) boolean mostrarGraficos,
			Model model, HttpServletResponse response,
			HttpServletRequest request, HttpSession session) {
		CalculadorController.LOGGER.info("[generarHtml - Inicio]");

		response.setCharacterEncoding("ISO-8859-1");

		response.setContentType(Constantes.CONTENTTYPE_HTML);
		response.setHeader("Content-Disposition",
				"inline;filename=SolucionBobinas.html");
		Resultado resultado = (Resultado) session
				.getAttribute(Constantes.SESSION_RESULTADO);
		resultado.setMostrarGraficos(mostrarGraficos);
		// /////////////////////////////////////////////////
		// /////////////////////////////////////////////////
		// /NECESARIO PARA PDF, BUG HTTPS IE 6, 7, 8 ///////
		// /////////////////////////////////////////////////

		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		response.setHeader("Cache-Control", "maxage=3600");
		response.setHeader("Pragma", "public");
		response.setHeader("Accept-Ranges", "none");
		// /////////////////////////////////////////////////
		// /////////////////////////////////////////////////

		try {
			PrintWriter stb = response.getWriter();
			this.generaHtmlResultado(stb, resultado, request);
			session.removeAttribute(Constantes.SESSION_RESULTADO);
		} catch (IOException e) {
			CalculadorController.LOGGER.error("[Error - generarExcel]", e);
		}

		CalculadorController.LOGGER.info("[generarHtml - Fin]");
		// generar descarga Excel

		return null;
	}

	/**
	 * Obtiene la descripción del literal en el idioma indicado
	 * 
	 * @param code
	 *            String
	 * @param locale
	 *            Locale
	 * @return String
	 */
	private String getLiteral(String code, Locale locale) {
		return this.messageSource.getMessage(code, null, locale);

	}

	/**********************************************************************************/

	// ////////////////////////////////
	// GENERAMOS EL DOCUMENTO HTML ///
	// ////////////////////////////////

	/**
	 * @param stb
	 *            PrintWriter
	 * @param resultado
	 *            Resultado
	 * @param request
	 *            HttpServletRequest
	 * @param mostrarGraficos
	 *            boolean
	 */
	private void generaHtmlResultado(PrintWriter stb, Resultado resultado,
			HttpServletRequest request) {
		Locale locale = LocaleContextHolder.getLocale();
		// String rutaStatics = (String)
		// this.appConfiguration.get("statics.path");
		String rutaDatos = (String) this.appConfiguration.get("ruta.image");
		String url = request.getRequestURL().toString();
		/* "http://desarrollo.jakina.ejiedes.net:7001" */
		String path = new StringBuffer(url.substring(0,
				url.indexOf("/calculador")))
				.append("/PintaImagenServlet?ruta=").append(rutaDatos)
				.toString();
		Transporte transporte = resultado.getTransporte();
		transporte.setVehiculo(Configuracion.getVehiculo(transporte
				.getVehiculo().getCodigo()));
		transporte.setTipoSujecion(Configuracion.getTipoSujecion(transporte
				.getTipoSujecion().getCodigo()));

		// TEXTO DE LA SOLUCION
		String textoVehiculo = (locale.equals(Constantes.LOCALE_EU)) ? transporte
				.getVehiculo().getDescEu() : transporte.getVehiculo()
				.getDescEs();
		String textoTipoSujecion = (locale.equals(Constantes.LOCALE_EU)) ? transporte
				.getTipoSujecion().getDescEu() : transporte.getTipoSujecion()
				.getDescEs();
		String textoDescTransporte = (locale.equals(Constantes.LOCALE_EU)) ? resultado
				.getTipoDistancia().getDescEu() : resultado.getTipoDistancia()
				.getDescEs();

		// DATOS DE LA SOLUCION DEL TRANSPORTE
		List<Bobina> bobinas = transporte.getBobinas();
		List<Estiba> estibas = resultado.getSolucion().getEstibas();
		stb.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
		// HEAD
		stb.append("<head>");
		stb.append("<meta name=\"extended-properties:Application\" content=\"Microsoft Excel\"/>");
		stb.append("<meta name=\"Content-Type\" content=\""
				+ Constantes.CONTENTTYPE_OCTET_STREAM + "\" />");
		/*
		 * stb.append("<link href=\"" + rutaStatics +
		 * "/aa94a/styles/bootstrap.min.css\" rel=\"stylesheet\">");
		 * stb.append("<link href=\"" + rutaStatics +
		 * "/aa94a/styles/bobinas.css\" rel=\"stylesheet\">");
		 */
		stb.append("<title></title>");
		stb.append("</head>");
		// BODY
		stb.append("<body>");
		// TABLA
		stb.append("<table border='0'>");
		// TITULO SIMULACION
		stb.append("<tr>");
		stb.append("<td colspan='5' align='center' bgcolor='#337ab7'><font color='white'><b>"
				+ getLiteral(Constantes.LABEL_DATOS_TITULO, locale)
				+ "</b></font>");
		stb.append("</td>");
		stb.append("</tr>");

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		// FIN LINEA EN BLANCO

		// DATOS VEHICULO
		stb.append("<tr>");
		stb.append("<td><b>" + getLiteral(Constantes.LABEL_DATOS_VEH, locale)
				+ "</b>:</td>");
		stb.append("<td colspan='3'>" + textoVehiculo + "</td>");
		stb.append("<td></td>");
		stb.append("</tr>");

		// DATOS TIPO SUJECION
		stb.append("<tr>");
		stb.append("<td>");
		stb.append("<b>" + getLiteral(Constantes.LABEL_DATOS_TIPOSUJ, locale)
				+ "</b>: ");
		stb.append("</td>");
		stb.append("<td colspan='3'>" + textoTipoSujecion + "</td>");
		stb.append("<td></td>");
		stb.append("</tr>");

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		// FIN LINEA EN BLANCO

		/*
		 * stb.append("<tr>");
		 * stb.append("<td colspan='3' align='center'  bgcolor='#337ab7''>");
		 * stb.append("<font color='white'>");
		 * stb.append(getLiteral(Constantes.LABEL_TXT_TABLA, locale));
		 * stb.append("</font>"); stb.append("</td>"); stb.append("<td></td>");
		 * stb.append("<td></td>"); stb.append("<td></td>");
		 * stb.append("<td></td>"); stb.append("</tr>");
		 */

		// INICIO TABLA BOBINAS
		/*
		 * stb.append("<tr>"); stb.append("<td colspan='4'>");
		 * HelpperExcel.pintaBobinas(stb,
		 * getLiteral(Constantes.LABEL_SOL_ANCHURA, locale),
		 * getLiteral(Constantes.LABEL_SOL_DIAMETROEXT, locale),
		 * getLiteral(Constantes.LABEL_SOL_PESO, locale), bobinas);
		 * stb.append("</td>"); stb.append("<td></td>");
		 * stb.append("<td></td>"); stb.append("<td></td>");
		 * stb.append("<td></td>"); stb.append("<td></td>");
		 * stb.append("</tr>");
		 */
		// FIN BOBINAS

		// LINEA EN BLANCO
		/* HelpperExcel.pintaSaltoDeLinea(stb); */
		// FIN LINEA EN BLANCO

		// TITULO SIMULACION
		stb.append("<tr>");
		stb.append("<td align='center' colspan='5' bgcolor='#337ab7'><font color='white'><b>"
				+ getLiteral(Constantes.LABEL_SOL_TITULO1, locale)
				+ "</b></font></td>");
		stb.append("</tr>");
		// FIN TITULO SIMULACION

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		// FIN LINEA EN BLANCO

		// POSICIONAMIENTO
		stb.append("<tr>");
		stb.append("<td colspan='5' align='center'  bgcolor='#337ab7''><font color='white'>"
				+ getLiteral(Constantes.LABEL_SOL_TITULO3, locale)
				+ "</font></td>");
		stb.append("</tr>");

		// INICIO TABLA POSICIONAMIENTO
		stb.append("<tr>");
		stb.append("<td colspan='5'>");
		HelpperHtml.pintaBobinasSolucion(stb,
				getLiteral(Constantes.LABEL_SOL_ID, locale),
				getLiteral(Constantes.LABEL_SOL_ANCHURA, locale),
				getLiteral(Constantes.LABEL_SOL_DIAMETROEXT, locale),
				getLiteral(Constantes.LABEL_SOL_PESO, locale),
				getLiteral(Constantes.LABEL_SOL_DISTANCIA, locale), bobinas);
		stb.append("</td>");
		stb.append("</tr>");
		// FIN POSICIONAMIENTO

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		// LINEA EN BLANCO

		// ACLARACION POSICIONAMIENTO
		stb.append("<tr>");
		stb.append("<td colspan='5'>(*)." + textoDescTransporte + "</td>");
		stb.append("</tr>");
		// FIN ACLARCION

		// IMAGEN POSICIONAMIENTO
		stb.append("<tr>");
		/*
		 * stb.append("<td colspan='3' rowspan='5'><img src='" + rutaDatos +
		 * "/aa94a/images/" + resultado.getGrafico() + "'width='400'/></td>");
		 */
		if (resultado.isMostrarGraficos()) {
			stb.append("<td colspan='5' align='center' rowspan='5'><img src='"
					.concat(path).concat(resultado.getGrafico()).concat("&")
					.concat(Constantes.PORTAL_NOPORTAL)
					.concat("' width='400'/></td>"));
		} else {
			stb.append("<td colspan='5'></td>");
		}
		stb.append("</tr>");
		// FIN IMAGEN POSICIONAMIENTO

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		HelpperHtml.pintaSaltoDeLinea(stb);
		// FIN LINEA EN BLANCO

		// ESTIBAS
		stb.append("<tr>");
		stb.append("<td colspan='5' align='center'  bgcolor='#337ab7''><font color='white'>"
				+ getLiteral(Constantes.LABEL_SOL_TITULO5, locale)
				+ "</font></td>");
		stb.append("</tr>");

		// TABLA ESTIBAS
		stb.append("<tr>");
		stb.append("<td colspan='5'>");
		HelpperHtml.pintarEstibas(stb,
				getLiteral(Constantes.LABEL_TXT_ESTIBAS, locale), path, locale,
				estibas, resultado.isMostrarGraficos());
		// FIN TABLA ESTIBAS
		stb.append("</td>");
		stb.append("</tr>");
		// FIN ESTIBAS

		// LINEA EN BLANCO
		HelpperHtml.pintaSaltoDeLinea(stb);
		// FIN LINEA EN BLANCO

		// RECOMENDACIONES
		HelpperHtml.pintaRecomendacion(stb,
				getLiteral(Constantes.LABEL_TXT_INT2, locale),
				getLiteral(Constantes.LABEL_TXT_INT3, locale),
				getLiteral(Constantes.LABEL_INT_DIAMETROEXT, locale),
				getLiteral(Constantes.LABEL_INT_DIAMETROINT, locale),
				getLiteral(Constantes.LABEL_INT_ANCHURA, locale),
				getLiteral(Constantes.LABEL_TXT_INT4, locale),
				getLiteral(Constantes.LABEL_INT_PESO, locale),
				getLiteral(Constantes.LABEL_PESO_BOBINA, locale),
				getLiteral(Constantes.LABEL_DIAMETRO_EXT, locale),
				getLiteral(Constantes.LABEL_DIAMETRO_INT, locale),
				getLiteral(Constantes.LABEL_ANCHURA_BOBINA, locale), path,
				resultado.isMostrarGraficos());

		stb.append("</table>");
		// FIN TABLE
		stb.append("</body>");
		// FIN BODY
		stb.append("</html>");
	}

	/**
	 * Realiza las validaciones del transporte
	 * 
	 * @param transporte
	 *            Transporte
	 * @return List<Mensaje>
	 */
	private List<Mensaje> validarTransporte(Transporte transporte) {
		List<Mensaje> mensajes = new ArrayList<Mensaje>();
		return mensajes;
	}

	// //////////////////////////////
	// GENERAMOS EL DOCUMENTO PDF //
	// ////////////////////////////

	/**
	 * Genera un documento de préstamo en formato PDF, a partir de un
	 * identificador de préstamo.
	 * 
	 * @param mostrarGraficos
	 *            boolean
	 * @param response
	 *            HttpServletResponse
	 * @param session
	 *            HttpSession
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/generarPdf", method = RequestMethod.GET)
	public ModelAndView generarPdf(
			@RequestParam(value = "mostrarGraficos", required = true) boolean mostrarGraficos,
			HttpServletResponse response, HttpSession session) {
		CalculadorController.LOGGER
				.info("CalculadorController generarPdf Inicio");
		try {
			BufferedOutputStream out = null;
			response.setCharacterEncoding("UTF-8");
			response.setContentType(Constantes.CONTENTTYPE_PDF);
			response.setHeader("Content-Disposition",
					"inline;filename=SolucionBobinas.pdf");
			// /////////////////////////////////////////////////
			// /////////////////////////////////////////////////
			// /NECESARIO PARA PDF, BUG HTTPS IE 6, 7, 8 ///////
			// /////////////////////////////////////////////////
			response.setHeader("Expires", "0");
			response.setHeader("Cache-Control", "private");
			response.setHeader("Cache-Control", "maxage=3600");
			response.setHeader("Pragma", "public");
			response.setHeader("Accept-Ranges", "none");
			// /////////////////////////////////////////////////
			// /////////////////////////////////////////////////
			// /////////////////////////////////////////////////
			// /////////////////////////////////////////////////

			Resultado resultado = (Resultado) session
					.getAttribute(Constantes.SESSION_RESULTADO);
			// ////////////////////////////////////////////
			// GENERAMOS EL DOCUMENTO
			out = new BufferedOutputStream(response.getOutputStream());
			out.write(this.getPDF(resultado, mostrarGraficos));
			session.removeAttribute(Constantes.SESSION_RESULTADO);
		} catch (IOException e) {
			CalculadorController.LOGGER.error(
					"CalculadorController IOException", e);
		} catch (DocumentException e) {
			CalculadorController.LOGGER.error(
					"CalculadorController DocumentException", e);
		}
		CalculadorController.LOGGER.info("CalculadorController generarPdf Fin");
		return null;
	}

	/**
	 * genera un PDF con el resultado de la simulación
	 * 
	 * @param resultado
	 *            Resultado
	 * @param mostrarGraficos
	 *            boolean
	 * @return byte[]
	 * @throws DocumentException
	 *             e
	 * @throws IOException
	 *             e
	 */
	private byte[] getPDF(Resultado resultado, boolean mostrarGraficos)
			throws DocumentException, IOException {

		// creamos el documento
		Locale locale = LocaleContextHolder.getLocale();
		// String rutaStatics = (String)

		String rutaDatos = (String) this.appConfiguration.get("ruta.image");
		Transporte transporte = resultado.getTransporte();
		transporte.setVehiculo(Configuracion.getVehiculo(transporte
				.getVehiculo().getCodigo()));
		transporte.setTipoSujecion(Configuracion.getTipoSujecion(transporte
				.getTipoSujecion().getCodigo()));

		// TEXTO DE LA SOLUCION
		String textoVehiculo = (locale.equals(Constantes.LOCALE_EU)) ? transporte
				.getVehiculo().getDescEu() : transporte.getVehiculo()
				.getDescEs();
		String textoTipoSujecion = (locale.equals(Constantes.LOCALE_EU)) ? transporte
				.getTipoSujecion().getDescEu() : transporte.getTipoSujecion()
				.getDescEs();
		String textoDescTransporte = (locale.equals(Constantes.LOCALE_EU)) ? resultado
				.getTipoDistancia().getDescEu() : resultado.getTipoDistancia()
				.getDescEs();

		Document documentResultado = new Document(ConstantesPDF.PAGE_SIZE_DOC,
				ConstantesPDF.MARG_LEFT_DOC, ConstantesPDF.MARG_RIGHT_DOC,
				ConstantesPDF.MARG_TOP_DOC, ConstantesPDF.MARG_BOTTON_DOC);

		String imagen = (String) this.appConfiguration
				.get(ConstantesPDF.RUTA_IMG_PDF);

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PdfWriter writerResolucion = PdfWriter.getInstance(documentResultado,
				baos);

		documentResultado.open();
		// APARTADO DE LA SOLUCION
		String parrafo1Sol = getLiteral(Constantes.LABEL_SOL_TITULO1, locale);
		String tituloPosiciones = getLiteral(Constantes.LABEL_SOL_TITULO3,
				locale);
		String parrafo22Sol = textoDescTransporte;
		String imagenSol = rutaDatos + resultado.getGrafico();
		String parrafo24Sol = getLiteral(Constantes.LABEL_SOL_TITULO5, locale);
		String tituloTabla = getLiteral(Constantes.LABEL_TXT_ESTIBAS, locale);

		// APARTADOS DE DATOS DE LA CARGA
		String parrafo1Datos = getLiteral(Constantes.LABEL_DATOS_TITULO, locale);
		String parrafo21Datos = getLiteral(Constantes.LABEL_DATOS_VEH, locale);
		String parrafo22Datos = textoVehiculo;
		String parrafo23Datos = getLiteral(Constantes.LABEL_DATOS_TIPOSUJ,
				locale);
		String parrafo24Datos = textoTipoSujecion;
		String tituloBobinas = getLiteral(Constantes.LABEL_TXT_TABLA, locale);
		String imagenRec = rutaDatos + Constantes.IMG_RECOMENDACION;

		// DATOS BOBINAS
		String tituloId = getLiteral(Constantes.LABEL_SOL_ID, locale);
		String tituloAnchura = getLiteral(Constantes.LABEL_SOL_ANCHURA, locale);
		String tituloDiametroext = getLiteral(Constantes.LABEL_SOL_DIAMETROEXT,
				locale);
		String tituloPeso = getLiteral(Constantes.LABEL_SOL_PESO, locale);
		String tituloDistancia = getLiteral(Constantes.LABEL_SOL_DISTANCIA,
				locale);

		// RECOMENDACIONES

		String parrafo1Rec = getLiteral(Constantes.LABEL_TXT_INT2, locale);
		String parrafo2rec = getLiteral(Constantes.LABEL_TXT_INT3, locale);
		String intdiametroExt = getLiteral(Constantes.LABEL_INT_DIAMETROEXT,
				locale);
		String intdiametroInt = getLiteral(Constantes.LABEL_INT_DIAMETROINT,
				locale);
		String intanchura = getLiteral(Constantes.LABEL_INT_ANCHURA, locale);
		String intpeso = getLiteral(Constantes.LABEL_INT_PESO, locale);

		String parrafo3rec = getLiteral(Constantes.LABEL_TXT_INT4, locale);
		String pesobobinas = getLiteral(Constantes.LABEL_PESO_BOBINA, locale);
		String diametroextbobinas = getLiteral(Constantes.LABEL_DIAMETRO_EXT,
				locale);
		String diametrointbobinas = getLiteral(Constantes.LABEL_DIAMETRO_INT,
				locale);
		String anchurabobinas = getLiteral(Constantes.LABEL_ANCHURA_BOBINA,
				locale);

		ResultadoPDF.generateDocumentoResultado(writerResolucion,
				documentResultado, resultado, imagen, parrafo1Sol,
				tituloPosiciones, parrafo22Sol, imagenSol, parrafo24Sol,
				tituloTabla, parrafo1Datos, parrafo21Datos, parrafo22Datos,
				parrafo23Datos, parrafo24Datos, tituloBobinas, tituloId,
				tituloAnchura, tituloDiametroext, tituloPeso, tituloDistancia,
				parrafo1Rec, parrafo2rec, intdiametroExt, intdiametroInt,
				intanchura, intpeso, parrafo3rec, pesobobinas,
				diametroextbobinas, diametrointbobinas, anchurabobinas,
				imagenRec, rutaDatos, mostrarGraficos);

		documentResultado.close();
		writerResolucion.flush();
		writerResolucion.close();
		return baos.toByteArray();

	}

	// /**
	// * Metodo para probar los diferentes casos
	// *
	// */
	// @RequestMapping(value = "testearSoluciones", method = {
	// RequestMethod.GET,
	// RequestMethod.POST })
	// public void testearSoluciones() {
	// CalculadorController.LOGGER.info("[testearSoluciones - Inicio]");
	// // Veh1
	// UtilPruebas.testearVeh1Suj1();
	// UtilPruebas.testearVeh1Suj2();
	// UtilPruebas.testearVeh1Suj3();
	// UtilPruebas.testearVeh1Suj4();
	// // Veh2
	// UtilPruebas.testearVeh2Suj1();
	// UtilPruebas.testearVeh2Suj2();
	// UtilPruebas.testearVeh2Suj3();
	// UtilPruebas.testearVeh2Suj4();
	// // Veh3
	// UtilPruebas.testearVeh3Suj1();
	// UtilPruebas.testearVeh3Suj2();
	// UtilPruebas.testearVeh3Suj3();
	// UtilPruebas.testearVeh3Suj4();
	// // Veh4
	// UtilPruebas.testearVeh4Suj1();
	// UtilPruebas.testearVeh4Suj2();
	// UtilPruebas.testearVeh4Suj3();
	// UtilPruebas.testearVeh4Suj4();
	// CalculadorController.LOGGER.info("[testearSoluciones - Fin]");
	// }

}
