/*
 **********************************************************************
 * Copyright (c) 2009-2012, 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.util.BagFormatter;
import com.ibm.icu.dev.util.Tabber.HTMLTabber;
import com.ibm.icu.dev.util.TransliteratorUtilities;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.dev.util.UnicodeMap.Composer;
import com.ibm.icu.dev.util.UnicodeMapIterator;
import com.ibm.icu.dev.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;
    }
}
