import java.io.*;
import java.text.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.*;

public class PathC{
	static Document document;
	static int osum=0;
	static int nsum=0;
	static int esum=0;
	static DecimalFormat nf;
	static int decimalPlaces=1;

	public static void main(String[]args){
		if(args.length!=2&&args.length!=3){
			System.err.println("Usage: java PathC infile outfile <decimal places (default=1)>");
			System.exit(1);
		}
		if(args.length==3){
			decimalPlaces=Integer.parseInt(args[2]);
		}
		String formatPattern="#";
		if(decimalPlaces>0){
			formatPattern+=".";
			for(int i=0;i<decimalPlaces;i++)
				formatPattern+="#";
		}
		nf=new DecimalFormat(formatPattern);

		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		try{
			DocumentBuilder builder=factory.newDocumentBuilder();
			document=builder.parse(new File(args[0]));

			NodeList paths=document.getElementsByTagName("path");
			System.out.println(paths.getLength()+" path elements found");
			for(int i=paths.getLength()-1;i>=0;--i){
				Node path=paths.item(i);
				if(path.hasAttributes()){
					NamedNodeMap map=path.getAttributes();
					for(int k=map.getLength()-1;k>=0;--k){
						Node att=map.item(k);
						String name=att.getNodeName();
						if(name.equals("d")){
							String val=att.getNodeValue();
							if(val.trim().length()==0){
								Node parent=path.getParentNode();
								parent.removeChild(path);
								esum++;
								break;
							}
							att.setNodeValue(compact(val));
						}
					}
				}
			}
			System.out.println("path data in   : "+osum+" bytes");
			System.out.println("path data out  : "+nsum+" bytes");
			System.out.println("path data saved: "+(osum-nsum)+" bytes");
			System.out.println("path data ratio: "+String.format("%.2f",(100.0/(double)osum*(double)nsum))+"%");
			if(esum>0)
				System.out.println("removed "+esum+" paths with empty path data");

			TransformerFactory tFactory=TransformerFactory.newInstance();
			Transformer transformer=tFactory.newTransformer();

			DOMSource source=new DOMSource(document);
			StreamResult result=new StreamResult(new FileOutputStream(args[1]));
			transformer.transform(source, result);

		}catch(Exception e){
			e.printStackTrace();
		}
	}
	private static String compact(String s){
		osum+=s.length();
		char mode=' ';
		char lastMode=mode;
		//"M 100 200 L 200 100 L -100 -200"
		//"M 100 200 L 200 100 -100 -200"
		//"M 100 100 L 200 200"
		//"M100 100L200 200"
		//mzlhvcsqta
		StringBuilder sb=new StringBuilder(512);
		String[] result = s.split("\\s|,|\\p{Cntrl}");
		boolean lastAddNum=false;
		for(int x=0;x<result.length;x++){
			String s2=result[x];
	        boolean isMode=false;
	        if(s2.length()==1){
				char c=s2.charAt(0);
				if(c>='a'&&c<='z'||c>='A'&&c<='Z'){
					isMode=true;
					mode=c;
					if(lastMode!=c){
						lastMode=mode;
						sb.append(mode);
						lastAddNum=false;
					}
				}
			}
			if(!isMode){
				if(s2.length()!=0){
					if(lastAddNum)
						sb.append(' ');
					double d=Double.parseDouble(s2);
					sb.append(nf.format(d));
					lastAddNum=true;
				}
			}
		}
		String ret=sb.toString();
		nsum+=ret.length();
		return ret;
	}
}