package eu.dnetlib.enabling.graph.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jgraph.graph.CellView;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphLayoutCache;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.jgraph.io.svg.SVGGraphWriter;

public class DnetSVGGraphWriter extends SVGGraphWriter {
	
	private static final Log log = LogFactory.getLog(DnetSVGGraphWriter.class); // NOPMD by marko on 11/24/08 5:02 PM

	
	@Override
	public Object[] getLabels(CellView view) {
		String[] res = new String[1];
		Object cell = view.getCell();
		if (cell instanceof DefaultEdge) {
			res[0] = ((DefaultEdge) cell).toString();
		} else if (cell instanceof DefaultGraphCell) {
			res[0] = ((DefaultGraphCell) cell).getUserObject().toString();
		} else {
			res[0] = cell.getClass().getSimpleName();
		}
		return res;
	}

	@Override
	public void write(OutputStream out, String title, GraphLayoutCache cache, int inset) {
		try {
			Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

			document.appendChild(createNode(document, title, cache, inset));
			
			XPathFactory factory = XPathFactory.newInstance();
			XPath xpath = factory.newXPath();
			XPathExpression expr = xpath.compile("//marker[@id='endMarker']/*");
			Object result = expr.evaluate(document, XPathConstants.NODESET);
			if (result instanceof NodeList) {
				NodeList nl = (NodeList) result;
				for (int i=0;  i < nl.getLength(); i++) {
					Node node = nl.item(i);
					node.getParentNode().removeChild(node);
				}
			}

			TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(out));
		} catch (Exception e) {
			log.error("Error writing svg", e);
			try {
				log.info("Sending error svg image...");
				InputStream input = getClass().getResourceAsStream("/eu/dnetlib/enabling/graph/utils/img/error.svg");
				IOUtils.copy(input, out);
				out.flush();
				log.info("...sent.");
			} catch (IOException e1) {
				log.error("Error sending error message");
			}
		}
	}

}
