// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.number;

import java.util.Locale;

import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.util.ULocale;

/**
 * All-in-one formatter for localized numbers, currencies, and units.
 *
 * For a full list of options, see {@link NumberFormatterSettings}.
 *
 * <pre>
 * // Most basic usage:
 * NumberFormatter.withLocale(...).format(123).toString();  // 1,234 in en-US
 *
 * // Custom notation, unit, and rounding strategy:
 * NumberFormatter.with()
 *     .notation(Notation.compactShort())
 *     .unit(Currency.getInstance("EUR"))
 *     .precision(Precision.maxDigits(2))
 *     .locale(...)
 *     .format(1234)
 *     .toString();  // €1.2K in en-US
 *
 * // Create a formatter in a private static final field:
 * private static final LocalizedNumberFormatter formatter = NumberFormatter.withLocale(...)
 *     .unit(NoUnit.PERCENT)
 *     .precision(Precision.fixedFraction(3));
 * formatter.format(5.9831).toString();  // 5.983% in en-US
 *
 * // Create a "template" in a private static final field but without setting a locale until the call site:
 * private static final UnlocalizedNumberFormatter template = NumberFormatter.with()
 *     .sign(SignDisplay.ALWAYS)
 *     .unitWidth(UnitWidth.FULL_NAME);
 * template.locale(...).format(new Measure(1234, MeasureUnit.METER)).toString();  // +1,234 meters in en-US
 * </pre>
 *
 * <p>
 * This API offers more features than {@link com.ibm.icu.text.DecimalFormat} and is geared toward new
 * users of ICU.
 *
 * <p>
 * NumberFormatter instances (i.e., LocalizedNumberFormatter and UnlocalizedNumberFormatter)
 * are immutable and thread safe. This means that invoking a configuration
 * method has no effect on the receiving instance; you must store and use the new number formatter
 * instance it returns instead.
 *
 * <pre>
 * UnlocalizedNumberFormatter formatter = UnlocalizedNumberFormatter.with()
 *         .notation(Notation.scientific());
 * formatter.precision(Precision.maxFraction(2)); // does nothing!
 * formatter.locale(ULocale.ENGLISH).format(9.8765).toString(); // prints "9.8765E0", not "9.88E0"
 * </pre>
 *
 * <p>
 * This API is based on the <em>fluent</em> design pattern popularized by libraries such as Google's
 * Guava. For extensive details on the design of this API, read <a href="https://goo.gl/szi5VB">the
 * design doc</a>.
 *
 * @author Shane Carr
 * @stable ICU 60
 */
public final class NumberFormatter {

    private static final UnlocalizedNumberFormatter BASE = new UnlocalizedNumberFormatter();

    /**
     * An enum declaring how to resolve conflicts between maximum fraction digits and maximum
     * significant digits.
     *
     * <p>There are two modes, RELAXED and STRICT:
     *
     * <ul>
     * <li> RELAXED: Relax one of the two constraints (fraction digits or significant digits) in order
     *   to round the number to a higher level of precision.
     * <li> STRICT: Enforce both constraints, resulting in the number being rounded to a lower
     *   level of precision.
     * </ul>
     *
     * <p>The default settings for compact notation rounding are Max-Fraction = 0 (round to the nearest
     * integer), Max-Significant = 2 (round to 2 significant digits), and priority RELAXED (choose
     * the constraint that results in more digits being displayed).
     *
     * <p>Conflicting *minimum* fraction and significant digits are always resolved in the direction that
     * results in more trailing zeros.
     *
     * <p>Example 1: Consider the number 3.141, with various different settings:
     *
     * <ul>
     * <li> Max-Fraction = 1: "3.1"
     * <li> Max-Significant = 3: "3.14"
     * </ul>
     *
     * <p>The rounding priority determines how to resolve the conflict when both Max-Fraction and
     * Max-Significant are set. With RELAXED, the less-strict setting (the one that causes more digits
     * to be displayed) will be used; Max-Significant wins. With STRICT, the more-strict setting (the
     * one that causes fewer digits to be displayed) will be used; Max-Fraction wins.
     *
     * <p>Example 2: Consider the number 8317, with various different settings:
     *
     * <ul>
     * <li> Max-Fraction = 1: "8317"
     * <li> Max-Significant = 3: "8320"
     * </ul>
     *
     * <p>Here, RELAXED favors Max-Fraction and STRICT favors Max-Significant. Note that this larger
     * number caused the two modes to favor the opposite result.
     *
     * @draft ICU 69
     */
    public static enum RoundingPriority {
        /**
         * Favor greater precision by relaxing one of the rounding constraints.
         *
         * @draft ICU 69
         */
        RELAXED,

        /**
         * Favor adherence to all rounding constraints by producing lower precision.
         *
         * @draft ICU 69
         */
        STRICT,
    }

    /**
     * An enum declaring how to render units, including currencies. Example outputs when formatting 123
     * USD and 123 meters in <em>en-CA</em>:
     *
     * <ul>
     * <li>NARROW: "$123.00" and "123 m"
     * <li>SHORT: "US$ 123.00" and "123 m"
     * <li>FULL_NAME: "123.00 US dollars" and "123 meters"
     * <li>ISO_CODE: "USD 123.00" and undefined behavior
     * <li>HIDDEN: "123.00" and "123"
     * </ul>
     *
     * <p>
     * This enum is similar to {@link com.ibm.icu.text.MeasureFormat.FormatWidth}.
     *
     * @stable ICU 60
     * @see NumberFormatter
     */
    public static enum UnitWidth {
        /**
         * Print an abbreviated version of the unit name. Similar to SHORT, but always use the shortest
         * available abbreviation or symbol. This option can be used when the context hints at the
         * identity of the unit. For more information on the difference between NARROW and SHORT, see
         * SHORT.
         *
         * <p>
         * In CLDR, this option corresponds to the "Narrow" format for measure units and the "¤¤¤¤¤"
         * placeholder for currencies.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        NARROW,

        /**
         * Print an abbreviated version of the unit name. Similar to NARROW, but use a slightly wider
         * abbreviation or symbol when there may be ambiguity. This is the default behavior.
         *
         * <p>
         * For example, in <em>es-US</em>, the SHORT form for Fahrenheit is "{0} °F", but the NARROW form
         * is "{0}°", since Fahrenheit is the customary unit for temperature in that locale.
         *
         * <p>
         * In CLDR, this option corresponds to the "Short" format for measure units and the "¤"
         * placeholder for currencies.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        SHORT,

        /**
         * Print the full name of the unit, without any abbreviations.
         *
         * <p>
         * In CLDR, this option corresponds to the default format for measure units and the "¤¤¤"
         * placeholder for currencies.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        FULL_NAME,

        /**
         * Use the three-digit ISO XXX code in place of the symbol for displaying currencies.
         *
         * <p>
         * Behavior of this option with non-currency units is not defined at this time.
         *
         * <p>
         * In CLDR, this option corresponds to the "¤¤" placeholder for currencies.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        ISO_CODE,

        /**
         * Use the formal variant of the currency symbol; for example, "NT$" for the New Taiwan
         * dollar in zh-TW.
         *
         * <p>
         * Behavior of this option with non-currency units is not defined at this time.
         *
         * @stable ICU 67
         * @see NumberFormatter
         */
        FORMAL,

        /**
         * Use the alternate variant of the currency symbol; for example, "TL" for the Turkish
         * lira (TRY).
         *
         * <p>
         * Behavior of this option with non-currency units is not defined at this time.
         *
         * @stable ICU 67
         * @see NumberFormatter
         */
        VARIANT,

        /**
         * Format the number according to the specified unit, but do not display the unit. For
         * currencies, apply monetary symbols and formats as with SHORT, but omit the currency symbol.
         * For measure units, the behavior is equivalent to not specifying the unit at all.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        HIDDEN,
    }

    /**
     * An enum declaring the strategy for when and how to display grouping separators (i.e., the
     * separator, often a comma or period, after every 2-3 powers of ten). The choices are several
     * pre-built strategies for different use cases that employ locale data whenever possible. Example
     * outputs for 1234 and 1234567 in <em>en-IN</em>:
     *
     * <ul>
     * <li>OFF: 1234 and 12345
     * <li>MIN2: 1234 and 12,34,567
     * <li>AUTO: 1,234 and 12,34,567
     * <li>ON_ALIGNED: 1,234 and 12,34,567
     * <li>THOUSANDS: 1,234 and 1,234,567
     * </ul>
     *
     * <p>
     * The default is AUTO, which displays grouping separators unless the locale data says that grouping
     * is not customary. To force grouping for all numbers greater than 1000 consistently across locales,
     * use ON_ALIGNED. On the other hand, to display grouping less frequently than the default, use MIN2
     * or OFF. See the docs of each option for details.
     *
     * <p>
     * Note: This enum specifies the strategy for grouping sizes. To set which character to use as the
     * grouping separator, use the "symbols" setter.
     *
     * @stable ICU 61
     * @see NumberFormatter
     */
    public static enum GroupingStrategy {
        /**
         * Do not display grouping separators in any locale.
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        OFF,

        /**
         * Display grouping using locale defaults, except do not show grouping on values smaller than
         * 10000 (such that there is a <em>minimum of two digits</em> before the first separator).
         *
         * <p>
         * Note that locales may restrict grouping separators to be displayed only on 1 million or
         * greater (for example, ee and hu) or disable grouping altogether (for example, bg currency).
         *
         * <p>
         * Locale data is used to determine whether to separate larger numbers into groups of 2
         * (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        MIN2,

        /**
         * Display grouping using the default strategy for all locales. This is the default behavior.
         *
         * <p>
         * Note that locales may restrict grouping separators to be displayed only on 1 million or
         * greater (for example, ee and hu) or disable grouping altogether (for example, bg currency).
         *
         * <p>
         * Locale data is used to determine whether to separate larger numbers into groups of 2
         * (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        AUTO,

        /**
         * Always display the grouping separator on values of at least 1000.
         *
         * <p>
         * This option ignores the locale data that restricts or disables grouping, described in MIN2 and
         * AUTO. This option may be useful to normalize the alignment of numbers, such as in a
         * spreadsheet.
         *
         * <p>
         * Locale data is used to determine whether to separate larger numbers into groups of 2
         * (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        ON_ALIGNED,

        /**
         * Use the Western defaults: groups of 3 and enabled for all numbers 1000 or greater. Do not use
         * locale data for determining the grouping strategy.
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        THOUSANDS
    }

    /**
     * An enum declaring how to denote positive and negative numbers. Example outputs when formatting
     * 123, 0, and -123 in <em>en-US</em>:
     *
     * <ul>
     * <li>AUTO: "123", "0", and "-123"
     * <li>ALWAYS: "+123", "+0", and "-123"
     * <li>NEVER: "123", "0", and "123"
     * <li>ACCOUNTING: "$123", "$0", and "($123)"
     * <li>ACCOUNTING_ALWAYS: "+$123", "+$0", and "($123)"
     * <li>EXCEPT_ZERO: "+123", "0", and "-123"
     * <li>ACCOUNTING_EXCEPT_ZERO: "+$123", "$0", and "($123)"
     * </ul>
     *
     * <p>
     * The exact format, including the position and the code point of the sign, differ by locale.
     *
     * @stable ICU 60
     * @see NumberFormatter
     */
    public static enum SignDisplay {
        /**
         * Show the minus sign on negative numbers, and do not show the sign on positive numbers. This is
         * the default behavior.
         *
         * If using this option, a sign will be displayed on negative zero, including negative numbers
         * that round to zero. To hide the sign on negative zero, use the NEGATIVE option.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        AUTO,

        /**
         * Show the minus sign on negative numbers and the plus sign on positive numbers, including zero.
         * To hide the sign on zero, see {@link #EXCEPT_ZERO}.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        ALWAYS,

        /**
         * Do not show the sign on positive or negative numbers.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        NEVER,

        /**
         * Use the locale-dependent accounting format on negative numbers, and do not show the sign on
         * positive numbers.
         *
         * <p>
         * The accounting format is defined in CLDR and varies by locale; in many Western locales, the
         * format is a pair of parentheses around the number.
         *
         * <p>
         * Note: Since CLDR defines the accounting format in the monetary context only, this option falls
         * back to the AUTO sign display strategy when formatting without a currency unit. This
         * limitation may be lifted in the future.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        ACCOUNTING,

        /**
         * Use the locale-dependent accounting format on negative numbers, and show the plus sign on
         * positive numbers, including zero. For more information on the accounting format, see the
         * ACCOUNTING sign display strategy. To hide the sign on zero, see
         * {@link #ACCOUNTING_EXCEPT_ZERO}.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        ACCOUNTING_ALWAYS,

        /**
         * Show the minus sign on negative numbers and the plus sign on positive numbers. Do not show a
         * sign on zero, numbers that round to zero, or NaN.
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        EXCEPT_ZERO,

        /**
         * Use the locale-dependent accounting format on negative numbers, and show the plus sign on
         * positive numbers. Do not show a sign on zero, numbers that round to zero, or NaN. For more
         * information on the accounting format, see the ACCOUNTING sign display strategy.
         *
         * @stable ICU 61
         * @see NumberFormatter
         */
        ACCOUNTING_EXCEPT_ZERO,

        /**
         * Same as AUTO, but do not show the sign on negative zero.
         *
         * @draft ICU 69
         */
        NEGATIVE,

        /**
         * Same as ACCOUNTING, but do not show the sign on negative zero.
         *
         * @draft ICU 69
         */
        ACCOUNTING_NEGATIVE,
    }

    /**
     * An enum declaring how to render the decimal separator. Example outputs when formatting 1 and 1.1
     * in <em>en-US</em>:
     *
     * <ul>
     * <li>AUTO: "1" and "1.1"
     * <li>ALWAYS: "1." and "1.1"
     * </ul>
     *
     * @stable ICU 60
     * @see NumberFormatter
     */
    public static enum DecimalSeparatorDisplay {
        /**
         * Show the decimal separator when there are one or more digits to display after the separator,
         * and do not show it otherwise. This is the default behavior.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        AUTO,

        /**
         * Always show the decimal separator, even if there are no digits to display after the separator.
         *
         * @stable ICU 60
         * @see NumberFormatter
         */
        ALWAYS,
    }

    /**
     * An enum declaring how to render trailing zeros.
     *
     * <ul>
     * <li>AUTO: 0.90, 1.00, 1.10
     * <li>HIDE_IF_WHOLE: 0.90, 1, 1.10
     * </ul>
     * 
     * @draft ICU 69
     * @provisional This API might change or be removed in a future release.
     */
    public static enum TrailingZeroDisplay {
        /**
         * Display trailing zeros according to the settings for minimum fraction and significant digits.
         *
         * @draft ICU 69
         */
        AUTO,
    
        /**
         * Same as AUTO, but hide trailing zeros after the decimal separator if they are all zero.
         *
         * @draft ICU 69
         */
        HIDE_IF_WHOLE,
    }

    /**
     * Use a default threshold of 3. This means that the third time .format() is called, the data
     * structures get built using the "safe" code path. The first two calls to .format() will trigger the
     * unsafe code path.
     */
    static final long DEFAULT_THRESHOLD = 3;

    /**
     * Private constructor, not designed for instantiation.
     */
    private NumberFormatter() {
    }

    /**
     * Call this method at the beginning of a NumberFormatter fluent chain in which the locale is not
     * currently known at the call site.
     *
     * @return An {@link UnlocalizedNumberFormatter}, to be used for chaining.
     * @stable ICU 60
     */
    public static UnlocalizedNumberFormatter with() {
        return BASE;
    }

    /**
     * Call this method at the beginning of a NumberFormatter fluent chain in which the locale is known
     * at the call site.
     *
     * @param locale
     *            The locale from which to load formats and symbols for number formatting.
     * @return A {@link LocalizedNumberFormatter}, to be used for chaining.
     * @stable ICU 60
     */
    public static LocalizedNumberFormatter withLocale(Locale locale) {
        return BASE.locale(locale);
    }

    /**
     * Call this method at the beginning of a NumberFormatter fluent chain in which the locale is known
     * at the call site.
     *
     * @param locale
     *            The locale from which to load formats and symbols for number formatting.
     * @return A {@link LocalizedNumberFormatter}, to be used for chaining.
     * @stable ICU 60
     */
    public static LocalizedNumberFormatter withLocale(ULocale locale) {
        return BASE.locale(locale);
    }

    /**
     * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based
     * on a given number skeleton string.
     *
     * For more information on number skeleton strings, see:
     * https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html
     *
     * @param skeleton
     *            The skeleton string off of which to base this NumberFormatter.
     * @return An {@link UnlocalizedNumberFormatter}, to be used for chaining.
     * @throws SkeletonSyntaxException If the given string is not a valid number formatting skeleton.
     * @stable ICU 62
     */
    public static UnlocalizedNumberFormatter forSkeleton(String skeleton) {
        return NumberSkeletonImpl.getOrCreate(skeleton);
    }

    /**
     * Note: In Java, since NumberPropertyMapper is package-private, this method is here so that it is
     * accessible to tests.
     *
     * @internal
     * @deprecated ICU 60 This API is ICU internal only.
     */
    @Deprecated
    public static UnlocalizedNumberFormatter fromDecimalFormat(
            DecimalFormatProperties properties,
            DecimalFormatSymbols symbols,
            DecimalFormatProperties exportedProperties) {
        return NumberPropertyMapper.create(properties, symbols, exportedProperties);
    }
}
