/* $Id$ */
package smart_gs.util;

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

import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import smart_gs.image_search.logical.TextType;
import smart_gs.logical.LineSegmentForEdit;
import smart_gs.logical.LineSegment;
import smart_gs.logical.Spread;
import smart_gs.swingui.WorkspaceWindow;
import sml_editor.logical.LineDirection;
public class DSCFileMaker {
	
	private Spread spread;
	
	public DSCFileMaker(Spread spread){
		this.spread = spread;
	}
	public DSCFileMaker(){
		
	}
	public void saveLineSegmentsAndDscCompile(String folderPath,String filename, String filetype, String lineDirectionType){
		File dscFolder = new File(Spread.DSC_FOLDER_PATH);
		
		if(!dscFolder.exists()){
			dscFolder.mkdir();
		}
		
		File folder = new File(folderPath);
		if(!folder.exists()){
			folder.mkdir();
		}
		
		List<LineSegmentForEdit> segments = spread.getLinesForEdit();
		if(segments == null){
			return;
		}
		
		this.saveLineSegmentsInXMLFormat(segments, folderPath, filename, filetype, lineDirectionType );

		File file = new File(folderPath+filename+".xml");
		String absolutePath = CanonicalPathString.get(file);
		int exitValue = this.dscCompileBody(folderPath,filename,true);
		if (exitValue == 0) {
			File targetDscDir = new File(folderPath + "dsc");
		}
	}
	public void dscCompile(String folderPath,String filename, String filetype){
		String linesegmentsfilepath = folderPath+filename+".xml";
		File linesegfile = new File(linesegmentsfilepath);
		if(!linesegfile.exists()){
			JOptionPane.showMessageDialog(null,"Line segments file " + filename+".xml" +" does not exist","Error",JOptionPane.ERROR_MESSAGE);
			return;
		}
		String absolutePath = CanonicalPathString.get(linesegfile);
		int exitValue = this.dscCompileBody(folderPath, filename,true);
		if (exitValue == 0) {
			File targetDscDir = new File(folderPath + "dsc");
		}
	}
	public void saveLineSegmentsInXMLFormat(List<LineSegmentForEdit> segments,String folderPath,String filename, String filetype, String lineDirectionType){
		DocumentBuilder builder = null;
		Element segmentElement = null;
		Document document = null;
		if(segments == null){
			return;
		}
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			document = builder.newDocument();
			Element segmentInfoElement = document.createElement("segmentInfo");
			document.appendChild(segmentInfoElement);
			Element source = document.createElement("source");
			source.appendChild(document.createTextNode(filename+"."+filetype));
			Element lineDirection = document.createElement("lineDirection");
			lineDirection.appendChild(document.createTextNode(lineDirectionType));
			segmentInfoElement.appendChild(source);
			segmentInfoElement.appendChild(lineDirection);
			segmentElement = document.createElement("segments");
			segmentInfoElement.appendChild(segmentElement);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (FactoryConfigurationError e) {
			e.printStackTrace();
		}
		

		for(int i=0;i<segments.size();i++){
			LineSegmentForEdit segment = (LineSegmentForEdit)segments.get(i);
			Element lineElement = this.getLineElement(document,segment);
			segmentElement.appendChild(lineElement);
		}
		
		XMLSaver saver = new XMLSaver(document,folderPath+filename+".xml");

		saver.save();
	}
	
	public int dscCompileBody(String folderPath,String filename,boolean showMessage){
		File lineSegFile = new File(folderPath + filename + ".xml");
		if (!lineSegFile.exists()) {
			String msg = String.format("File%n  " + lineSegFile + "%ndoes not exist");
			GSLog.getInstance().warnWithWindow(msg);
		}
		String absolutePath = CanonicalPathString.get(lineSegFile);
		ProcessBuilder segfo2dscBuilder;
		// OSによってsegfo2dsc実行のコマンドを変える
		String osName = System.getProperty("os.name").toLowerCase();
		if(osName.startsWith("windows")) {
			segfo2dscBuilder = new ProcessBuilder("Segfo2dsc.exe","-nm","-"+absolutePath);
		} else if (osName.startsWith("mac")) {
			absolutePath = absolutePath.replace("/", "\\");
			segfo2dscBuilder = new ProcessBuilder("wine", "Segfo2dsc.exe","-nm","-Z:"+absolutePath);
		} else if  (osName.startsWith("linux")) {
			absolutePath = absolutePath.replace("/", "\\");
			segfo2dscBuilder = new ProcessBuilder("wine", "Segfo2dsc.exe","-nm","-Z:"+absolutePath);
		} else {
			segfo2dscBuilder = new ProcessBuilder("Segfo2dsc.exe","-nm","-"+absolutePath);
		}
		System.out.println(absolutePath);
		int exitValue;
		try {
			Process process = segfo2dscBuilder.start();
			process.waitFor();
			exitValue = process.exitValue();
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		} catch (InterruptedException e) {
			e.printStackTrace();
			return -2;
		}
//		Segfo2dsc.exe always returns 0 as the exit value.
//		if(showMessage){
//			if (exitValue==0){
//				JOptionPane.showMessageDialog(null,"DSC file made successfully");
//			} else {
//				JOptionPane.showMessageDialog(null,"failed to make DSC file");
//			}
//		}

		File dscFile = new File(folderPath + "dsc/" + filename + ".dsc");
		if (dscFile.exists() && dscFile.length()!=0){
			if(showMessage) JOptionPane.showMessageDialog(null,"DSC file has been made");
			File dscLineSegFile = new File(folderPath + "dsc/" + filename + ".xml");
			FileUtils.deleteQuietly(dscLineSegFile);
			spread.setTransformationIsNecessary(false);
		} else {
			if(showMessage) JOptionPane.showMessageDialog(null,"failed to make DSC file");
		}
//		return exitValue;
		return 0;  /* dummy value */
	}
	
	private Element getLineElement(Document doc,LineSegmentForEdit segment){
		Element lineElement = doc.createElement("line");
		Element vertexes = doc.createElement("vertexes");
		lineElement.appendChild(vertexes);
		
		List points = segment.getPoints();
		for(int i=0;i<points.size();i++){
			Element vertex = doc.createElement("vertex");
			Point2D point = (Point2D)points.get(i);
			int x = (int)point.getX();
			int y = (int)point.getY();
			Element xElement = doc.createElement("x");
			Element yElement = doc.createElement("y");
			xElement.appendChild(doc.createTextNode(""+x));
			yElement.appendChild(doc.createTextNode(""+y));
			vertex.appendChild(xElement);
			vertex.appendChild(yElement);
			vertexes.appendChild(vertex);
		}
		
		return lineElement;
		
	}
}
