/*
 * PDFCreator.java
 *
 * Created on 19 de Abril de 2006, 18:20
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package siprp.util.fop;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.swing.JFileChooser;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.xmlgraphics.util.MimeConstants;


/**
 * PDFCreator creates PDF's using FO.
 * 
 * @author Frederico Palma
 * @author João Neto
 * @version %I%, %G%
 */
public class PDFCreator
{
	// private final Translator translator = new SecureResourceBundle( null );

	private static final Object LOCK = new Object();

	private static PDFCreator pdfCreator;
	FopFactory fopFactory;

	private static File userConfig;

	
	public static PDFCreator getPDFCreator()
	{
		synchronized (LOCK) 
		{
			if (pdfCreator == null)
			{
				pdfCreator = new PDFCreator();
			}
		}
		return pdfCreator;
	}

	public static File getUserConfig()
	{
		return userConfig;
	}

	public static void setUserConfig(File userConfig)
	{
		PDFCreator.userConfig = userConfig;
	}

	public static void main(String arg[]) throws Exception
	{
		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
		final FOPCreator creator = FOPCreator.getFOPCreator();
		System.out.println("Creating FO");

		JFileChooser chooser = new JFileChooser();
		chooser.setDialogTitle("Select XML data file:");
		int returnVal = chooser.showOpenDialog(null);
		String dataFile = null;
		if (returnVal == JFileChooser.APPROVE_OPTION)
		{
			dataFile = chooser.getSelectedFile().getAbsolutePath();
		}
		chooser.setDialogTitle("Select XSL-FO template file:");
		returnVal = chooser.showOpenDialog(null);
		String templateFile = null;
		if (returnVal == JFileChooser.APPROVE_OPTION)
		{
			templateFile = chooser.getSelectedFile().getAbsolutePath();
			System.out.println(chooser.getSelectedFile().getAbsolutePath());
		}

		final String DATA = dataFile;
		final String TEMPLATE = templateFile;
		creator.createFOfromXML(new FileInputStream(DATA), new FileInputStream(TEMPLATE), baos);
		// Thread t = new Thread() {
		// public void run()
		// {
		// try
		// {
		// creator.createFOfromXML( new FileInputStream( DATA ),
		// new FileInputStream( TEMPLATE ), baos );
		// System.out.println( "FO created" );
		// }
		// catch( Exception ex )
		// {
		// ex.printStackTrace();
		// }
		// } };
		// t.start();
		// Thread.currentThread().sleep( 2 );
		System.out.println("Starting to print");
		// options.put( FOP_DUPLEX_TYPE,
		// javax.print.attribute.standard.Sides.TUMBLE );
		byte pdf[] = PDFCreator.getPDFCreator().createPdfFromFo(baos.toByteArray());
		// new FOPPrinter().printFO( new FileInputStream( "c:\\simplecol.fo" ),
		// true, false );
		File pdfFile = new File("/home/jneto/Desktop/teste.pdf");
		File foFile = new File("/home/jneto/Desktop/teste.fo");
		pdfFile.createNewFile();
		foFile.createNewFile();
		FileOutputStream fos = new FileOutputStream(pdfFile);
		FileOutputStream fofos = new FileOutputStream(foFile);
		fos.write(pdf);
		fofos.write(baos.toByteArray());
		fos.close();
		fofos.close();
		System.out.println("DONE");
	}

//	/** Creates a new instance of PDFCreator */
//	private PDFCreator()
//	{
//		fopFactory = FopFactory.newInstance();
//	}
	
	/** Creates a new instance of PDFCreator */
	private PDFCreator()
	{
		fopFactory = FopFactory.newInstance();
		if (userConfig != null)
		{
			try
			{
				fopFactory.setUserConfig(userConfig);
			} catch (Exception e)
			{
				System.err.println("Ignoring invalid user config file");
				e.printStackTrace();
			}
		}
	}
	
	

	/**
	 * Creates PDF content as an array of bytes, given FO content as an array of
	 * bytes.
	 * 
	 * @param fo
	 *            the byte[] with the FO content to convert
	 * @return the PDF content
	 * @throws Exception
	 *             if the conversion fails
	 * 
	 */
	public byte[] createPdfFromFo(byte[] fo) throws Exception
	{

		fopFactory.setStrictValidation(false);

		ByteArrayOutputStream pdf = new ByteArrayOutputStream();
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer = factory.newTransformer();
		FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

		Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdf);

		Source src = new StreamSource(new ByteArrayInputStream(fo));
		Result res = new SAXResult(fop.getDefaultHandler());

		transformer.transform(src, res);

		return pdf.toByteArray();

	}
}
