/*
 **********************************************************************
 * Copyright (c) 2009-2011, Google, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Author: Mark Davis
 **********************************************************************
 */
package com.ibm.icu.dev.tool.cldr;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ibm.icu.dev.test.util.BagFormatter;
import com.ibm.icu.dev.test.util.Tabber.HTMLTabber;
import com.ibm.icu.dev.test.util.TransliteratorUtilities;
import com.ibm.icu.dev.test.util.UnicodeMap;
import com.ibm.icu.dev.test.util.UnicodeMap.Composer;
import com.ibm.icu.dev.test.util.UnicodeMapIterator;
import com.ibm.icu.dev.test.util.XEquivalenceClass.SetMaker;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;


public class CheckSystemFonts {
    
    static String outputDirectoryName;
    static Set<String> SKIP_SHAPES = new HashSet<String>();
    
    public static void main(String[] args) throws IOException {
        System.out.println("Arguments:\t" + Arrays.asList(args));
        if (args.length < 2) {
            throw new IllegalArgumentException("Need command-line args:" +
                    "\n\t\tfont-name-regex" +
                    "\n\t\toutput-directory"
                    );
        }
        Matcher nameMatcher = Pattern.compile(args[0], Pattern.CASE_INSENSITIVE).matcher("");
        outputDirectoryName = args[1].trim();
        File outputDirectory = new File(outputDirectoryName);
        if (!outputDirectory.isDirectory()) {
            throw new IllegalArgumentException("2nd arg must be valid directory");
        }
        loadSkipShapes();

        Map<UnicodeSet,Set<String>> data = new TreeMap<UnicodeSet, Set<String>>();
        Map<String, Font> fontMap = new TreeMap<String, Font>();
        getFontData(nameMatcher, data, fontMap);
        
        showInvisibles();
        showSameGlyphs();

        UnicodeMap<Set<String>> map = showEquivalentCoverage(data);

        showRawCoverage(data);

        Map<Set<String>, String> toShortName = showRawCoverage(map);

        showFullCoverage(map, toShortName);
    }

    private static void loadSkipShapes() {
        try {
            BufferedReader in = BagFormatter.openUTF8Reader(outputDirectoryName, "skip_fonts.txt");
            while (true) {
                String line = in.readLine();
                if (line == null) break;
                String[] fonts = line.trim().split("\\s+");
                for (String font : fonts) {
                    SKIP_SHAPES.add(font);
                }
            }
            in.close();
        } catch (IOException e) {
            System.err.println("Couldn't open:\t" + outputDirectoryName + "/" + "skip_fonts.txt");
        }
    }


    private static final Collator English = Collator.getInstance();

    static {
        English.setStrength(Collator.SECONDARY);
    }

    public static final UnicodeSet DONT_CARE = new UnicodeSet("[[:cn:][:co:][:cs:]]").freeze();
    public static final UnicodeSet COVERAGE = new UnicodeSet(DONT_CARE).complement().freeze();

    private static final Comparator<String> SHORTER_FIRST = new Comparator<String>() {
        public int compare(String n1, String n2) {
            int result = n1.length() - n2.length();
            if (result != 0) return result;
            return n1.compareTo(n2);
        }
    };

    private static final Comparator<UnicodeSet> LONGER_SET_FIRST = new Comparator<UnicodeSet>() {
        public int compare(UnicodeSet n1, UnicodeSet n2) {
            int result = n1.size() - n2.size();
            if (result != 0) return -result;
            return n1.compareTo(n2);
        }
    };

    private static final Comparator<Collection> SHORTER_COLLECTION_FIRST = new Comparator<Collection>() {
        public int compare(Collection n1, Collection n2) {
            int result = n1.size() - n2.size();
            if (result != 0) return result;
            return UnicodeSet.compare(n1, n2);
        }
    };

    private static final HashSet SKIP_TERMS = new HashSet(Arrays.asList("black", "blackitalic", "bold", "boldit", "bolditalic", "bolditalicmt", "boldmt",
            "boldob", "boldoblique", "boldslanted", "book", "bookitalic", "condensed", "condensedblack", "condensedbold", "condensedextrabold",
            "condensedlight", "condensedmedium", "extracondensed", "extralight", "heavy", "italic", "italicmt", "light", "lightit", "lightitalic", "medium",
            "mediumitalic", "oblique", "regular", "roman", "semibold", "semibolditalic", "shadow", "slanted", "ultrabold", "ultralight", "ultralightitalic"
    ));

    private static Composer<Set<String>> composer = new Composer<Set<String>>() {
        Map<R2<Set<String>, Set<String>>,Set<String>> cache = new HashMap<R2<Set<String>, Set<String>>,Set<String>>();
        public Set<String> compose(int codePoint, String string, Set<String> a, Set<String> b) {
            return a == null ? b
                    : b == null ? null 
                            : intern(a,b);
        }
        private Set<String> intern(Set<String> a, Set<String> b) {
            R2<Set<String>, Set<String>> row = Row.of(a, b);
            Set<String> result = cache.get(row);
            if (result == null) {
                result = new TreeSet<String>(English);
                result.addAll(a);
                result.addAll(b);
                cache.put(row, result);
            }
            return result;
        }
    };


    private static void showFullCoverage(UnicodeMap<Set<String>> map, Map<Set<String>, String> toShortName) throws IOException {
        System.out.println("\n***COVERAGE:\t" + map.keySet().size() + "\n");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "coverage.txt");

        for (UnicodeMapIterator<String> it = new UnicodeMapIterator<String>(map); it.nextRange();) {
            String codes = "U+" + Utility.hex(it.codepoint);
            String names = UCharacter.getExtendedName(it.codepoint);
            if (it.codepointEnd != it.codepoint) {
                codes += "..U+" + Utility.hex(it.codepointEnd);
                names += ".." + UCharacter.getExtendedName(it.codepointEnd);
            }
            out.println(codes + "\t" + toShortName.get(map.get(it.codepoint)) + "\t" + names);
        }

        UnicodeSet missing = new UnicodeSet(COVERAGE).removeAll(map.keySet());
        out.println("\nMISSING:\t" + missing.size() + "\n");

        UnicodeMap<String> missingMap = new UnicodeMap<String>();
        for (UnicodeSetIterator it = new UnicodeSetIterator(missing); it.next();) {
            missingMap.put(it.codepoint, UScript.getName(UScript.getScript(it.codepoint)) + "-" + getShortAge(it.codepoint));
        }

        Set<String> sorted = new TreeSet<String>(English);
        sorted.addAll(missingMap.values());
        for (String value : sorted) {
            UnicodeSet items = missingMap.getSet(value);
            for (UnicodeSetIterator it = new UnicodeSetIterator(items); it.nextRange();) {
                String codes = "U+" + Utility.hex(it.codepoint);
                String names = UCharacter.getExtendedName(it.codepoint);
                if (it.codepointEnd != it.codepoint) {
                    codes += "..U+" + Utility.hex(it.codepointEnd);
                    names += ".." + UCharacter.getExtendedName(it.codepointEnd);
                }
                out.println(codes + "\t" + value + "\t" + names);
            }
            out.println();
        }
        out.close();
    }

    private static Map<Set<String>, String> showRawCoverage(UnicodeMap<Set<String>> map) throws IOException {
        System.out.println("\n***COMBO NAMES\n");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "combo_names.txt");

        int count = 0;
        Map<Set<String>, String> toShortName = new HashMap<Set<String>, String>();
        TreeSet<Set<String>> sortedValues = new TreeSet<Set<String>>(SHORTER_COLLECTION_FIRST);
        sortedValues.addAll(map.values());
        for (Set<String> value : sortedValues) {
            String shortName = "combo" + count++;
            Set<String> contained = getLargestContained(value, toShortName.keySet());
            String valueName;
            if (contained != null) {
                Set<String> remainder = new TreeSet<String>();
                remainder.addAll(value);
                remainder.removeAll(contained);
                valueName = toShortName.get(contained) + " + " + remainder;
            } else {
                valueName = value.toString();
            }
            toShortName.put(value, shortName);
            out.println(shortName + "\t" + valueName);
        }
        out.close();
        return toShortName;
    }

    private static void showRawCoverage(Map<UnicodeSet, Set<String>> data) throws IOException {
        System.out.println("\n***RAW COVERAGE (bridging unassigned)\n");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "raw_coverage.txt");

        for (Entry<UnicodeSet, Set<String>> entry : data.entrySet()) {
            UnicodeSet s = entry.getKey();
            Set<String> nameSet = entry.getValue();
            String name = nameSet.iterator().next();
            UnicodeSet bridged = new UnicodeSet(s).addBridges(DONT_CARE);
            out.println(name + "\t" + s.size() + "\t" + bridged);
        }
        out.close();
    }

    private static UnicodeMap<Set<String>> showEquivalentCoverage(Map<UnicodeSet, Set<String>> data) throws IOException {
        System.out.println("\n***EQUIVALENT COVERAGE\n");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "equiv_coverage.txt");

        UnicodeMap<Set<String>> map = new UnicodeMap<Set<String>>();

        Map<String,Set<String>> nameToSingleton = new HashMap<String,Set<String>>();

        for (Entry<UnicodeSet, Set<String>> entry : data.entrySet()) {
            UnicodeSet s = entry.getKey();
            Set<String> nameSet = entry.getValue();
            String name = nameSet.iterator().next();
            //System.out.println(s);
            Set<String> temp2 = nameToSingleton.get(name);
            if (temp2 == null) {
                temp2 = new TreeSet<String>(English);
                temp2.add(name);
            }
            map.composeWith(s, temp2, composer);
            if (nameSet.size() > 1) {
                TreeSet<String> temp = new TreeSet<String>(English);
                temp.addAll(nameSet);
                temp.remove(name);
                out.println(name + "\t" + temp);
            }
        }
        out.close();
        return map;
    }

    private static void showSameGlyphs() throws IOException {
        System.out.println("\n***Visual Equivalences");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "same_glyphs.txt");
        PrintWriter out2 = BagFormatter.openUTF8Writer(outputDirectoryName, "same_glyphs.html");
        out2.println("<html><head>");
        out2.println("<meta content=\"text/html; charset=utf-8\" http-equiv=Content-Type></HEAD>");
        out2.println("<link rel='stylesheet' href='index.css' type='text/css'>");
        out2.println("</head><body><table>");
        HTMLTabber tabber = new HTMLTabber();

        out2.println(tabber.process("Code1\tCode2\tNFC1\tNFC1\tCh1\tCh1\tCh1/F\tCh2/F\tName1\tName2\tFonts"));
        tabber.setParameters(0, "class='c'");
        tabber.setParameters(1, "class='c'");
        tabber.setParameters(2, "class='nf'");
        tabber.setParameters(3, "class='nf'");
        tabber.setParameters(4, "class='p'");
        tabber.setParameters(5, "class='p'");
        //tabber.setParameters(6, "class='q'");
        //tabber.setParameters(7, "class='q'");
        tabber.setParameters(8, "class='n'");
        tabber.setParameters(9, "class='n'");
        tabber.setParameters(10, "class='f'");

        for (R2<Integer,Integer> sample : equivalences.keySet()) {
            final Set<String> reasonSet = equivalences.get(sample);
            String reasons = reasonSet.toString();
            if (reasons.length() > 100) reasons = reasons.substring(0,100) + "...";
            final Integer codepoint1 = sample.get0();
            final Integer codepoint2 = sample.get1();
            
            out.println("U+" + Utility.hex(codepoint1) + "\t" + "U+" + Utility.hex(codepoint2)
                    + "\t" + showNfc(codepoint1) + "\t" + showNfc(codepoint2)
                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, false)
                    + "\t" + UCharacter.getExtendedName(codepoint1) + "\t" + UCharacter.getExtendedName(codepoint2)
                    + "\t" + reasons);
            String line = "U+" + Utility.hex(codepoint1) + "\t" + "U+" + Utility.hex(codepoint2)
                    + "\t" + showNfc(codepoint1) + "\t" + showNfc(codepoint2)
                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, true)
                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, true)
                    + "\t" + UCharacter.getExtendedName(codepoint1) + "\t" + UCharacter.getExtendedName(codepoint2)
                    + "\t" + reasons;
            
            String fonts = "class='q' style='font-family:";
            int maxCount = 5;
            for (String font : reasonSet) {
                if (maxCount != 5) {
                    fonts += ",";
                }
                fonts += font;
                --maxCount;
                if (maxCount <= 0) break;
            }
            fonts += "'";
            tabber.setParameters(6, fonts);
            tabber.setParameters(7, fonts);
            out2.println(tabber.process(line));
        }
        out2.println("</table></body>");
        out2.close();
        out.close();
    }

    private static void showInvisibles() throws IOException {
        System.out.println("\n***Invisibles Equivalences");
        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "invisibles.txt");
        for (String sample : invisibles) {
            String reasons = invisibles.get(sample).toString();
            if (reasons.length() > 100) reasons = reasons.substring(0,100) + "...";
            int codepoint = sample.codePointAt(0);
            out.println("U+" + Utility.hex(sample)
                    + "\t" + showChar(codepoint, false)
                    + "\t" + showNfc(codepoint)
                    + "\t" + UCharacter.getExtendedName(codepoint)
                    + "\t" + reasons);

        }
        out.close();
    }

    private static void getFontData(Matcher nameMatcher, Map<UnicodeSet, Set<String>> data, Map<String, Font> fontMap) {
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        Font[] fonts = env.getAllFonts();
        for (Font font : fonts) {
            if (!font.isPlain()) {
                continue;
            }
            String name = font.getName();
            int lastDash = name.lastIndexOf('-');
            String term = lastDash < 0 ? "" : name.substring(lastDash+1).toLowerCase();
            if (SKIP_TERMS.contains(term)) {
                continue;
            }
            if (nameMatcher != null && !nameMatcher.reset(name).find()) {
                continue;
            }
            fontMap.put(name,font);
        }
        for (Entry<String, Font> entry : fontMap.entrySet()) {
            String name = entry.getKey();
            Font font = entry.getValue();
            System.out.println(name);
            UnicodeSet coverage = getCoverage(font);
            Set<String> sameFonts = data.get(coverage);
            if (sameFonts == null) {
                data.put(coverage, sameFonts = new TreeSet<String>(SHORTER_FIRST));
            } else {
                System.out.println("\tNote: same coverage as " + sameFonts.iterator().next());
            }
            sameFonts.add(name);
        }
    }
    
    static Comparator<Integer> NFCLower = new Comparator<Integer>() {
        public int compare(Integer o1, Integer o2) {
            boolean n1 = Normalizer.isNormalized(o1, Normalizer.NFC, 0);
            boolean n2 = Normalizer.isNormalized(o2, Normalizer.NFC, 0);
            if (n1 != n2) return n1 ? -1 : 1;
            n1 = Normalizer.isNormalized(o1, Normalizer.NFKC, 0);
            n2 = Normalizer.isNormalized(o2, Normalizer.NFKC, 0);
            if (n1 != n2) return n1 ? -1 : 1;
            return o1.compareTo(o2);
        } 
    };
    
    static Comparator<R2<Integer,Integer>> NFCLowerR2 = new Comparator<R2<Integer,Integer>>() {
        public int compare(R2<Integer, Integer> o1, R2<Integer, Integer> o2) {
            int diff = NFCLower.compare(o1.get0(), o2.get0());
            if (diff != 0) return diff;
            return NFCLower.compare(o1.get1(), o2.get1());
        }
    };

    private static String showNfc(int codepoint) {
        return Normalizer.isNormalized(codepoint, Normalizer.NFC, 0) ? "" 
                : Normalizer.isNormalized(codepoint, Normalizer.NFKC, 0) ? "!C" : "!K";
    }

    private static String showChar(Integer item, boolean html) {
        return rtlProtect(UTF16.valueOf(item), html);
    }
    static UnicodeSet RTL = new UnicodeSet("[[:bc=R:][:bc=AL:][:bc=AN:]]").freeze();
    static UnicodeSet CONTROLS = new UnicodeSet("[[:cc:][:Zl:][:Zp:]]").freeze();
    static UnicodeSet INVISIBLES = new UnicodeSet("[:di:]").freeze();
    static final char LRM = '\u200E';

    private static String rtlProtect(String source, boolean html) {
        if (CONTROLS.containsSome(source)) {
            source = "";
        } else if (INVISIBLES.containsSome(source)) {
            source = "";
        } else if (RTL.containsSome(source) || source.startsWith("\"")) {
            source = LRM + source + LRM;
        }
        return html ? TransliteratorUtilities.toHTML.transform(source) : source;
    }


    private static Set<String> getLargestContained(Set<String> value, Collection<Set<String>> collection) {
        Set<String> best = null;
        for (Set<String> set : collection) {
            if (best != null && best.size() > set.size()) {
                continue;
            }
            if (value.containsAll(set)) {
                best = set;
            }
        }
        return best;
    }

    private static String getShortAge(int i) {
        String age = UCharacter.getAge(i).toString();
        return age.substring(0,age.indexOf('.',age.indexOf('.') + 1));
    }

    static SetMaker setMaker = new SetMaker() {
        public Set make() {
            return new TreeSet();
        } 
    };

    static UnicodeMap<Set<String>> invisibles = new UnicodeMap();
    static Map<R2<Integer,Integer>, Set<String>> equivalences = new TreeMap<R2<Integer,Integer>, Set<String>>(NFCLowerR2);
//    static Set<String> SKIP_SHAPES = new HashSet<String>(Arrays.asList(
//            "MT-Extra",
//            "JCsmPC",
//            "DFKaiShu-SB-Estd-BF",
//            "LiGothicMed",
//            "LiHeiPro",
//            "LiSongPro",
//            "LiSungLight",
//            "PMingLiU",
//            "SIL-Hei-Med-Jian",
//            "SIL-Kai-Reg-Jian",
//            "CharcoalCY",
//            "GenevaCY",
//            "HelveticaCYBoldOblique",
//            "HelveticaCYOblique",
//            "HelveticaCYPlain",
//            "HoeflerText-Ornaments",
//            "Apple-Chancery",
//            "MSReferenceSpecialty",
//            "Stencil",
//            "Hooge0555",
//            "Hooge0556",
//            "Desdemona",
//            "EccentricStd",
//            "EngraversMT",
//            "MesquiteStd",
//            "RosewoodStd-Fill",
//            "Stencil",
//            "StencilStd",
//            "Osaka",
//            "Osaka-Mono",
//            "Kroeger0455",
//            "Kroeger0456",
//            "Uni0563",
//            "Uni0564",
//            "Code2001",
//            "AppleSymbols",
//            "AppleGothic", 
//            "AppleMyungjo",
//            "JCkg",
//            "MalithiWeb",
//            "JCfg"
//    ));

    // bug on Mac: http://forums.sun.com/thread.jspa?threadID=5209611
    private static UnicodeSet getCoverage(Font font) {
        String name = font.getFontName();
        boolean skipShapes = SKIP_SHAPES.contains(name);
        UnicodeSet result = new UnicodeSet();
        final FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
        char[] array = new char[1];
        char[] array2 = new char[2];
        Map<Rectangle2D,Map<Shape,UnicodeSet>> boundsToData = new TreeMap<Rectangle2D,Map<Shape,UnicodeSet>>(ShapeComparator);
        for (UnicodeSetIterator it = new UnicodeSetIterator(COVERAGE); it.next();) {
            if (font.canDisplay(it.codepoint)) {
                char[] temp;
                if (it.codepoint <= 0xFFFF) {
                    array[0] = (char) it.codepoint;
                    temp = array;
                } else {
                    Character.toChars(it.codepoint, array2, 0);
                    temp = array2;
                }

                GlyphVector glyphVector = font.createGlyphVector(fontRenderContext, temp);
                int glyphCode = glyphVector.getGlyphCode(0);
                boolean validchar = (glyphCode > 0);
                if (!validchar) continue;

                result.add(it.codepoint);

                if (skipShapes) continue;
                Shape shape = glyphVector.getOutline();
                if (isInvisible(shape)) {
                    Set<String> set = invisibles.get(it.codepoint);
                    if (set == null) {
                        invisibles.put(it.codepoint, set = new TreeSet<String>());
                    }
                    set.add(name);
                } else {
                    Rectangle2D bounds = glyphVector.getVisualBounds();
                    Map<Shape, UnicodeSet> map = boundsToData.get(bounds);
                    if (map == null) {
                        boundsToData.put(bounds, map = new TreeMap<Shape,UnicodeSet>(ShapeComparator));
                    }
                    UnicodeSet set = map.get(shape);
                    if (set == null) {
                        map.put(shape, set = new UnicodeSet());
                    }
                    if (false && set.size() != 0) {
                        System.out.println("Adding " + Utility.hex(it.codepoint) + "\t" + UTF16.valueOf(it.codepoint) +  "\tto " + set.toPattern(false));
                    }
                    set.add(it.codepoint);
                }
            }
        }
        //System.out.println(result.size() + "\t" + result);
        for (Rectangle2D bounds : boundsToData.keySet()) {
            Map<Shape, UnicodeSet> map = boundsToData.get(bounds);
            for (UnicodeSet set : map.values()) {
                set.removeAll(CONTROLS);
                if (set.size() != 1) {
                    //System.out.println(set.toPattern(false));
                    for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) {
                        for (UnicodeSetIterator it2 = new UnicodeSetIterator(set); it2.next();) {
                            int cp = it.codepoint;
                            int cp2 = it2.codepoint;
                            if (cp >= cp2) continue;
                            R2<Integer, Integer> r = Row.of(cp, cp2);
                            Set<String> reasons = equivalences.get(r);
                            if (reasons == null) {
                                equivalences.put(r, reasons = new TreeSet());
                            }
                            reasons.add(name);
                        }
                    }
                }
            }
        }
        return result.freeze();
    }

    static Comparator<Rectangle2D> RectComparator = new Comparator<Rectangle2D>() {

        public int compare(Rectangle2D r1, Rectangle2D r2) {
            int diff;
            if (0 != (diff = compareDiff(r1.getX(),r2.getX()))) return diff;
            if (0 != (diff = compareDiff(r1.getY(),r2.getY()))) return diff;
            if (0 != (diff = compareDiff(r1.getWidth(),r2.getWidth()))) return diff;
            if (0 != (diff = compareDiff(r1.getHeight(),r2.getHeight()))) return diff;
            return 0;
        }

    };

    static final AffineTransform IDENTITY = new AffineTransform();

    static boolean isInvisible(Shape shape) {
        return shape.getPathIterator(IDENTITY).isDone();
    }

    static Comparator<Shape> ShapeComparator = new Comparator<Shape>() {
        float[] coords1 = new float[6];
        float[] coords2 = new float[6];

        public int compare(Shape s1, Shape s2) {
            int diff;
            PathIterator p1 = s1.getPathIterator(IDENTITY);
            PathIterator p2 = s2.getPathIterator(IDENTITY);
            while (true) {
                if (p1.isDone()) {
                    return p2.isDone() ? 0 : -1;
                } else if (p2.isDone()) {
                    return 1;
                }
                int t1 = p1.currentSegment(coords1);
                int t2 = p2.currentSegment(coords2);
                diff = t1 - t2;
                if (diff != 0) return diff;
                /*
                 * SEG_MOVETO and SEG_LINETO types returns one point,
                 * SEG_QUADTO returns two points,
                 * SEG_CUBICTO returns 3 points
                 * and SEG_CLOSE does not return any points.
                 */
                switch (t1) {
                case PathIterator.SEG_CUBICTO: 
                    if (0 != (diff = compareDiff(coords1[5],coords2[5]))) return diff;
                    if (0 != (diff = compareDiff(coords1[4],coords2[4]))) return diff;
                case PathIterator.SEG_QUADTO: 
                    if (0 != (diff = compareDiff(coords1[3],coords2[3]))) return diff;
                    if (0 != (diff = compareDiff(coords1[2],coords2[2]))) return diff;
                case PathIterator.SEG_MOVETO:
                case PathIterator.SEG_LINETO: 
                    if (0 != (diff = compareDiff(coords1[1],coords2[1]))) return diff;
                    if (0 != (diff = compareDiff(coords1[0],coords2[0]))) return diff;
                case PathIterator.SEG_CLOSE: break;
                default: throw new IllegalArgumentException();
                }
                p1.next();
                p2.next();
            }
        }
    };

    private static int compareDiff(float f, float g) {
        return f < g ? -1 : f > g ? 1 : 0;
    }
    private static int compareDiff(double f, double g) {
        return f < g ? -1 : f > g ? 1 : 0;
    }
}
