package org.infohazard.maverick.opt.transform;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.fop.apps.Driver;
import org.apache.fop.apps.FOPException;
import org.infohazard.maverick.flow.Transform;
import org.xml.sax.InputSource;

public class FopTransform implements Transform {

	protected TransformerFactory tFactory = TransformerFactory.newInstance();
	
	public FopTransform() {}

	public void go(Reader input, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		InputSource is = new InputSource(input);
		go(is, request, response);
	}
	
	public void go(String input, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		StringReader reader = new StringReader(input);
		go(reader, request, response);
	}

	public void go(Source input, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		InputSource is = SAXSource.sourceToInputSource(input);
		if (is!=null)
		{
			go(is, request, response);

		}
		else
		{ //unable to convert input to InputSource

			// Use JAXP 1.1 transform api to make copy of dom to String
			try
			{
				Transformer trans = tFactory.newTransformer();
				trans.setOutputProperty(OutputKeys.INDENT, "no");
	
				StringWriter output = new StringWriter();
				Result res = new StreamResult(output);
	
				trans.transform(input, res);
	
				this.go(output.toString(), request, response);
			}
			catch (TransformerException ex)
			{
				throw new ServletException(ex);
			}
		}
	}
	
	private void go(InputSource input, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Driver driver = new Driver();
		driver.setRenderer(Driver.RENDER_PDF);
		driver.setInputSource(input);
		driver.setOutputStream(baos);

	    try
	    {
			driver.run();
		}
		catch (FOPException ex)
		{
			throw new ServletException(ex);	
		}
		
		response.setContentType("application/pdf");
		response.setContentLength(baos.size());
		OutputStream out = response.getOutputStream();
		baos.writeTo(out);
	}
}