/* $Id: XMLToLineConverter.java 654 2013-02-08 10:05:15Z ohura $ */
package smart_gs.util;

import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import smart_gs.GSConstants;
import smart_gs.logical.GSResource;
import smart_gs.logical.LineSegment;
import smart_gs.logical.LineSegmentForEdit;
import smart_gs.logical.Spread;
import sml_editor.logical.LineDirection;

public class XMLToLineConverter {
	
	private Spread spread;
	
	public XMLToLineConverter(Spread spread){
		this.spread = spread;
	}
	
	public Pair<LineDirection,List<LineSegment>> getLines(File file){
		LineDirection lineDirection = LineDirection.UNDEFINED;
		List<LineSegment> results_lines = new ArrayList<LineSegment>();
		DocumentBuilder builder = null;
		Document document = null;
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			document = builder.parse(file);
			NodeList line_direction_nodes = document.getElementsByTagName("lineDirection");
			
			if (line_direction_nodes == null
					|| line_direction_nodes.getLength() != 1 ) {
				System.out.printf("Line Direction in %s is not given%n", file);
				return null;
			}
 
			if( ! (line_direction_nodes.item(0).getNodeType() == Node.ELEMENT_NODE 
					&& line_direction_nodes.item(0).getChildNodes().getLength() == 1
						&& line_direction_nodes.item(0).getFirstChild().getNodeType() == Node.TEXT_NODE) ) {
				System.out.printf("Line Direction format in %s is illegal%n");
			}
			
			String tmp0 = line_direction_nodes.item(0).getFirstChild().getNodeValue().trim();
			
			if ( ! tmp0.equalsIgnoreCase("horizontal") && ! tmp0.equalsIgnoreCase("vertical")) {
				System.out.printf("Line Direction $s in %s is illegal%n", tmp0, file);
				return null;
			}
			if (tmp0.equalsIgnoreCase("horizontal")) {
				lineDirection = LineDirection.HORIZONTAL;
			}
			if (tmp0.equalsIgnoreCase("vertical")) {
				lineDirection = LineDirection.VERTICAL;
			}
			NodeList lines = document.getElementsByTagName("vertexes");
			for(int i=0;i<lines.getLength();i++){
				if(lines.item(i).getNodeType() == Node.ELEMENT_NODE){
					LineSegment segment = this.getLineSegment((Element)lines.item(i), i);
					results_lines.add(segment);
				}
			}
		} catch(ParserConfigurationException e){
			e.printStackTrace();
			return null;
		} catch (SAXException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		//	e.printStackTrace();
		}
		return new Pair<LineDirection,List<LineSegment>>(lineDirection,results_lines);
	}
	private LineSegment getLineSegment(Element element, int index){
		List<Point2D> points = new ArrayList<Point2D>();
		String uri = element.getAttribute("uri");
		String originalURI = element.getAttribute(GSResource.ORIGINAL_URI);
		NodeList nodes = element.getElementsByTagName("vertex");
		double x = 0.0 ,y = 0.0;
		for(int i=0;i<nodes.getLength();i++){
			if(nodes.item(i).getNodeType() == Node.ELEMENT_NODE){
				Element e = (Element)nodes.item(i);
				NodeList childs = e.getChildNodes();
				for(int j=0;j<childs.getLength();j++){
					if(childs.item(j).getNodeType() == Node.ELEMENT_NODE){
						Element elem = (Element)childs.item(j);
						if(elem.getNodeName().equals("x")){
							x = new Double(elem.getTextContent());
						}
						else if(elem.getNodeName().equals("y")){
							y = new Double(elem.getTextContent());
							points.add(new Point2D.Double(x,y));
						}
					}
				}
			}
		}
		return new LineSegment(spread,points,uri,originalURI,index);

	}

	public List<LineSegmentForEdit> getLinesForEdit(File file){
		List<LineSegmentForEdit> results = new ArrayList<LineSegmentForEdit>();
		DocumentBuilder builder = null;
		Document document = null;
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			document = builder.parse(file);
			NodeList lines = document.getElementsByTagName("vertexes");
			for(int i=0;i<lines.getLength();i++){
				if(lines.item(i).getNodeType() == Node.ELEMENT_NODE){
					LineSegmentForEdit segment = this.getLineSegmentForEdit((Element)lines.item(i), i);
					results.add(segment);
				}
			}
		}
		catch(ParserConfigurationException e){
			
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
		//	e.printStackTrace();
		}
		return results;
	}
	private LineSegmentForEdit getLineSegmentForEdit(Element element, int index){
		List<Point2D> points = new ArrayList<Point2D>();
		NodeList nodes = element.getElementsByTagName("vertex");
		double x = 0.0 ,y = 0.0;
		for(int i=0;i<nodes.getLength();i++){
			if(nodes.item(i).getNodeType() == Node.ELEMENT_NODE){
				Element e = (Element)nodes.item(i);
				NodeList childs = e.getChildNodes();
				for(int j=0;j<childs.getLength();j++){
					if(childs.item(j).getNodeType() == Node.ELEMENT_NODE){
						Element elem = (Element)childs.item(j);
						if(elem.getNodeName().equals("x")){
							x = new Double(elem.getTextContent());
						}
						else if(elem.getNodeName().equals("y")){
							y = new Double(elem.getTextContent());
							points.add(new Point2D.Double(x,y));
						}
					}
				}
			}
		}
		LineDirection lineDirection;
		NodeList nodes2 = element.getElementsByTagName("lineDirection");
		Element e = (Element)nodes2.item(0);
		if(e.getNodeType() != Node.TEXT_NODE) {
			System.out.printf("Illegal XML line specification for spread %s",spread);
			return null;
		}
		String lineDirectionType = e.getNodeValue();
		
		if (lineDirectionType.equals("Horizontal")) {
			lineDirection = LineDirection.HORIZONTAL;
		} else if (lineDirectionType.equals("Vertical")) {
			lineDirection = LineDirection.VERTICAL;
		} else {
			System.out.printf("Illegal XML line specification for spread %s: %s",spread,lineDirectionType);
			return null;
		}
		
		return new LineSegmentForEdit(points,lineDirection,index);

	}
}
