/*
********************************************************************************
*   Copyright (C) 1997-2001, 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"
#include "unicode/unistr.h"
#include "unicode/numfmt.h"
#include "unicode/fieldpos.h"
#include "unicode/format.h"


/**
 * A ChoiceFormat allows you to attach a format to a range of numbers.
 * It is generally used in a MessageFormat for doing things like plurals.
 * The choice is specified with an ascending list of doubles, where each item
 * specifies a half-open interval up to the next item:
 * <pre>
 * \code
 *     X matches j if and only if limit[j] <= X < limit[j+1]
 * \endcode
 * </pre>
 * If there is no match, then either the first or last index is used, depending
 * on whether the number is too low or too high.  The length of the array of
 * formats must be the same as the length of the array of limits.
 * For example,
 * <pre>
 * \code
 *      {1,2,3,4,5,6,7},
 *           {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}
 *      {0, 1, ChoiceFormat::nextDouble(1)},
 *           {"no files", "one file", "many files"}
 *  \endcode
 * </pre>
 * (nextDouble can be used to get the next higher double, to make the half-open
 * interval.)
 * <P>
 * Here is a simple example that shows formatting and parsing:
 * <pre>
 * \code
 *   void SimpleChoiceExample( void )
 *   {
 *       double limits[] = {1,2,3,4,5,6,7};
 *       UnicodeString monthNames[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
 *       ChoiceFormat* form = new ChoiceFormat(limits, monthNames, 7 );
 *       ParsePosition* status = new ParsePosition(0);
 *       UnicodeString str;
 *       FieldPosition f1(0), f2(0);
 *       for (double i = 0.0; i <= 8.0; ++i) {
 *           status->setIndex(0);
 *           Formattable parseResult;
 *           str.remove();
 *           cout << i << " -> " << form->format(i,str, f1) 
 *                     << " -> " << parseResult << endl;
 *       }
 *       delete form;
 *       delete status;
 *       cout << endl;
 *   }
 * \endcode
 * </pre>
 * Here is a more complex example, with a pattern format.
 * <pre>
 * \code
 *   void ComplexChoiceExample( void )
 *   {
 *       double filelimits[] = {0,1,2};
 *       UnicodeString filepart[] = {"are no files","is one file","are {2} files"};
 *       ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3 );
 *       UErrorCode success = U_ZERO_ERROR;
 *       const Format* testFormats[] = { fileform, NULL, NumberFormat::createInstance(success) };
 *       MessageFormat* pattform = new MessageFormat("There {0} on {1}", success );
 *       pattform->setFormats( testFormats, 3 );
 *       Formattable testArgs[] = {0L, "Disk_A", 0L};
 *       FieldPosition fp(0);
 *       UnicodeString str;
 *       for (int32_t i = 0; i < 4; ++i) {
 *           Formattable fInt(i);
 *           testArgs[0] = fInt;
 *           testArgs[2] = testArgs[0];
 *           str.remove();
 *           pattform->format(testArgs, 3, str, fp, success );
 *           cout << "Output for i=" << i << " : " << str << endl;
 *       }
 *       delete pattform;
 *       cout << endl;
 *   }
 * \endcode
 * </pre>
 * ChoiceFormat objects may be converted to and from patterns.  The
 * syntax of these patterns is [TODO fill in this section with detail].
 * Here is an example of a ChoiceFormat pattern:
 * <P>
 * You can either do this programmatically, as in the above example,
 * or by using a pattern (see ChoiceFormat for more information) as in:
 * <pre>
 * \code
 *        "0#are no files|1#is one file|1&lt;are many files"
 * \endcode
 * </pre>
 * Here the notation is:
 * <pre>
 *  \code
 *        <number> "#"  Specifies a limit value.
 *        <number> "<"  Specifies a limit of nextDouble(<number>).
 *        <number> ">"  Specifies a limit of previousDouble(<number>).
 *  \endcode
 * </pre>
 * Each limit value is followed by a string, which is terminated by
 * a vertical bar character ("|"), except for the last string, which
 * is terminated by the end of the string.
 */
class U_I18N_API ChoiceFormat: public NumberFormat {
public:
    /**
     * Construct a new ChoiceFormat with the limits and the corresponding formats
     * based on the pattern.
     *
     * @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.
     * @stable
     */
    ChoiceFormat(const UnicodeString& newPattern,
                 UErrorCode& status);


    /**
     * Construct a new ChoiceFormat with the given limits and formats.  Copy
     * 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.
     * @stable
     */
    
    ChoiceFormat(const double* limits,
                 const UnicodeString* formats,
                 int32_t count );

    /**
     * Copy constructor.
     * @stable
     */
    ChoiceFormat(const ChoiceFormat&);

    /**
     * Assignment operator.
     * @stable
     */
    const ChoiceFormat& operator=(const ChoiceFormat&);

    /**
     * Destructor.
     * @stable
     */
    virtual ~ChoiceFormat();

    /**
     * Clone this Format object polymorphically. The caller owns the
     * result and should delete it when done.
     * @stable
     */
    virtual Format* clone(void) const;

    /**
     * Return true if the given Format objects are semantically equal.
     * Objects of different subclasses are considered unequal.
     * @stable
     */
    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.
     * @stable
     */
    virtual void applyPattern(const UnicodeString& pattern,
                              UErrorCode& status);

    /**
     * Gets the pattern.
     * @stable
     */
    virtual UnicodeString& toPattern(UnicodeString &pattern) const;

    /**
     * Set the choices to be used in formatting.  The arrays are adopted and
     * should not be deleted by the caller.
     *
     * @param limitsToAdopt     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 formatsToAdopt    The format strings you want to use for each limit.
     * @param count             The size of the above arrays.
     * @stable
     */
    virtual void adoptChoices(double* limitsToAdopt,
                              UnicodeString* formatsToAdopt,
                              int32_t count );  

    /**
     * Set the choices to be used in formatting.
     *
     * @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.
     * @stable
     */
    virtual void setChoices(const double* limitsToCopy,
                            const UnicodeString* formatsToCopy,
                            int32_t count );    
    /**
     * Get the limits passed in the constructor.
     * @return the limits.
     * @stable
     */
    virtual const double* getLimits(int32_t& count) const;

    /**
     * Get the formats passed in the constructor.
     * @return the formats.
     * @stable
     */
    virtual const UnicodeString* getFormats(int32_t& count) const;

   /**
    * Format a double or long number using this object's choices.
    *
    * @param number     The value to be formatted.
    * @param toAppendTo The string to append the formatted string to.
    *                   This is an output parameter.
    * @param pos        On input: an alignment field, if desired.
    *                   On output: the offsets of the alignment field.
    * @return           A reference to 'toAppendTo'.
    * @stable
    */
    virtual UnicodeString& format(double number,
                                  UnicodeString& toAppendTo,
                                  FieldPosition& pos) const;
   /**
    * Format a int_32t number using this object's choices.
    *
    * @stable
    */
    virtual UnicodeString& format(int32_t number,
                                  UnicodeString& toAppendTo,
                                  FieldPosition& pos) const;
   /**
    * Format an array of objects using this object's choices.
    *
    * @stable
    */
    virtual UnicodeString& format(const Formattable* objs,
                                  int32_t cnt,
                                  UnicodeString& toAppendTo,
                                  FieldPosition& pos,
                                  UErrorCode& success) const;
   /**
    * Format an object using this object's choices.
    *
    * @stable
    */
    virtual UnicodeString& format(const Formattable& obj,
                                  UnicodeString& toAppendTo,
                                  FieldPosition& pos, 
                                  UErrorCode& status) const;

    /**
     * Redeclared NumberFormat method.
     * @stable
     */
    UnicodeString& format(const Formattable& obj,
                          UnicodeString& result,
                          UErrorCode& status) const;

    /**
     * Redeclared NumberFormat method.
     * @stable
     */
    UnicodeString& format(  double number,
                            UnicodeString& output) const;

    /**
     * Redeclared NumberFormat method.
     * @stable
     */
    UnicodeString& format(  int32_t number,
                            UnicodeString& output) const;

   /**
    * Return a long if possible (e.g. within range LONG_MAX,
    * LONG_MAX], and with no decimals), otherwise a double.  If
    * IntegerOnly is set, will stop at a decimal point (or equivalent;
    * e.g. for rational numbers "1 2/3", will stop after the 1).
    * <P>
    * If no object can be parsed, parsePosition is unchanged, and NULL is
    * returned.
    *
    * @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.
    * @return               A Formattable object of numeric type.  The caller
    *                       owns this an must delete it.  NULL on failure.
    * @see                  NumberFormat::isParseIntegerOnly
    * @stable
    */
    virtual void parse(const UnicodeString& text,
                       Formattable& result,
                       ParsePosition& parsePosition) const;
    virtual void parse(const UnicodeString& text,
                       Formattable& result,
                       UErrorCode& status) const;
    
    
public:
    /**
     * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
     * This method is to implement a simple version of RTTI, since not all
     * C++ compilers support genuine RTTI.  Polymorphic operator==() and
     * clone() methods call this method.
     *
     * @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.
     * @stable
     */
    virtual UClassID getDynamicClassID(void) const;

    /**
     * Return 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.
     * @stable
     */
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }

    /*
     * Finds the least double greater than d (if positive == true),
     * or the greatest double less than d (if positive == false).
     * If NaN, returns same value.
     * <P>
     * Does not affect floating-point flags,
     * @stable
     */
    static double nextDouble(double d, UBool positive);

    /**
     * Finds the least double greater than d.
     * If NaN, returns same value.
     * Used to make half-open intervals.
     * @see ChoiceFormat::previousDouble
     * @stable
     */
    static double nextDouble(double d );

    /**
     * Finds the greatest double less than d.
     * If NaN, returns same value.
     * @see ChoiceFormat::nextDouble
     * @stable
     */
    static double previousDouble(double d );

private:
    // static cache management (thread-safe)
    static NumberFormat* getNumberFormat(UErrorCode &status); // call this function to 'check out' a numberformat from the cache.
    static void          releaseNumberFormat(NumberFormat *adopt); // call this function to 'return' the number format to the cache.
    
    /**
     * Converts a string to a double value using a default NumberFormat object
     * which is static (shared by all ChoiceFormat instances).
     * @param string the string to be converted with.
     * @param status error code.
     * @return the converted double number.
     */
    static double stod(const UnicodeString& string, UErrorCode& status);

    /**
     * Converts a double value to a string using a default NumberFormat object
     * which is static (shared by all ChoiceFormat instances).
     * @@param value the double number to be converted with.
     * @@param string the result string.
     * @@param status error code.
     * @@return the converted string.
     */
    static UnicodeString& dtos(double value, UnicodeString& string, UErrorCode& status);

    static NumberFormat* fgNumberFormat;
    static char fgClassID;

    double*         fChoiceLimits;
    UnicodeString*  fChoiceFormats;
    int32_t         fCount;
};
 
inline UClassID 
ChoiceFormat::getDynamicClassID() const
{ 
    return ChoiceFormat::getStaticClassID(); 
}

inline double ChoiceFormat::nextDouble( double d )
{
    return ChoiceFormat::nextDouble( d, TRUE );
}
    
inline double ChoiceFormat::previousDouble( double d )
{
    return ChoiceFormat::nextDouble( d, FALSE );
}

inline UnicodeString&
ChoiceFormat::format(const Formattable& obj,
                     UnicodeString& result,
                     UErrorCode& status) const {
    // Don't use Format:: - use immediate base class only,
    // in case immediate base modifies behavior later.
    return NumberFormat::format(obj, result, status);
}

inline UnicodeString&
ChoiceFormat::format(double number,
                     UnicodeString& output) const {
    return NumberFormat::format(number, output);
}

inline UnicodeString&
ChoiceFormat::format(int32_t number,
                     UnicodeString& output) const {
    return NumberFormat::format(number, output);
}

#endif // _CHOICFMT
//eof
