/*
********************************************************************************
*   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
