//##header J2SE15
//#if defined(FOUNDATION10) || defined(J2SE13)
//#else
/*
 *******************************************************************************
 * Copyright (C) 2002-2007, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;

import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;

public class BagFormatter {
    static final boolean DEBUG = false;
    public static final boolean SHOW_FILES;
    static {
    boolean showFiles = false;
    try {
        showFiles = System.getProperty("SHOW_FILES") != null;
    }
    catch (SecurityException e) {
    }
    SHOW_FILES = showFiles;
    }

    public static final PrintWriter CONSOLE = new PrintWriter(System.out,true);

    private static PrintWriter log = CONSOLE;

    private boolean abbreviated = false;
    private String separator = ",";
    private String prefix = "[";
    private String suffix = "]";
    private UnicodeProperty.Factory source;
    private UnicodeLabel nameSource;
    private UnicodeLabel labelSource;
    private UnicodeLabel rangeBreakSource;
    private UnicodeLabel valueSource;
    private String propName = "";
    private boolean showCount = true;
    //private boolean suppressReserved = true;
    private boolean hexValue = false;
    private static final String NULL_VALUE = "_NULL_VALUE_";
    private int fullTotal = -1;
    private boolean showTotal = true;
    private String lineSeparator = "\r\n";
    private Tabber tabber = new Tabber.MonoTabber();

    /**
     * Compare two UnicodeSets, and show the differences
     * @param name1 name of first set to be compared
     * @param set1 first set
     * @param name2 name of second set to be compared
     * @param set2 second set
     * @return formatted string
     */
    public String showSetDifferences(
        String name1,
        UnicodeSet set1,
        String name2,
        UnicodeSet set2) {

        StringWriter result = new StringWriter();
        showSetDifferences(new PrintWriter(result),name1,set1,name2,set2);
        result.flush();
        return result.getBuffer().toString();
    }

    public String showSetDifferences(
        String name1,
        Collection set1,
        String name2,
        Collection set2) {

        StringWriter result = new StringWriter();
        showSetDifferences(new PrintWriter(result), name1, set1, name2, set2);
        result.flush();
        return result.getBuffer().toString();
    }

    public void showSetDifferences(
            PrintWriter pw,
            String name1,
            UnicodeSet set1,
            String name2,
            UnicodeSet set2) {
        showSetDifferences(pw, name1, set1, name2, set2, -1);
    }
    /**
     * Compare two UnicodeSets, and show the differences
     * @param name1 name of first set to be compared
     * @param set1 first set
     * @param name2 name of second set to be compared
     * @param set2 second set
     */
    public void showSetDifferences(
        PrintWriter pw,
        String name1,
        UnicodeSet set1,
        String name2,
        UnicodeSet set2,
        int flags) 
    {
        if (pw == null) pw = CONSOLE;
        String[] names = { name1, name2 };

        UnicodeSet temp;
        
        if ((flags&1) != 0) {
            temp = new UnicodeSet(set1).removeAll(set2);
            pw.print(lineSeparator);
            pw.print(inOut.format(names));
            pw.print(lineSeparator);
            showSetNames(pw, temp);
        }

        if ((flags&2) != 0) {
            temp = new UnicodeSet(set2).removeAll(set1);
            pw.print(lineSeparator);
            pw.print(outIn.format(names));
            pw.print(lineSeparator);
            showSetNames(pw, temp);
        }

        if ((flags&4) != 0) {
            temp = new UnicodeSet(set2).retainAll(set1);
            pw.print(lineSeparator);
            pw.print(inIn.format(names));
            pw.print(lineSeparator);
            showSetNames(pw, temp);
        }
        pw.flush();
    }

    public void showSetDifferences(
        PrintWriter pw,
        String name1,
        Collection set1,
        String name2,
        Collection set2) {

        if (pw == null) pw = CONSOLE;
        String[] names = { name1, name2 };
        // damn'd collection doesn't have a clone, so
        // we go with Set, even though that
        // may not preserve order and duplicates
        Collection temp = new HashSet(set1);
        temp.removeAll(set2);
        pw.println();
        pw.println(inOut.format(names));
        showSetNames(pw, temp);

        temp.clear();
        temp.addAll(set2);
        temp.removeAll(set1);
        pw.println();
        pw.println(outIn.format(names));
        showSetNames(pw, temp);

        temp.clear();
        temp.addAll(set1);
        temp.retainAll(set2);
        pw.println();
        pw.println(inIn.format(names));
        showSetNames(pw, temp);
    }

    /**
     * Returns a list of items in the collection, with each separated by the separator.
     * Each item must not be null; its toString() is called for a printable representation
     * @param c source collection
     * @return a String representation of the list
     * @internal
     */
    public String showSetNames(Object c) {
        StringWriter buffer = new StringWriter();
        PrintWriter output = new PrintWriter(buffer);
        showSetNames(output,c);
        return buffer.toString();
    }

    /**
     * Returns a list of items in the collection, with each separated by the separator.
     * Each item must not be null; its toString() is called for a printable representation
     * @param output destination to which to write names
     * @param c source collection
     * @internal
     */
    public void showSetNames(PrintWriter output, Object c) {
        mainVisitor.doAt(c, output);
        output.flush();
    }

    /**
     * Returns a list of items in the collection, with each separated by the separator.
     * Each item must not be null; its toString() is called for a printable representation
     * @param filename destination to which to write names
     * @param c source collection
     * @internal
     */
    public void showSetNames(String filename, Object c) throws IOException {
        PrintWriter pw = new PrintWriter(
            new OutputStreamWriter(
                new FileOutputStream(filename),"utf-8"));
        showSetNames(log,c);
        pw.close();
    }

    public String getAbbreviatedName(
        String source,
        String pattern,
        String substitute) {

        int matchEnd = NameIterator.findMatchingEnd(source, pattern);
        int sdiv = source.length() - matchEnd;
        int pdiv = pattern.length() - matchEnd;
        StringBuffer result = new StringBuffer();
        addMatching(
            source.substring(0, sdiv),
            pattern.substring(0, pdiv),
            substitute,
            result);
        addMatching(
            source.substring(sdiv),
            pattern.substring(pdiv),
            substitute,
            result);
        return result.toString();
    }

    abstract public static class Relation {
        abstract public String getRelation(String a, String b);
    }

    static class NullRelation extends Relation {
        public String getRelation(String a, String b) { return ""; }
    }

    private Relation r = new NullRelation();

    public BagFormatter setRelation(Relation r) {
        this.r = r;
        return this; // for chaining
    }

    public Relation getRelation() {
        return r;
    }

    /*
     r.getRelati on(last, s) + quote(s) + "\t#" + UnicodeSetFormatter.getResolvedName(s)
    */
    /*
    static final UnicodeSet NO_NAME =
        new UnicodeSet("[\\u0080\\u0081\\u0084\\u0099\\p{Cn}\\p{Co}]");
    static final UnicodeSet HAS_NAME = new UnicodeSet(NO_NAME).complement();
    static final UnicodeSet NAME_CHARACTERS =
        new UnicodeSet("[A-Za-z0-9\\<\\>\\-\\ ]");

    public UnicodeSet getSetForName(String namePattern) {
        UnicodeSet result = new UnicodeSet();
        Matcher m = Pattern.compile(namePattern).matcher("");
        // check for no-name items, and add in bulk
        m.reset("<no name>");
        if (m.matches()) {
            result.addAll(NO_NAME);
        }
        // check all others
        UnicodeSetIterator usi = new UnicodeSetIterator(HAS_NAME);
        while (usi.next()) {
            String name = getName(usi.codepoint);
            if (name == null)
                continue;
            m.reset(name);
            if (m.matches()) {
                result.add(usi.codepoint);
            }
        }
        // Note: if Regex had some API so that if we could tell that
        // an initial substring couldn't match, e.g. "CJK IDEOGRAPH-"
        // then we could optimize by skipping whole swathes of characters
        return result;
    }
    */

    public BagFormatter setMergeRanges(boolean in) {
        mergeRanges = in;
        return this;
    }
    public BagFormatter setShowSetAlso(boolean b) {
        showSetAlso = b;
        return this;
    }

    public String getName(int codePoint) {
        return getName("", codePoint, codePoint);
    }

    public String getName(String separator, int start, int end) {
        if (getNameSource() == null || getNameSource() == UnicodeLabel.NULL) return "";
        String result = getName(start, false);
        if (start == end) return separator + result;
        String endString = getName(end, false);
        if (result.length() == 0 && endString.length() == 0) return separator;
        if (abbreviated) endString = getAbbreviatedName(endString,result,"~");
        return separator + result + ".." + endString;
    }

    public String getName(String s) {
        return getName(s, false);
    }

    public static class NameLabel extends UnicodeLabel {
        UnicodeProperty nameProp;
        UnicodeSet control;
        UnicodeSet private_use;
        UnicodeSet noncharacter;
        UnicodeSet surrogate;

        public NameLabel(UnicodeProperty.Factory source) {
            nameProp = source.getProperty("Name");
            control = source.getSet("gc=Cc");
            private_use = source.getSet("gc=Co");
            surrogate = source.getSet("gc=Cs");
            noncharacter = source.getSet("noncharactercodepoint=yes");
        }

        public String getValue(int codePoint, boolean isShort) {
            String hcp = !isShort
                ? "U+" + Utility.hex(codePoint, 4) + " "
                : "";
            String result = nameProp.getValue(codePoint);
            if (result != null)
                return hcp + result;
            if (control.contains(codePoint)) {
                return "<control-" + Utility.hex(codePoint, 4) + ">";
            }
            if (private_use.contains(codePoint)) {
                return "<private-use-" + Utility.hex(codePoint, 4) + ">";
            }
            if (surrogate.contains(codePoint)) {
                return "<surrogate-" + Utility.hex(codePoint, 4) + ">";
            }
            if (noncharacter.contains(codePoint)) {
                return "<noncharacter-" + Utility.hex(codePoint, 4) + ">";
            }
            //if (suppressReserved) return "";
            return hcp + "<reserved-" + Utility.hex(codePoint, 4) + ">";
        }

    }

    // refactored
    public String getName(int codePoint, boolean withCodePoint) {
        String result = getNameSource().getValue(codePoint, !withCodePoint);
        return fixName == null ? result : fixName.transliterate(result);
    }

    public String getName(String s, boolean withCodePoint) {
           String result = getNameSource().getValue(s, separator, !withCodePoint);
        return fixName == null ? result : fixName.transliterate(result);
     }

    public String hex(String s) {
        return hex(s,separator);
    }

    public String hex(String s, String separator) {
        return UnicodeLabel.HEX.getValue(s, separator, true);
    }

    public String hex(int start, int end) {
        String s = Utility.hex(start,4);
        if (start == end) return s;
        return s + ".." + Utility.hex(end,4);
    }

    public BagFormatter setUnicodePropertyFactory(UnicodeProperty.Factory source) {
        this.source = source;
        return this;
    }

    public UnicodeProperty.Factory getUnicodePropertyFactory() {
        if (source == null) source = ICUPropertyFactory.make();
        return source;
    }

    public BagFormatter () {
    }

    public BagFormatter (UnicodeProperty.Factory source) {
        setUnicodePropertyFactory(source);
    }

    public String join(Object o) {
        return labelVisitor.join(o);
    }

    // ===== PRIVATES =====

    private Join labelVisitor = new Join();

    private boolean mergeRanges = true;
    private Transliterator showLiteral = null;
    private Transliterator fixName = null;
    private boolean showSetAlso = false;

    private RangeFinder rf = new RangeFinder();

    private MessageFormat inOut = new MessageFormat("In {0}, but not in {1}:");
    private MessageFormat outIn = new MessageFormat("Not in {0}, but in {1}:");
    private MessageFormat inIn = new MessageFormat("In both {0}, and in {1}:");

    private MyVisitor mainVisitor = new MyVisitor();

    /*
    private String getLabels(int start, int end) {
        Set names = new TreeSet();
        for (int cp = start; cp <= end; ++cp) {
            names.add(getLabel(cp));
        }
        return labelVisitor.join(names);
    }
    */

    private void addMatching(
        String source,
        String pattern,
        String substitute,
        StringBuffer result) {
        NameIterator n1 = new NameIterator(source);
        NameIterator n2 = new NameIterator(pattern);
        boolean first = true;
        while (true) {
            String s1 = n1.next();
            if (s1 == null)
                break;
            String s2 = n2.next();
            if (!first)
                result.append(" ");
            first = false;
            if (s1.equals(s2))
                result.append(substitute);
            else
                result.append(s1);
        }
    }

    private static NumberFormat nf =
        NumberFormat.getIntegerInstance(Locale.ENGLISH);
    static {
        nf.setGroupingUsed(false);
    }

    private class MyVisitor extends Visitor {
        private PrintWriter output;
        String commentSeparator;
        int counter;
        int valueSize;
        int labelSize;
        boolean isHtml;
        boolean inTable = false;
        
        public void toOutput(String s) {
          if (isHtml) {
            if (inTable) {
              output.print("</table>");
              inTable = false;
            }
            output.print("<p>");
          }
          output.print(s);
          if (isHtml)
            output.println("</p>");
          else
            output.print(lineSeparator);
        }
        
        public void toTable(String s) {
          if (isHtml && !inTable) {
            output.print("<table>");
            inTable = true;
          }
          output.print(tabber.process(s) +  lineSeparator);
        }

        public void doAt(Object c, PrintWriter output) {
            this.output = output;
            isHtml = tabber instanceof Tabber.HTMLTabber;
            counter = 0;
            
            tabber.clear();
            // old:
            // 0009..000D    ; White_Space # Cc   [5] <control-0009>..<control-000D>
            // new
            // 0009..000D    ; White_Space #Cc  [5] <control>..<control>
            tabber.add(mergeRanges ? 14 : 6,Tabber.LEFT);

            if (propName.length() > 0) {
                tabber.add(propName.length() + 2,Tabber.LEFT);
            }

            valueSize = getValueSource().getMaxWidth(shortValue);
            if (DEBUG) System.out.println("ValueSize: " + valueSize);
            if (valueSize > 0) {
                tabber.add(valueSize + 2,Tabber.LEFT); // value
            }

            tabber.add(3,Tabber.LEFT); // comment character

            labelSize = getLabelSource(true).getMaxWidth(shortLabel);
            if (labelSize > 0) {
                tabber.add(labelSize + 1,Tabber.LEFT); // value
            }

            if (mergeRanges && showCount) {
                tabber.add(5,Tabber.RIGHT);
            }

            if (showLiteral != null) {
                tabber.add(4,Tabber.LEFT);
            }
            //myTabber.add(7,Tabber.LEFT);

            commentSeparator = (showCount || showLiteral != null
              || getLabelSource(true) != UnicodeLabel.NULL
              || getNameSource() != UnicodeLabel.NULL)
            ? "\t #" : "";

            if (DEBUG) System.out.println("Tabber: " + tabber.toString());
            if (DEBUG) System.out.println("Tabber: " + tabber.process(
                    "200C..200D\t; White_Space\t #\tCf\t [2]\t ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER"));
            doAt(c);
        }

        public String format(Object o) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            doAt(o);
            pw.flush();
            String result = sw.getBuffer().toString();
            pw.close();
            return result;
        }

        protected void doBefore(Object container, Object o) {
            if (showSetAlso && container instanceof UnicodeSet) {
              toOutput("#" + container);
            }
        }

        protected void doBetween(Object container, Object lastItem, Object nextItem) {
        }

        protected void doAfter(Object container, Object o) {
            if (fullTotal != -1 && fullTotal != counter) {
                if (showTotal) {
                    toOutput("");
                    toOutput("# The above property value applies to " + nf.format(fullTotal-counter) + " code points not listed here.");
                    toOutput("# Total code points: " + nf.format(fullTotal));
                }
                fullTotal = -1;
            } else if (showTotal) {
                toOutput("");
                toOutput("# Total code points: " + nf.format(counter));
            }
        }

        protected void doSimpleAt(Object o) {
            if (o instanceof Map.Entry) {
                Map.Entry oo = (Map.Entry)o;
                Object key = oo.getKey();
                Object value = oo.getValue();
                doBefore(o, key);
                doAt(key);
                output.println("\u2192");
                doAt(value);
                doAfter(o, value);
                counter++;
            } else if (o instanceof Visitor.CodePointRange) {
                doAt((Visitor.CodePointRange) o);
            } else {
                String thing = o.toString();
                String value = getValueSource() == UnicodeLabel.NULL ? "" : getValueSource().getValue(thing, ",", true);
                if (getValueSource() != UnicodeLabel.NULL) value = "\t; " + value;
                String label = getLabelSource(true) == UnicodeLabel.NULL ? "" : getLabelSource(true).getValue(thing, ",", true);
                if (label.length() != 0) label = " " + label;
                toTable(
                    hex(thing)
                    + value
                    + commentSeparator
                    + label
                    + insertLiteral(thing)
                    + "\t"
                    + getName(thing));
                counter++;
            }
        }

        protected void doAt(Visitor.CodePointRange usi) {
            if (!mergeRanges) {
                for (int cp = usi.codepoint; cp <= usi.codepointEnd; ++cp) {
                    showLine(cp, cp);
                }
            } else {
                rf.reset(usi.codepoint, usi.codepointEnd + 1);
                while (rf.next()) {
                    showLine(rf.start, rf.limit - 1);
                }
            }
        }

        private void showLine(int start, int end) {
            String label = getLabelSource(true).getValue(start, shortLabel);
            String value = getValue(start, shortValue);
            if (value == NULL_VALUE) return;

            counter += end - start + 1;
            String pn = propName;
            if (pn.length() != 0) {
                pn = "\t; " + pn;
            }
            if (valueSize > 0) {
                value = "\t; " + value;
            } else if (value.length() > 0) {
                throw new IllegalArgumentException("maxwidth bogus " + value + "," + getValueSource().getMaxWidth(shortValue));
            }
            if (labelSize > 0) {
                label = "\t" + label;
            } else if (label.length() > 0) {
                throw new IllegalArgumentException("maxwidth bogus " + label + ", " + getLabelSource(true).getMaxWidth(shortLabel));
            }

            String count = "";
            if (mergeRanges && showCount) {
                if (end == start) count = "\t";
                else count = "\t ["+ nf.format(end - start + 1)+ "]";
           }

            toTable(
                hex(start, end)
                + pn
                + value
                + commentSeparator
                + label
                + count
                + insertLiteral(start, end)
                + getName("\t ", start, end));
        }

        private String insertLiteral(String thing) {
            return (showLiteral == null ? ""
                :  " \t(" + showLiteral.transliterate(thing) + ") ");
        }

        private String insertLiteral(int start, int end) {
            return (showLiteral == null ? "" :
                " \t(" + showLiteral.transliterate(UTF16.valueOf(start))
                        + ((start != end)
                            ? (".." + showLiteral.transliterate(UTF16.valueOf(end)))
                            : "")
                + ") ");
        }
        /*
        private String insertLiteral(int cp) {
            return (showLiteral == null ? ""
                :  " \t(" + showLiteral.transliterate(UTF16.valueOf(cp)) + ") ");
        }
        */
    }

    /**
     * Iterate through a string, breaking at words.
     * @author Davis
     */
    private static class NameIterator {
        String source;
        int position;
        int start;
        int limit;

        NameIterator(String source) {
            this.source = source;
            this.start = 0;
            this.limit = source.length();
        }
        /**
         * Find next word, including trailing spaces
         * @return the next word
         */
        String next() {
            if (position >= limit)
                return null;
            int pos = source.indexOf(' ', position);
            if (pos < 0 || pos >= limit)
                pos = limit;
            String result = source.substring(position, pos);
            position = pos + 1;
            return result;
        }

        static int findMatchingEnd(String s1, String s2) {
            int i = s1.length();
            int j = s2.length();
            try {
                while (true) {
                    --i; // decrement both before calling function!
                    --j;
                    if (s1.charAt(i) != s2.charAt(j))
                        break;
                }
            } catch (Exception e) {} // run off start

            ++i; // counteract increment
            i = s1.indexOf(' ', i); // move forward to space
            if (i < 0)
                return 0;
            return s1.length() - i;
        }
    }

    private class RangeFinder {
        int start, limit;
        private int veryLimit;
        //String label, value;
        void reset(int start, int limit) {
            this.limit = start;
            this.veryLimit = limit;
        }
        boolean next() {
            if (limit >= veryLimit)
                return false;
            start = limit; // set to end of last
            String label = getLabelSource(false).getValue(limit, true);
            String value = getValue(limit, true);
            String breaker = getRangeBreakSource().getValue(limit,true);
            if (DEBUG && limit < 0x7F) System.out.println("Label: " + label + ", Value: " + value + ", Break: " + breaker);
            limit++;
            for (; limit < veryLimit; limit++) {
                String s = getLabelSource(false).getValue(limit, true);
                String v = getValue(limit, true);
                String b = getRangeBreakSource().getValue(limit, true);
                if (DEBUG && limit < 0x7F) System.out.println("*Label: " + label + ", Value: " + value + ", Break: " + breaker);
                if (!equalTo(s, label) || !equalTo(v, value) || !equalTo(b, breaker)) break;
            }
            // at this point, limit is the first item that has a different label than source
            // OR, we got to the end, and limit == veryLimit
            return true;
        }
    }

    boolean equalTo(Object a, Object b) {
        if (a == b) return true;
        if (a == null) return false;
        return a.equals(b);
    }

    boolean shortLabel = true;
    boolean shortValue = true;

    public String getPrefix() {
        return prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public BagFormatter setPrefix(String string) {
        prefix = string;
        return this;
    }

    public BagFormatter setSuffix(String string) {
        suffix = string;
        return this;
    }

    public boolean isAbbreviated() {
        return abbreviated;
    }

    public BagFormatter setAbbreviated(boolean b) {
        abbreviated = b;
        return this;
    }

    public UnicodeLabel getLabelSource(boolean visible) {
        if (labelSource == null) {
            Map labelMap = new HashMap();
            //labelMap.put("Lo","L&");
            labelMap.put("Lu","L&");
            labelMap.put("Lt","L&");
            labelMap.put("Ll","L&");
            labelSource = new UnicodeProperty.FilteredProperty(
                getUnicodePropertyFactory().getProperty("General_Category"),
                new UnicodeProperty.MapFilter(labelMap)
            ).setAllowValueAliasCollisions(true);
        }
        return labelSource;
    }

    /**
     * @deprecated
     */
    public static void addAll(UnicodeSet source, Collection target) {
        source.addAllTo(target);
    }

    // UTILITIES

    public static final Transliterator hex = Transliterator.getInstance(
        "[^\\u0009\\u0020-\\u007E\\u00A0-\\u00FF] hex");

    public static BufferedReader openUTF8Reader(String dir, String filename) throws IOException {
        return openReader(dir,filename,"UTF-8");
    }

    public static BufferedReader openReader(String dir, String filename, String encoding) throws IOException {
        File file = new File(dir + filename);
        if (SHOW_FILES && log != null) {
            log.println("Opening File: "
                + file.getCanonicalPath());
        }
        return new BufferedReader(
            new InputStreamReader(
                new FileInputStream(file),
                encoding),
            4*1024);
    }

    public static PrintWriter openUTF8Writer(String dir, String filename) throws IOException {
        return openWriter(dir,filename,"UTF-8");
    }

    public static PrintWriter openWriter(String dir, String filename, String encoding) throws IOException {
        File file = new File(dir + filename);
        if (SHOW_FILES && log != null) {
            log.println("Creating File: "
                + file.getCanonicalPath());
        }
        String parentName = file.getParent();
        if (parentName != null) {
            File parent = new File(parentName);
            parent.mkdirs();
        }
        return new PrintWriter(
            new BufferedWriter(
                new OutputStreamWriter(
                    new FileOutputStream(file),
                    encoding),
                4*1024));
    }
    public static PrintWriter getLog() {
        return log;
    }
    public BagFormatter setLog(PrintWriter writer) {
        log = writer;
        return this;
    }
    public String getSeparator() {
        return separator;
    }
    public BagFormatter setSeparator(String string) {
        separator = string;
        return this;
    }
    public Transliterator getShowLiteral() {
        return showLiteral;
    }
    public BagFormatter setShowLiteral(Transliterator transliterator) {
        showLiteral = transliterator;
        return this;
    }

    // ===== CONVENIENCES =====
    private class Join extends Visitor {
        StringBuffer output = new StringBuffer();
        int depth = 0;
        String join (Object o) {
            output.setLength(0);
            doAt(o);
            return output.toString();
        }
        protected void doBefore(Object container, Object item) {
            ++depth;
            output.append(prefix);
        }
        protected void doAfter(Object container, Object item) {
            output.append(suffix);
            --depth;
        }
        protected void doBetween(Object container, Object lastItem, Object nextItem) {
            output.append(separator);
        }
        protected void doSimpleAt(Object o) {
            if (o != null) output.append(o.toString());
        }
    }

    /**
     * @param label
     */
    public BagFormatter setLabelSource(UnicodeLabel label) {
        if (label == null) label = UnicodeLabel.NULL;
        labelSource = label;
        return this;
    }

    /**
     * @return the NameLable representing the source
     */
    public UnicodeLabel getNameSource() {
        if (nameSource == null) {
            nameSource = new NameLabel(getUnicodePropertyFactory());
        }
        return nameSource;
    }

    /**
     * @param label
     */
    public BagFormatter setNameSource(UnicodeLabel label) {
        if (label == null) label = UnicodeLabel.NULL;
        nameSource = label;
        return this;
    }

    /**
     * @return the UnicodeLabel representing the value
     */
    public UnicodeLabel getValueSource() {
        if (valueSource == null) valueSource = UnicodeLabel.NULL;
        return valueSource;
    }

    private String getValue(int cp, boolean shortValue) {
        String result = getValueSource().getValue(cp, shortValue);
        if (result == null) return NULL_VALUE;
        if (hexValue) result = hex(result, " ");
        return result;
    }

    /**
     * @param label
     */
    public BagFormatter setValueSource(UnicodeLabel label) {
        if (label == null) label = UnicodeLabel.NULL;
        valueSource = label;
        return this;
    }

    public BagFormatter setValueSource(String label) {
        return setValueSource(new UnicodeLabel.Constant(label));
    }

    /**
     * @return true if showCount is true
     */
    public boolean isShowCount() {
        return showCount;
    }

    /**
     * @param b true to show the count
     * @return this (for chaining)
     */
    public BagFormatter setShowCount(boolean b) {
        showCount = b;
        return this;
    }

    /**
     * @return the property name
     */
    public String getPropName() {
        return propName;
    }

    /**
     * @param string
     * @return this (for chaining)
     */
    public BagFormatter setPropName(String string) {
        if (string == null) string = "";
        propName = string;
        return this;
    }

    /**
     * @return true if this is a hexValue
     */
    public boolean isHexValue() {
        return hexValue;
    }

    /**
     * @param b
     * @return this (for chaining)
     */
    public BagFormatter setHexValue(boolean b) {
        hexValue = b;
        return this;
    }

    /**
     * @return the full total
     */
    public int getFullTotal() {
        return fullTotal;
    }

    /**
     * @param i set the full total
     * @return this (for chaining)
     */
    public BagFormatter setFullTotal(int i) {
        fullTotal = i;
        return this;
    }

    /**
     * @return the line separator
     */
    public String getLineSeparator() {
        return lineSeparator;
    }

    /**
     * @param string
     * @return this (for chaining)
     */
    public BagFormatter setLineSeparator(String string) {
        lineSeparator = string;
        return this;
    }

    /**
     * @return the UnicodeLabel representing the range break source
     */
    public UnicodeLabel getRangeBreakSource() {
        if (rangeBreakSource == null) {
            Map labelMap = new HashMap();
            // reflects the code point types on p 25
            labelMap.put("Lo", "G&");
            labelMap.put("Lm", "G&");
            labelMap.put("Lu", "G&");
            labelMap.put("Lt", "G&");
            labelMap.put("Ll", "G&");
            labelMap.put("Mn", "G&");
            labelMap.put("Me", "G&");
            labelMap.put("Mc", "G&");
            labelMap.put("Nd", "G&");
            labelMap.put("Nl", "G&");
            labelMap.put("No", "G&");
            labelMap.put("Zs", "G&");
            labelMap.put("Pd", "G&");
            labelMap.put("Ps", "G&");
            labelMap.put("Pe", "G&");
            labelMap.put("Pc", "G&");
            labelMap.put("Po", "G&");
            labelMap.put("Pi", "G&");
            labelMap.put("Pf", "G&");
            labelMap.put("Sm", "G&");
            labelMap.put("Sc", "G&");
            labelMap.put("Sk", "G&");
            labelMap.put("So", "G&");

            labelMap.put("Zl", "Cf");
            labelMap.put("Zp", "Cf");

            rangeBreakSource =
                new UnicodeProperty
                    .FilteredProperty(
                        getUnicodePropertyFactory().getProperty(
                            "General_Category"),
                        new UnicodeProperty.MapFilter(labelMap))
                    .setAllowValueAliasCollisions(true);

            /*
            "Cn", // = Other, Not Assigned 0
            "Cc", // = Other, Control 15
            "Cf", // = Other, Format 16
            UnicodeProperty.UNUSED, // missing
            "Co", // = Other, Private Use 18
            "Cs", // = Other, Surrogate 19
            */
        }
        return rangeBreakSource;
    }

    /**
     * @param label
     */
    public BagFormatter setRangeBreakSource(UnicodeLabel label) {
        if (label == null) label = UnicodeLabel.NULL;
        rangeBreakSource = label;
        return this;
    }

    /**
     * @return Returns the fixName.
     */
    public Transliterator getFixName() {
        return fixName;
    }
    /**
     * @param fixName The fixName to set.
     */
    public void setFixName(Transliterator fixName) {
        this.fixName = fixName;
    }

    public Tabber getTabber() {
        return tabber;
    }

    public void setTabber(Tabber tabber) {
        this.tabber = tabber;
    }

    public boolean isShowTotal() {
        return showTotal;
    }

    public void setShowTotal(boolean showTotal) {
        this.showTotal = showTotal;
    }
}
//#endif
