// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
********************************************************************************
*   Copyright (C) 1997-2013, International Business Machines
*   Corporation and others.  All Rights Reserved.
********************************************************************************
*
* File CHOICFMT.H
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   03/20/97    helena      Finished first cut of implementation and got rid
*                           of nextDouble/previousDouble and replaced with
*                           boolean array.
*   4/10/97     aliu        Clean up.  Modified to work on AIX.
*   8/6/97      nos         Removed overloaded constructor, member var 'buffer'.
*   07/22/98    stephen     Removed operator!= (implemented in Format)
********************************************************************************
*/

#ifndef CHOICFMT_H
#define CHOICFMT_H

#include "unicode/utypes.h"

/**
 * \file
 * \brief C++ API: Choice Format.
 */

#if !UCONFIG_NO_FORMATTING
#ifndef U_HIDE_DEPRECATED_API

#include "unicode/fieldpos.h"
#include "unicode/format.h"
#include "unicode/messagepattern.h"
#include "unicode/numfmt.h"
#include "unicode/unistr.h"

U_NAMESPACE_BEGIN

class MessageFormat;

/**
 * ChoiceFormat converts between ranges of numeric values and strings for those ranges.
 * The strings must conform to the MessageFormat pattern syntax.
 *
 * <p><em><code>ChoiceFormat</code> is probably not what you need.
 * Please use <code>MessageFormat</code>
 * with <code>plural</code> arguments for proper plural selection,
 * and <code>select</code> arguments for simple selection among a fixed set of choices!</em></p>
 *
 * <p>A <code>ChoiceFormat</code> splits
 * the real number line \htmlonly<code>-&#x221E;</code> to
 * <code>+&#x221E;</code>\endhtmlonly into two
 * or more contiguous ranges. Each range is mapped to a
 * string.</p>
 *
 * <p><code>ChoiceFormat</code> was originally intended
 * for displaying grammatically correct
 * plurals such as &quot;There is one file.&quot; vs. &quot;There are 2 files.&quot;
 * <em>However,</em> plural rules for many languages
 * are too complex for the capabilities of ChoiceFormat,
 * and its requirement of specifying the precise rules for each message
 * is unmanageable for translators.</p>
 *
 * <p>There are two methods of defining a <code>ChoiceFormat</code>; both
 * are equivalent.  The first is by using a string pattern. This is the
 * preferred method in most cases.  The second method is through direct
 * specification of the arrays that logically make up the
 * <code>ChoiceFormat</code>.</p>
 *
 * <p>Note: Typically, choice formatting is done (if done at all) via <code>MessageFormat</code>
 * with a <code>choice</code> argument type,
 * rather than using a stand-alone <code>ChoiceFormat</code>.</p>
 *
 * <h5>Patterns and Their Interpretation</h5>
 *
 * <p>The pattern string defines the range boundaries and the strings for each number range.
 * Syntax:
 * <pre>
 * choiceStyle = number separator message ('|' number separator message)*
 * number = normal_number | ['-'] \htmlonly&#x221E;\endhtmlonly (U+221E, infinity)
 * normal_number = double value (unlocalized ASCII string)
 * separator = less_than | less_than_or_equal
 * less_than = '<'
 * less_than_or_equal = '#' | \htmlonly&#x2264;\endhtmlonly (U+2264)
 * message: see {@link MessageFormat}
 * </pre>
 * Pattern_White_Space between syntax elements is ignored, except
 * around each range's sub-message.</p>
 *
 * <p>Each numeric sub-range extends from the current range's number
 * to the next range's number.
 * The number itself is included in its range if a <code>less_than_or_equal</code> sign is used,
 * and excluded from its range (and instead included in the previous range)
 * if a <code>less_than</code> sign is used.</p>
 *
 * <p>When a <code>ChoiceFormat</code> is constructed from
 * arrays of numbers, closure flags and strings,
 * they are interpreted just like
 * the sequence of <code>(number separator string)</code> in an equivalent pattern string.
 * <code>closure[i]==TRUE</code> corresponds to a <code>less_than</code> separator sign.
 * The equivalent pattern string will be constructed automatically.</p>
 *
 * <p>During formatting, a number is mapped to the first range
 * where the number is not greater than the range's upper limit.
 * That range's message string is returned. A NaN maps to the very first range.</p>
 *
 * <p>During parsing, a range is selected for the longest match of
 * any range's message. That range's number is returned, ignoring the separator/closure.
 * Only a simple string match is performed, without parsing of arguments that
 * might be specified in the message strings.</p>
 *
 * <p>Note that the first range's number is ignored in formatting
 * but may be returned from parsing.</p>
 *
 * <h5>Examples</h5>
 *
 * <p>Here is an example of two arrays that map the number
 * <code>1..7</code> to the English day of the week abbreviations
 * <code>Sun..Sat</code>. No closures array is given; this is the same as
 * specifying all closures to be <code>FALSE</code>.</p>
 *
 * <pre>    {1,2,3,4,5,6,7},
 *     {&quot;Sun&quot;,&quot;Mon&quot;,&quot;Tue&quot;,&quot;Wed&quot;,&quot;Thur&quot;,&quot;Fri&quot;,&quot;Sat&quot;}</pre>
 *
 * <p>Here is an example that maps the ranges [-Inf, 1), [1, 1], and (1,
 * +Inf] to three strings. That is, the number line is split into three
 * ranges: x &lt; 1.0, x = 1.0, and x &gt; 1.0.
 * (The round parentheses in the notation above indicate an exclusive boundary,
 * like the turned bracket in European notation: [-Inf, 1) == [-Inf, 1[  )</p>
 *
 * <pre>    {0, 1, 1},
 *     {FALSE, FALSE, TRUE},
 *     {&quot;no files&quot;, &quot;one file&quot;, &quot;many files&quot;}</pre>
 *
 * <p>Here is an example that shows formatting and parsing: </p>
 *
 * \code
 *   #include <unicode/choicfmt.h>
 *   #include <unicode/unistr.h>
 *   #include <iostream.h>
 *
 *   int main(int argc, char *argv[]) {
 *       double limits[] = {1,2,3,4,5,6,7};
 *       UnicodeString monthNames[] = {
 *           "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 *       ChoiceFormat fmt(limits, monthNames, 7);
 *       UnicodeString str;
 *       char buf[256];
 *       for (double x = 1.0; x <= 8.0; x += 1.0) {
 *           fmt.format(x, str);
 *           str.extract(0, str.length(), buf, 256, "");
 *           str.truncate(0);
 *           cout << x << " -> "
 *                << buf << endl;
 *       }
 *       cout << endl;
 *       return 0;
 *   }
 * \endcode
 *
 * <p><em>User subclasses are not supported.</em> While clients may write
 * subclasses, such code will not necessarily work and will not be
 * guaranteed to work stably from release to release.
 *
 * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
 */
class U_I18N_API ChoiceFormat: public NumberFormat {
public:
    /**
     * Constructs a new ChoiceFormat from the pattern string.
     *
     * @param pattern   Pattern used to construct object.
     * @param status    Output param to receive success code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    ChoiceFormat(const UnicodeString& pattern,
                 UErrorCode& status);


    /**
     * Constructs a new ChoiceFormat with the given limits and message strings.
     * All closure flags default to <code>FALSE</code>,
     * equivalent to <code>less_than_or_equal</code> separators.
     *
     * Copies the limits and formats instead of adopting them.
     *
     * @param limits    Array of limit values.
     * @param formats   Array of formats.
     * @param count     Size of 'limits' and 'formats' arrays.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    ChoiceFormat(const double* limits,
                 const UnicodeString* formats,
                 int32_t count );

    /**
     * Constructs a new ChoiceFormat with the given limits, closure flags and message strings.
     *
     * Copies the limits and formats instead of adopting them.
     *
     * @param limits Array of limit values
     * @param closures Array of booleans specifying whether each
     * element of 'limits' is open or closed.  If FALSE, then the
     * corresponding limit number is a member of its range.
     * If TRUE, then the limit number belongs to the previous range it.
     * @param formats Array of formats
     * @param count Size of 'limits', 'closures', and 'formats' arrays
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    ChoiceFormat(const double* limits,
                 const UBool* closures,
                 const UnicodeString* formats,
                 int32_t count);

    /**
     * Copy constructor.
     *
     * @param that   ChoiceFormat object to be copied from
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    ChoiceFormat(const ChoiceFormat& that);

    /**
     * Assignment operator.
     *
     * @param that   ChoiceFormat object to be copied
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    const ChoiceFormat& operator=(const ChoiceFormat& that);

    /**
     * Destructor.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual ~ChoiceFormat();

    /**
     * Clones this Format object. The caller owns the
     * result and must delete it when done.
     *
     * @return a copy of this object
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual Format* clone(void) const;

    /**
     * Returns true if the given Format objects are semantically equal.
     * Objects of different subclasses are considered unequal.
     *
     * @param other    ChoiceFormat object to be compared
     * @return         true if other is the same as this.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UBool operator==(const Format& other) const;

    /**
     * Sets the pattern.
     * @param pattern   The pattern to be applied.
     * @param status    Output param set to success/failure code on
     *                  exit. If the pattern is invalid, this will be
     *                  set to a failure result.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual void applyPattern(const UnicodeString& pattern,
                              UErrorCode& status);

    /**
     * Sets the pattern.
     * @param pattern    The pattern to be applied.
     * @param parseError Struct to receive information on position
     *                   of error if an error is encountered
     * @param status     Output param set to success/failure code on
     *                   exit. If the pattern is invalid, this will be
     *                   set to a failure result.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual void applyPattern(const UnicodeString& pattern,
                             UParseError& parseError,
                             UErrorCode& status);
    /**
     * Gets the pattern.
     *
     * @param pattern    Output param which will receive the pattern
     *                   Previous contents are deleted.
     * @return    A reference to 'pattern'
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UnicodeString& toPattern(UnicodeString &pattern) const;

    /**
     * Sets the choices to be used in formatting.
     * For details see the constructor with the same parameter list.
     *
     * @param limitsToCopy      Contains the top value that you want
     *                          parsed with that format,and should be in
     *                          ascending sorted order. When formatting X,
     *                          the choice will be the i, where limit[i]
     *                          &lt;= X &lt; limit[i+1].
     * @param formatsToCopy     The format strings you want to use for each limit.
     * @param count             The size of the above arrays.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual void setChoices(const double* limitsToCopy,
                            const UnicodeString* formatsToCopy,
                            int32_t count );

    /**
     * Sets the choices to be used in formatting.
     * For details see the constructor with the same parameter list.
     *
     * @param limits Array of limits
     * @param closures Array of limit booleans
     * @param formats Array of format string
     * @param count The size of the above arrays
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual void setChoices(const double* limits,
                            const UBool* closures,
                            const UnicodeString* formats,
                            int32_t count);

    /**
     * Returns NULL and 0.
     * Before ICU 4.8, this used to return the choice limits array.
     *
     * @param count Will be set to 0.
     * @return NULL
     * @deprecated ICU 4.8 Use the MessagePattern class to analyze a ChoiceFormat pattern.
     */
    virtual const double* getLimits(int32_t& count) const;

    /**
     * Returns NULL and 0.
     * Before ICU 4.8, this used to return the limit booleans array.
     *
     * @param count Will be set to 0.
     * @return NULL
     * @deprecated ICU 4.8 Use the MessagePattern class to analyze a ChoiceFormat pattern.
     */
    virtual const UBool* getClosures(int32_t& count) const;

    /**
     * Returns NULL and 0.
     * Before ICU 4.8, this used to return the array of choice strings.
     *
     * @param count Will be set to 0.
     * @return NULL
     * @deprecated ICU 4.8 Use the MessagePattern class to analyze a ChoiceFormat pattern.
     */
    virtual const UnicodeString* getFormats(int32_t& count) const;


    using NumberFormat::format;

    /**
     * Formats a double number using this object's choices.
     *
     * @param number    The value to be formatted.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param pos       On input: an alignment field, if desired.
     *                  On output: the offsets of the alignment field.
     * @return          Reference to 'appendTo' parameter.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UnicodeString& format(double number,
                                  UnicodeString& appendTo,
                                  FieldPosition& pos) const;
    /**
     * Formats an int32_t number using this object's choices.
     *
     * @param number    The value to be formatted.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param pos       On input: an alignment field, if desired.
     *                  On output: the offsets of the alignment field.
     * @return          Reference to 'appendTo' parameter.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UnicodeString& format(int32_t number,
                                  UnicodeString& appendTo,
                                  FieldPosition& pos) const;

    /**
     * Formats an int64_t number using this object's choices.
     *
     * @param number    The value to be formatted.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param pos       On input: an alignment field, if desired.
     *                  On output: the offsets of the alignment field.
     * @return          Reference to 'appendTo' parameter.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UnicodeString& format(int64_t number,
                                  UnicodeString& appendTo,
                                  FieldPosition& pos) const;

    /**
     * Formats an array of objects using this object's choices.
     *
     * @param objs      The array of objects to be formatted.
     * @param cnt       The size of objs.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param pos       On input: an alignment field, if desired.
     *                  On output: the offsets of the alignment field.
     * @param success   Output param set to success/failure code on
     *                  exit.
     * @return          Reference to 'appendTo' parameter.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UnicodeString& format(const Formattable* objs,
                                  int32_t cnt,
                                  UnicodeString& appendTo,
                                  FieldPosition& pos,
                                  UErrorCode& success) const;

   using NumberFormat::parse;

   /**
    * Looks for the longest match of any message string on the input text and,
    * if there is a match, sets the result object to the corresponding range's number.
    *
    * If no string matches, then the parsePosition is unchanged.
    *
    * @param text           The text to be parsed.
    * @param result         Formattable to be set to the parse result.
    *                       If parse fails, return contents are undefined.
    * @param parsePosition  The position to start parsing at on input.
    *                       On output, moved to after the last successfully
    *                       parse character. On parse failure, does not change.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
    */
    virtual void parse(const UnicodeString& text,
                       Formattable& result,
                       ParsePosition& parsePosition) const;

    /**
     * Returns a unique class ID POLYMORPHICALLY. Part of ICU's "poor man's RTTI".
     *
     * @return          The class ID for this object. All objects of a
     *                  given class have the same class ID.  Objects of
     *                  other classes have different class IDs.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    virtual UClassID getDynamicClassID(void) const;

    /**
     * Returns the class ID for this class.  This is useful only for
     * comparing to a return value from getDynamicClassID().  For example:
     * <pre>
     * .       Base* polymorphic_pointer = createPolymorphicObject();
     * .       if (polymorphic_pointer->getDynamicClassID() ==
     * .           Derived::getStaticClassID()) ...
     * </pre>
     * @return          The class ID for all objects of this class.
     * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
     */
    static UClassID U_EXPORT2 getStaticClassID(void);

private:
    /**
     * Converts a double value to a string.
     * @param value the double number to be converted.
     * @param string the result string.
     * @return the converted string.
     */
    static UnicodeString& dtos(double value, UnicodeString& string);

    ChoiceFormat(); // default constructor not implemented

    /**
     * Construct a new ChoiceFormat with the limits and the corresponding formats
     * based on the pattern.
     *
     * @param newPattern   Pattern used to construct object.
     * @param parseError   Struct to receive information on position
     *                     of error if an error is encountered.
     * @param status       Output param to receive success code.  If the
     *                     pattern cannot be parsed, set to failure code.
     */
    ChoiceFormat(const UnicodeString& newPattern,
                 UParseError& parseError,
                 UErrorCode& status);

    friend class MessageFormat;

    virtual void setChoices(const double* limits,
                            const UBool* closures,
                            const UnicodeString* formats,
                            int32_t count,
                            UErrorCode &errorCode);

    /**
     * Finds the ChoiceFormat sub-message for the given number.
     * @param pattern A MessagePattern.
     * @param partIndex the index of the first ChoiceFormat argument style part.
     * @param number a number to be mapped to one of the ChoiceFormat argument's intervals
     * @return the sub-message start part index.
     */
    static int32_t findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number);

    static double parseArgument(
            const MessagePattern &pattern, int32_t partIndex,
            const UnicodeString &source, ParsePosition &pos);

    /**
     * Matches the pattern string from the end of the partIndex to
     * the beginning of the limitPartIndex,
     * including all syntax except SKIP_SYNTAX,
     * against the source string starting at sourceOffset.
     * If they match, returns the length of the source string match.
     * Otherwise returns -1.
     */
    static int32_t matchStringUntilLimitPart(
            const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex,
            const UnicodeString &source, int32_t sourceOffset);

    /**
     * Some of the ChoiceFormat constructors do not have a UErrorCode paramater.
     * We need _some_ way to provide one for the MessagePattern constructor.
     * Alternatively, the MessagePattern could be a pointer field, but that is
     * not nice either.
     */
    UErrorCode constructorErrorCode;

    /**
     * The MessagePattern which contains the parsed structure of the pattern string.
     *
     * Starting with ICU 4.8, the MessagePattern contains a sequence of
     * numeric/selector/message parts corresponding to the parsed pattern.
     * For details see the MessagePattern class API docs.
     */
    MessagePattern msgPattern;

    /**
     * Docs & fields from before ICU 4.8, before MessagePattern was used.
     * Commented out, and left only for explanation of semantics.
     * --------
     * Each ChoiceFormat divides the range -Inf..+Inf into fCount
     * intervals.  The intervals are:
     *
     *         0: fChoiceLimits[0]..fChoiceLimits[1]
     *         1: fChoiceLimits[1]..fChoiceLimits[2]
     *        ...
     *  fCount-2: fChoiceLimits[fCount-2]..fChoiceLimits[fCount-1]
     *  fCount-1: fChoiceLimits[fCount-1]..+Inf
     *
     * Interval 0 is special; during formatting (mapping numbers to
     * strings), it also contains all numbers less than
     * fChoiceLimits[0], as well as NaN values.
     *
     * Interval i maps to and from string fChoiceFormats[i].  When
     * parsing (mapping strings to numbers), then intervals map to
     * their lower limit, that is, interval i maps to fChoiceLimit[i].
     *
     * The intervals may be closed, half open, or open.  This affects
     * formatting but does not affect parsing.  Interval i is affected
     * by fClosures[i] and fClosures[i+1].  If fClosures[i]
     * is FALSE, then the value fChoiceLimits[i] is in interval i.
     * That is, intervals i and i are:
     *
     *  i-1:                 ... x < fChoiceLimits[i]
     *    i: fChoiceLimits[i] <= x ...
     *
     * If fClosures[i] is TRUE, then the value fChoiceLimits[i] is
     * in interval i-1.  That is, intervals i-1 and i are:
     *
     *  i-1:                ... x <= fChoiceLimits[i]
     *    i: fChoiceLimits[i] < x ...
     *
     * Because of the nature of interval 0, fClosures[0] has no
     * effect.
     */
    // double*         fChoiceLimits;
    // UBool*          fClosures;
    // UnicodeString*  fChoiceFormats;
    // int32_t         fCount;
};


U_NAMESPACE_END

#endif  // U_HIDE_DEPRECATED_API
#endif /* #if !UCONFIG_NO_FORMATTING */

#endif // CHOICFMT_H
//eof
