package org.eclipse.stem.ui.grapheditor;

/*******************************************************************************
 * Copyright (c) 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

import java.io.File;
import java.io.FileWriter;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;


/**
 * Given a map of gmlPolygons, export the spatial data to a gml file
 */
public class SpatialGmlExporter {
	
	static Document doc;
	
	
	private static final String MAP = "Map"; //$NON-NLS-1$
	private static final String TITLE = "title"; //$NON-NLS-1$
	private static final String SUBTITLE = "subTitle"; //$NON-NLS-1$
	private static final String UPDATED = "updated";//$NON-NLS-1$
	private static final String ENTRY = "entry";//$NON-NLS-1$
	private static final String WHERE = "georss:where";//$NON-NLS-1$
	private static final String POLYGON = "gml:Polygon";//$NON-NLS-1$
	private static final String ID = "gml:id";//$NON-NLS-1$

	private static final String BOUNDARY = "gml:outerBoundaryIs";//$NON-NLS-1$
	private static final String RING = "gml:LinearRing";//$NON-NLS-1$
	private static final String POSLIST = "gml:posList";//$NON-NLS-1$
	
	private static final String ISO_CODE = "ISO-8859-1"; //$NON-NLS-1$
	private static final String INDENT = "yes"; //$NON-NLS-1$
	
	
	/**
	 * 
	 */
	public SpatialGmlExporter() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param args
	 */
	//public static void main(String[] args) {
		//test();
	//}
	
	
//	/** 
//	 * Test the gmlExporter using data from a kml file.
//	 */
//	public static void test() {
//		SpatialGmlExporter self = new SpatialGmlExporter();
//		String dir = "I://WiggerJ/"; //$NON-NLS-1$
//		//KmlReader kmlReader = new KmlReader();
//		
//		Set<GmlPolygon> gmlPolySet = new HashSet<GmlPolygon>();
//		gmlPolySet.add(new GmlPolygon("tst"));
//		Map<String,Set<GmlPolygon>> polygonMap = new HashMap<String,Set<GmlPolygon>>();
//			//kmlReader.readKML(dir+"test2.KML",1); //$NON-NLS-1$
//		//nameToIDMap = kmlReader.getNameToIDMap();
//		polygonMap.put("test", gmlPolySet);
//		String outFile = dir+"/TEST_2_MAP.xml"; //$NON-NLS-1$
//		String threeLetterCode = "CAN"; //$NON-NLS-1$
//		self.writeSpatialData(polygonMap, outFile, threeLetterCode, 1);
//	}// test 
//	
	
	
	/**
	 * Given a map of gmlPolygons, writes the GML data to an xml file
	 * @param polygonMap
	 * @param outputFile
	 * @param threeLetterCode
	 * @param adminLevel
	 */
	public void writeSpatialData(Map<String,Set<GmlPolygon>> polygonMap, String outputFile, String mapName, int adminLevel) {
		writeGML(outputFile, mapName, adminLevel, polygonMap); 
	}
	
	public void writeSpatialData(Map<String,Set<GmlPolygon>> polygonMap, String outputFile, String mapName) {
		writeGML(outputFile, mapName , -1, polygonMap); 
	}
	
	
	
	/**
	 * Write the GML
	 * @param fileName
	 * @param countryCode
	 * @param level
	 */
	@SuppressWarnings("deprecation")
	private void writeGML(String fileName, String mapName, int level, Map<String,Set<GmlPolygon>> polygonMap) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document document = null;

		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.newDocument();
		} catch (Exception e) {
			Activator.logInformation("Error parsing file " + e.getMessage()); //$NON-NLS-1$
		}
		
		//Map Element
		Element root = document.createElement(MAP);
		document.appendChild(root);
		root.setAttribute("xmlns:gml", "http://www.opengis.net/gml"); //$NON-NLS-1$ //$NON-NLS-2$
		root.setAttribute("xmlns:georss", "http://www.georss.org/georss"); //$NON-NLS-1$ //$NON-NLS-2$
		// title
		Element titleElt = document.createElement(TITLE);
		
		if (level >0) titleElt.setTextContent(mapName + " Level "+level+" map"); //$NON-NLS-1$ //$NON-NLS-2$
		else titleElt.setTextContent(mapName + "  map"); //$NON-NLS-1$ 
		root.appendChild(titleElt);
		// subtitle
		Element subTitleElt = document.createElement(SUBTITLE);
		subTitleElt.setTextContent("Administrative Boundaries"); //$NON-NLS-1$
		root.appendChild(subTitleElt);
		// updated
		Element updatedElt = document.createElement(UPDATED);
		Calendar cal = Calendar.getInstance();
		String date = cal.getTime().toLocaleString();
		updatedElt.setTextContent(date);
		root.appendChild(updatedElt);
		
		// ENTRY
		Element entryElt = document.createElement(ENTRY);
		root.appendChild(entryElt);
		// WHERE
		Element whereElt = document.createElement(WHERE);
		entryElt.appendChild(whereElt);
		
	
		Iterator<String> iter = polygonMap.keySet().iterator();
				
		while(iter.hasNext()) {
			
			String id = iter.next();			
			Set<GmlPolygon> polySet = polygonMap.get(id);
			Element polyElt = document.createElement(POLYGON);
			polyElt.setAttribute(ID, id); //id);
			whereElt.appendChild(polyElt);
			Element boundaryElt = document.createElement(BOUNDARY);
			polyElt.appendChild(boundaryElt);
			
			Iterator<GmlPolygon> rings = polySet.iterator();
			while((rings!=null) && (rings.hasNext())) {
				GmlPolygon p = rings.next();
				Element ringElt = document.createElement(RING);
				boundaryElt.appendChild(ringElt);
				Element posListElt = document.createElement(POSLIST);
				String data = p.getData();
				posListElt.setTextContent(data);
				ringElt.appendChild(posListElt);
			}
		
		}// all polygons
		
		write(document,fileName);
		
		
	}// writeGML
	
	
	/**
	 * A standard JAXP way to write a DOM document
	 * @param document 
	 * @param fileName 
	 * 
	 */
	private static synchronized void write(Document document, String fileName) 
	{
		//if(log.logFlag) log.logEnter("XmlUtilities.write(" + document + ", " + xmlFile + ")");
		try 
		{	
			File file = new File(fileName);
			file.delete();
			
			FileWriter fw = new FileWriter(fileName);
			
			DOMSource domSource = new DOMSource(document);
			StreamResult streamResult = new StreamResult(fw);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer serializer = tf.newTransformer();
			serializer.setOutputProperty(OutputKeys.ENCODING, ISO_CODE);
			serializer.setOutputProperty(OutputKeys.INDENT,INDENT);
			serializer.transform(domSource, streamResult); 
			
			fw.close();
		} 
		catch(Exception e)
		{
			e.printStackTrace();
		}
		//if(log.logFlag) log.logExit("XmlUtilities.write");
		return;
	}											// end write

	

} // SpatialGmlExporter
