/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.patient.gui.reports;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.tetrasix.majix.rtf.RtfAnalyser;
import com.tetrasix.majix.rtf.RtfDocument;
import com.tetrasix.majix.rtf.RtfReader;
import com.tetrasix.majix.templates.ConversionTemplateFactory;
import com.tetrasix.majix.xml.ConversionTemplate;
import com.tetrasix.majix.xml.XmlGenerator;
import com.tetrasix.majix.xml.XmlGeneratorParam;
import com.tetrasix.majix.xml.XmlWriter;
import com.tetrasix.util.Configuration;

/**
 * class to convert RTF reports to xml and html for display purposes.
 * uses  majix for rtf to xml conversion and xsl for xml to html conversion 
 * 
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @version
 * <br>$Log: RTFReportTranslator.java,v $
 * <br>Revision 1.6  2013-12-27 18:09:26  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.5  2013-07-15 06:18:37  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.4  2008-09-25 09:43:06  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.3  2008-01-21 15:14:16  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 *
 */
public class RTFReportTranslator {

	private static Logger logger = Logger.getLogger(RTFReportTranslator.class
			.getName());
	
	private boolean debug = false;
	private boolean dump;
	private String templatename= "mydoc";
	private ConversionTemplate template;
	private StringBuffer headerText = new StringBuffer();
	private XmlGenerator xmlGenerator;
	private Templates templates;
	
	private static final String tempDir = System.getProperty("java.io.tmpdir") + File.separator;
	private static final String DTD_NAME = "chemReport";
	private static final String DTD_FILE = tempDir + "chemReport.dtd";
	public static final InputStream XSL_FILE_STREAM = RTFReportTranslator.class.getResourceAsStream("chemReport.xsl");

	
	public RTFReportTranslator() {
		initConverter();
	}
	
	
	/**
	 * initialize the converter
	 */
	private void initConverter() {

		// init majix
		Configuration.init("majix", true);	
		
		ConversionTemplateFactory factory = new ConversionTemplateFactory();
		this.template = factory.getConversionTemplate(templatename);	
		
		// load the needed dtd
		if (! new File(DTD_FILE).canRead()) {
			try {
				InputStream fis = RTFReportTranslator.class.getResourceAsStream("chemReport.dtd");
				OutputStream fos = new FileOutputStream(DTD_FILE);
				byte[] buf = new byte[1024];
			    int i = 0;
			    while((i=fis.read(buf))!=-1) {
			      fos.write(buf, 0, i);
			      }
			    fis.close();
			    fos.close();
			} catch (Exception e) {
				logger.log(Level.WARN, "initializing converter failed", e);
			}
		}
		
		
		this.template.getGeneratorParam().setDtdName(DTD_NAME);
		this.template.getGeneratorParam().setDtdSystemId(DTD_FILE);
		
		// create a new xml generator
        xmlGenerator = new XmlGenerator(template);
		
        // build a default xml header
        buildXMLHeader();

	}
	
	/**
	 * creates a valid xml header
	 */
	public void buildXMLHeader() {
		String is_xml = template.getGeneratorParam().getAttributes("ix");
        XmlGeneratorParam param = template.getGeneratorParam();
		
        param.getDtdName();
        
        
        if ((is_xml != null) && is_xml.equals("true")) {
            String pi = "<?xml version=\"1.0\"";
            String encoding = param.getActualTag("ec", true);
            if (!encoding.equals("")) {
                pi = pi + " encoding=\"" + encoding + "\"";
            }
            String standalone = param.getActualTag("sa", true);
            if (!standalone.equals("")) {
                if (standalone.equals("true")) {
                    pi = pi + " standalone=\"yes\"";
                } else {
                    pi = pi + " standalone=\"no\"";
                }
            }
            pi = pi + "?>";
            headerText.append(pi + "\n");
        }
        if (!param.getActualTag("sn", true).equals("")
                && !param.getActualTag("st", true).equals("")) {
        }
	}
	
	
	/**
	 * converts the given rtf stream to an xml stream
	 * @param inStream rtf input stream
	 * @param outStream xml output stream
	 */
	public void convert2XML(InputStream inStream, OutputStream outStream) {
		long start = System.currentTimeMillis();
		try {

			// create The Reader for the input rtf File
			RtfReader reader = new RtfReader(inStream);

			// create a writer for the new XML File
	        BufferedOutputStream bos = new BufferedOutputStream(outStream);
	        XmlWriter xw = new XmlWriter(bos);
	
	        RtfAnalyser ana = new RtfAnalyser(reader, xw);
	        RtfDocument doc;
			doc = ana.parse();

			xw.println(headerText.toString());

			// for debugging purpose
	        if (dump) {
	        	headerText.append("<!-- dump of the DOCRTF intermediate structure");
	            doc.Dump(xw);
	            xw.println("-->");
	        }
			
	        xmlGenerator.reset();
	        xmlGenerator.setDebugFlag(debug);
	        xmlGenerator.generate(doc, xw, null);
	
	        xw.flush();
	        xw.close();

		}catch (Exception e) {
			logger.log(Level.WARN, "converting rtf to xml failed", e);
		}
		
		logger.info("RTF2XML conversion took: " + (System.currentTimeMillis()-start));
	}
	
	/**
	 * set the used xsl template for xml->html conversion
	 * @param templateStream
	 * @throws TransformerConfigurationException
	 */
	public void setXSLTemplate(InputStream templateStream) throws TransformerConfigurationException {
		TransformerFactory tFactory = TransformerFactoryImpl.newInstance();
		StreamSource source = new StreamSource(templateStream);
        templates = tFactory.newTemplates(source);
	}
	
	/**
	 * converts the given xml stream to a html stream using the set xsl file
	 * @param inStream given xml input stream
	 * @param outStream generated html output stream
	 * @throws TransformerException
	 */
	public void convert2HTML(InputStream inStream, OutputStream outStream) throws TransformerException {
		 long start = System.currentTimeMillis();
         Transformer transformer = templates.newTransformer();
         StreamSource sourceXML = new StreamSource(inStream);
         StreamResult result = new StreamResult(outStream);
         transformer.transform(sourceXML, result);
         logger.info("XML2HTML conversion took: " + (System.currentTimeMillis()-start));
	}
	
}
