/*
 * XMLUtils.java
 * Created on 2005.06.11.
 * Author:  Laszlo Felfoldi, Etixpert GmbH 
 * mail:    laszlo.felfoldi@etixpert.com
 */
package com.etixpert.evolution.app.utils;

import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

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.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.Driver;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.transform.JDOMSource;



public class XMLUtils {
	public static void getIds(Element src, Map from, Map target) {
		for (Iterator it = src.getChildren().iterator(); it.hasNext();) {
			Element e = (Element) it.next();
			Integer key = new Integer(e.getAttributeValue("Id"));
			target.put(key, from.get(key));
			getIds(e, from, target);
		}
	}
	
	public static boolean filter(Element e, Element dst, String id) {
		org.apache.log4j.Logger logger = com.etixpert.evolution.gui.servlets.MainControl.logger;
		String eid = e.getAttributeValue("Id");
		if (eid != null && eid.equals(id)) {
			
			return true;
		} else {
			
			List deleteList = new LinkedList();
			for (Iterator it = e.getChildren().iterator(); it.hasNext(); ) {
				Element ae = (Element) it.next();
				if (filter(ae, dst, id)) deleteList.add(ae);
			}
			if (deleteList.size() > 0) {
				for (Iterator it = deleteList.iterator(); it.hasNext(); ) {
					Element ae = (Element) it.next();
					
					ae.detach();
					dst.addContent(ae);
				}
				return false;
			}
		}
		return false;
	}

	
	public static String transform(String buffer, String xslt) throws Exception {
		return transform(new StreamSource(new StringReader(buffer)), xslt);
	}
	
	public static String transform(Source src, String xslt) throws Exception {
		StringWriter       sw  = new StringWriter();
	 
		StreamSource       xsl = new StreamSource(new StringReader(xslt));
		TransformerFactory tf  = TransformerFactory.newInstance();
		System.out.println("Transformerfactory: "+tf.getClass().getName());
		Transformer        t   = tf.newTransformer(xsl);
		Result             res = new StreamResult(sw);			
		t.transform(src, res);
		return sw.toString();
	}
	
	public static String transform(Document doc, String xslt) throws Exception {
		return transform(doc, xslt, false);
	}
	
	public static String transform(Document doc, String xslt, boolean saveDocToString) throws Exception {
		if (saveDocToString) {
			StringWriter sw = new StringWriter();
			Format format = Format.getRawFormat();
			XMLOutputter outputter = new XMLOutputter(format);
			outputter.output(doc, sw);
			String buffer = sw.getBuffer().toString();

			FileWriter fw = new FileWriter("/tmp/debug" + System.currentTimeMillis() + ".xml");
			fw.write(buffer);
			fw.close();

			return transform(buffer, xslt);    	  
		} else {
			
			return transform(new JDOMSource(doc), xslt);
		}
	}
	
	public static byte[] transformPDF(Document doc, String xslt) throws Exception {
		// write it into a String
		StringWriter sw = new StringWriter();
	    Format format = Format.getRawFormat();
	    XMLOutputter outputter = new XMLOutputter(format);
    	outputter.output(doc, sw);
    	String buffer = sw.getBuffer().toString();

FileWriter fw = new FileWriter("/tmp/debug" + System.currentTimeMillis() + ".xml");
fw.write(buffer);
fw.close();
    	
    	// transform it
		Driver driver = new Driver();
		driver.setRenderer(Driver.RENDER_PDF);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		StreamSource          src = new StreamSource(new StringReader(buffer));
		StreamSource          xsl = new StreamSource(new StringReader(xslt));
		driver.setOutputStream(out);
		TransformerFactory    tf  = TransformerFactory.newInstance();
		Transformer           t   = tf.newTransformer(xsl);
		Result                res = new SAXResult(driver.getContentHandler());			
		t.transform(src, res);
		
		return out.toByteArray();
	}
}
