package utiliServlet;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.StringWriter;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import m05bClasses.m05bFileLog;

import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.fop.apps.Driver;
import org.apache.fop.messaging.MessageHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * Clase para generar PDFS
 * 
 * @author co00610a
 * 
 */
public class m05bPdfMaker {
	private static org.apache.log4j.Logger logger = org.apache.log4j.Logger
			.getLogger(m05bPdfMaker.class);
	private String idioma;

	public m05bPdfMaker(String idioma) {

		// System.out.println("hola"+idioma);
		this.idioma = idioma;
	}

	/**
	 * Crea un documento XML con el String de entrada
	 * 
	 * @param xml
	 *            String XML
	 * @return document
	 */
	public Document createDocument(String xml) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			Document doc = factory.newDocumentBuilder().parse(
					new ByteArrayInputStream(xml.getBytes()));
			return doc;
		} catch (Exception e) {
			   m05bFileLog miLog = new m05bFileLog();
			miLog.addTraza(e);
		}
		return null;
	}

	/**
	 * Método para generar un PDF en el Objeto response
	 * 
	 * @param response
	 *            Salida (normalmente web)
	 * @param xml
	 *            String XML
	 * @param plantilla
	 *            plantilla XSL-FO para generar el PDF
	 * @throws Exception
	 *             error
	 */
	public void generarPDF(HttpServletResponse response, Document doc,
			String plantilla) throws Exception {
		logger.info("Generando PDF");
		// logger.info(doc.);
		try {
			if (idioma == null || idioma.length() == 0 || idioma.equals("ES"))
				plantilla = plantilla.replaceAll("IDIOMAX", "es");
			else
				plantilla = plantilla.replaceAll("IDIOMAX", "eu");
		} catch (Exception e) {
			plantilla = plantilla.replaceAll("IDIOMAX", "es");
		}
		logger.info(plantilla);
		logger.info(nodeToString(doc));
		// System.out.println(xml);
		// Document doc=createDocument(xml);
		// Construct driver
		Driver driver = new Driver();
		response.setContentType("application/pdf");
		OutputStream out = response.getOutputStream();

		// uramos el logger
		Logger logger2 = new ConsoleLogger(ConsoleLogger.LEVEL_FATAL);
		MessageHandler.setScreenLogger(logger2);
		driver.setLogger(logger2);
		logger.info("traza1");
		
		// Setup Renderer (output format)
		driver.setRenderer(Driver.RENDER_PDF);

		driver.setOutputStream(out);
		logger.info("traza2");
		TransformerFactory factory = TransformerFactory.newInstance();
		// Transformer transformer = factory.newTransformer(new
		// StreamSource(xsltfile));
		// Transformer transformer = factory.newTransformer(new
		// StreamSource(getClass().getResourceAsStream(plantilla)));
		// Transformer transformer = factory.newTransformer(new StreamSource(new
		// DataInputStream (new URL(plantilla).openStream())));
		Transformer transformer = factory.newTransformer(new StreamSource(
				new DataInputStream(new FileInputStream(plantilla))));
		// Set the value of a <param> in the stylesheet
		// transformer.setParameter("versionParam", "2.0");

		// Setup input for XSLT transformation
		DOMSource src = new DOMSource(doc);
		logger.info("traza3");
		// Source src = new StreamSource(xmlfile.openStream());
		// Resulting SAX events (the generated FO) must be piped through to FOP
		Result res = new SAXResult(driver.getContentHandler());
		logger.info("traza4");
		// Start XSLT transformation and FOP processing
		transformer.transform(src, res);

	}

	private String nodeToString(Node node) {// element

		StringWriter sw = new StringWriter();

		try {

			Transformer t = TransformerFactory.newInstance().newTransformer();

			t.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");

			t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");

			t.setOutputProperty(OutputKeys.INDENT, "yes");

			t.transform(new DOMSource(node), new StreamResult(sw));

		} catch (TransformerException te) {

			StackTraceElement[] stackTraceElements = Thread.currentThread()

			.getStackTrace();

			for (StackTraceElement stackTrace : stackTraceElements) {

				logger.error(stackTrace.getClassName() + "  "

				+ stackTrace.getMethodName() + " "

				+ stackTrace.getLineNumber());

			}

		//	System.out.println("nodeToString Transformer Exception");

		}

		return sw.toString();

	}

}
