/*
**********************************************************************
*   Copyright (c) 2001-2004, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   11/19/2001  aliu        Creation.
**********************************************************************
*/
package com.ibm.icu.text;
import com.ibm.icu.impl.Utility;

/**
 * A transliterator that converts Unicode characters to an escape
 * form.  Examples of escape forms are "U+4E01" and "&#x10FFFF;".
 * Escape forms have a prefix and suffix, either of which may be
 * empty, a radix, typically 16 or 10, a minimum digit count,
 * typically 1, 4, or 8, and a boolean that specifies whether
 * supplemental characters are handled as 32-bit code points or as two
 * 16-bit code units.  Most escape forms handle 32-bit code points,
 * but some, such as the Java form, intentionally break them into two
 * surrogate pairs, for backward compatibility.
 *
 * <p>Some escape forms actually have two different patterns, one for
 * BMP characters (0..FFFF) and one for supplements (>FFFF).  To
 * handle this, a second EscapeTransliterator may be defined that
 * specifies the pattern to be produced for supplementals.  An example
 * of a form that requires this is the C form, which uses "\\uFFFF"
 * for BMP characters and "\\U0010FFFF" for supplementals.
 *
 * <p>This class is package private.  It registers several standard
 * variants with the system which are then accessed via their IDs.
 *
 * @author Alan Liu
 */
class EscapeTransliterator extends Transliterator {

    /**
     * The prefix of the escape form; may be empty, but usually isn't.
     * May not be null.
     */
    private String prefix;

    /**
     * The prefix of the escape form; often empty.  May not be null.
     */
    private String suffix;

    /**
     * The radix to display the number in.  Typically 16 or 10.  Must
     * be in the range 2 to 36.
     */
    private int radix;

    /**
     * The minimum number of digits.  Typically 1, 4, or 8.  Values
     * less than 1 are equivalent to 1.
     */
    private int minDigits;

    /**
     * If true, supplementals are handled as 32-bit code points.  If
     * false, they are handled as two 16-bit code units.
     */
    private boolean grokSupplementals;

    /**
     * The form to be used for supplementals.  If this is null then
     * the same form is used for BMP characters and supplementals.  If
     * this is not null and if grokSupplementals is true then the
     * prefix, suffix, radix, and minDigits of this object are used
     * for supplementals.
     */
    private EscapeTransliterator supplementalHandler;

    /**
     * Registers standard variants with the system.  Called by
     * Transliterator during initialization.
     */
    static void register() {
        // Unicode: "U+10FFFF" hex, min=4, max=6
        Transliterator.registerFactory("Any-Hex/Unicode", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/Unicode",
                                                "U+", "", 16, 4, true, null);
            }
        });
        
        // Java: "\\uFFFF" hex, min=4, max=4
        Transliterator.registerFactory("Any-Hex/Java", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/Java",
                                                "\\u", "", 16, 4, false, null);
            }
        });
        
        // C: "\\uFFFF" hex, min=4, max=4; \\U0010FFFF hex, min=8, max=8
        Transliterator.registerFactory("Any-Hex/C", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/C",
                                                "\\u", "", 16, 4, true,
                       new EscapeTransliterator("", "\\U", "", 16, 8, true, null));
            }
        });
        
        // XML: "&#x10FFFF;" hex, min=1, max=6
        Transliterator.registerFactory("Any-Hex/XML", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/XML",
                                                "&#x", ";", 16, 1, true, null);
            }
        });

        // XML10: "&1114111;" dec, min=1, max=7 (not really "Any-Hex")
        Transliterator.registerFactory("Any-Hex/XML10", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/XML10",
                                                "&#", ";", 10, 1, true, null);
            }
        });

        // Perl: "\\x{263A}" hex, min=1, max=6
        Transliterator.registerFactory("Any-Hex/Perl", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex/Perl",
                                                "\\x{", "}", 16, 1, true, null);
            }
        });

        // Generic
        Transliterator.registerFactory("Any-Hex", new Transliterator.Factory() {
            public Transliterator getInstance(String ID) {
                return new EscapeTransliterator("Any-Hex",
                                                "\\u", "", 16, 4, false, null);
            }
        });
    }

    /**
     * Constructs an escape transliterator with the given ID and
     * parameters.  See the class member documentation for details.
     */
    EscapeTransliterator(String ID, String prefix, String suffix,
                         int radix, int minDigits,
                         boolean grokSupplementals,
                         EscapeTransliterator supplementalHandler) {
        super(ID, null);
        this.prefix = prefix;
        this.suffix = suffix;
        this.radix = radix;
        this.minDigits = minDigits;
        this.grokSupplementals = grokSupplementals;
        this.supplementalHandler = supplementalHandler;
    }

    /**
     * Implements {@link Transliterator#handleTransliterate}.
     */
    protected void handleTransliterate(Replaceable text,
                                       Position pos, boolean incremental) {
        int start = pos.start;
        int limit = pos.limit;

        StringBuffer buf = new StringBuffer(prefix);
        int prefixLen = prefix.length();
        boolean redoPrefix = false;

        while (start < limit) {
            int c = grokSupplementals ? text.char32At(start) : text.charAt(start);
            int charLen = grokSupplementals ? UTF16.getCharCount(c) : 1;

            if ((c & 0xFFFF0000) != 0 && supplementalHandler != null) {
                buf.setLength(0);
                buf.append(supplementalHandler.prefix);
                Utility.appendNumber(buf, c, supplementalHandler.radix,
                                     supplementalHandler.minDigits);
                buf.append(supplementalHandler.suffix);
                redoPrefix = true;
            } else {
                if (redoPrefix) {
                    buf.setLength(0);
                    buf.append(prefix);
                    redoPrefix = false;
                } else {
                    buf.setLength(prefixLen);
                }
                Utility.appendNumber(buf, c, radix, minDigits);
                buf.append(suffix);
            }

            text.replace(start, start + charLen, buf.toString());
            start += buf.length();
            limit += buf.length() - charLen;
        }

        pos.contextLimit += limit - pos.limit;
        pos.limit = limit;
        pos.start = start;
    }
}
