/*
*******************************************************************************
* Copyright (C) 1997-1999, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File NUMFMT.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   03/18/97    clhuang     Implemented with C++ APIs.
*   04/17/97    aliu        Enlarged MAX_INTEGER_DIGITS to fully accomodate the
*                           largest double, by default.
*                           Changed DigitCount to int per code review.
*    07/20/98    stephen        Changed operator== to check for grouping
*                            Changed setMaxIntegerDigits per Java implementation.
*                            Changed setMinIntegerDigits per Java implementation.
*                            Changed setMinFractionDigits per Java implementation.
*                            Changed setMaxFractionDigits per Java implementation.
********************************************************************************
*/
 
#include "unicode/numfmt.h"
#include "unicode/locid.h"
#include "unicode/resbund.h"
#include "unicode/dcfmtsym.h"
#include "unicode/decimfmt.h"
#include <float.h>

// If no number pattern can be located for a locale, this is the last
// resort.
static const UChar gLastResortDecimalPat[] = {
    0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x3B, 0x2D, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#0.###;-#0.###" */
};
static const UChar gLastResortCurrencyPat[] = {
    0x24, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x3B, 0x28, 0x24, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x29, 0 /* "$#0.00;($#0.00)" */
};
static const UChar gLastResortPercentPat[] = {
    0x23, 0x30, 0x25, 0 /* "#0%" */
};
static const UChar gLastResortScientificPat[] = {
    0x23, 0x45, 0x30, 0 /* "#E0" */
};
// *****************************************************************************
// class NumberFormat
// *****************************************************************************

U_NAMESPACE_BEGIN

const char NumberFormat::fgClassID = 0; // Value is irrelevant

// If the maximum base 10 exponent were 4, then the largest number would 
// be 99,999 which has 5 digits.
const int32_t NumberFormat::fgMaxIntegerDigits = DBL_MAX_10_EXP + 1; // Should be ~40 ? --srl
const int32_t NumberFormat::fgMinIntegerDigits = 127;

const int32_t NumberFormat::fgNumberPatternsCount = 3;

const UChar * const NumberFormat::fgLastResortNumberPatterns[] =
{
    gLastResortDecimalPat,
    gLastResortCurrencyPat,
    gLastResortPercentPat,
	gLastResortScientificPat
};

// -------------------------------------
// default constructor

NumberFormat::NumberFormat()
:   fGroupingUsed(TRUE),
    fMaxIntegerDigits(fgMaxIntegerDigits),
    fMinIntegerDigits(1),
    fMaxFractionDigits(3), // invariant, >= minFractionDigits
    fMinFractionDigits(0),
    fParseIntegerOnly(FALSE)
{
}

// -------------------------------------

NumberFormat::~NumberFormat()
{
}

// -------------------------------------
// copy constructor

NumberFormat::NumberFormat(const NumberFormat &source)
:   Format(source)
{
    *this = source;
}

// -------------------------------------
// assignment operator

NumberFormat&
NumberFormat::operator=(const NumberFormat& rhs)
{
    if (this != &rhs)
    {
        fGroupingUsed = rhs.fGroupingUsed;
        fMaxIntegerDigits = rhs.fMaxIntegerDigits;
        fMinIntegerDigits = rhs.fMinIntegerDigits;
        fMaxFractionDigits = rhs.fMaxFractionDigits;
        fMinFractionDigits = rhs.fMinFractionDigits;
        fParseIntegerOnly = rhs.fParseIntegerOnly;
    }
    return *this;
}

// -------------------------------------
 
UBool
NumberFormat::operator==(const Format& that) const
{
    NumberFormat* other = (NumberFormat*)&that;

    return ((this == &that) ||
            ((Format::operator==(that) &&
              getDynamicClassID()== that.getDynamicClassID() &&
              fMaxIntegerDigits == other->fMaxIntegerDigits &&
              fMinIntegerDigits == other->fMinIntegerDigits &&
              fMaxFractionDigits == other->fMaxFractionDigits &&
              fMinFractionDigits == other->fMinFractionDigits &&
              fGroupingUsed == other->fGroupingUsed &&
              fParseIntegerOnly == other->fParseIntegerOnly)));
}

// -------------------------------------
// Formats the number object and save the format
// result in the toAppendTo string buffer.
 
UnicodeString&
NumberFormat::format(const Formattable& obj,
                        UnicodeString& toAppendTo,
                        FieldPosition& pos,
                        UErrorCode& status) const
{
    if (U_FAILURE(status)) return toAppendTo;

    if (obj.getType() == Formattable::kDouble) {
        return format(obj.getDouble(), toAppendTo, pos);
    }
    else if (obj.getType() == Formattable::kLong) {
        return format(obj.getLong(), toAppendTo, pos);
    }
    // can't try to format a non-numeric object
    else {
        status = U_INVALID_FORMAT_ERROR;
        return toAppendTo; 
    }
}
  
// -------------------------------------
// Parses the string and save the result object as well
// as the final parsed position.

void
NumberFormat::parseObject(const UnicodeString& source,
                             Formattable& result,
                             ParsePosition& parse_pos) const
{
    parse(source, result, parse_pos);
}
 
// -------------------------------------
// Formats a double number and save the result in a string.
 
UnicodeString&
NumberFormat::format(double number, UnicodeString& toAppendTo) const
{
    FieldPosition pos(0);
    return format(number, toAppendTo, pos);
}
 
// -------------------------------------
// Formats a long number and save the result in a string.
 
UnicodeString&
NumberFormat::format(int32_t number, UnicodeString& toAppendTo) const
{
    FieldPosition pos(0);
    return format(number, toAppendTo, pos);
}
 
// -------------------------------------
// Parses the text and save the result object.  If the returned
// parse position is 0, that means the parsing failed, the status
// code needs to be set to failure.  Ignores the returned parse 
// position, otherwise.
 
void
NumberFormat::parse(const UnicodeString& text,
                        Formattable& result,
                        UErrorCode& status) const
{
    if (U_FAILURE(status)) return;

    ParsePosition parsePosition(0);
    parse(text, result, parsePosition);
    if (parsePosition.getIndex() == 0) {
        status = U_INVALID_FORMAT_ERROR;
    }
}
 
// -------------------------------------
// Sets to only parse integers.
 
void
NumberFormat::setParseIntegerOnly(UBool value)
{
    fParseIntegerOnly = value;
}
 
// -------------------------------------
// Create a number style NumberFormat instance with the default locale.
 
NumberFormat*
NumberFormat::createInstance(UErrorCode& status)
{
    return createInstance(Locale::getDefault(), kNumberStyle, status);
}
 
// -------------------------------------
// Create a number style NumberFormat instance with the inLocale locale.
 
NumberFormat*
NumberFormat::createInstance(const Locale& inLocale, UErrorCode& status)
{
    return createInstance(inLocale, kNumberStyle, status);
}
 
// -------------------------------------
// Create a currency style NumberFormat instance with the default locale.
 
NumberFormat*
NumberFormat::createCurrencyInstance(UErrorCode& status)
{
    return createInstance(Locale::getDefault(), kCurrencyStyle, status);
}
 
// -------------------------------------
// Create a currency style NumberFormat instance with the inLocale locale.
 
NumberFormat*
NumberFormat::createCurrencyInstance(const Locale& inLocale, UErrorCode& status)
{
    return createInstance(inLocale, kCurrencyStyle, status);
}
 
// -------------------------------------
// Create a percent style NumberFormat instance with the default locale.
 
NumberFormat*
NumberFormat::createPercentInstance(UErrorCode& status)
{
    return createInstance(Locale::getDefault(), kPercentStyle, status);
}
 
// -------------------------------------
// Create a percent style NumberFormat instance with the inLocale locale.
 
NumberFormat*
NumberFormat::createPercentInstance(const Locale& inLocale, UErrorCode& status)
{
    return createInstance(inLocale, kPercentStyle, status);
}
 
// -------------------------------------
// Create a scientific style NumberFormat instance with the default locale.
 
NumberFormat*
NumberFormat::createScientificInstance(UErrorCode& status)
{
    return createInstance(Locale::getDefault(), kScientificStyle, status);
}
 
// -------------------------------------
// Create a scientific style NumberFormat instance with the inLocale locale.
 
NumberFormat*
NumberFormat::createScientificInstance(const Locale& inLocale, UErrorCode& status)
{
    return createInstance(inLocale, kScientificStyle, status);
}
 
// -------------------------------------
 
const Locale*
NumberFormat::getAvailableLocales(int32_t& count)
{
    return Locale::getAvailableLocales(count);
}
 
// -------------------------------------
// Checks if the thousand/10 thousand grouping is used in the 
// NumberFormat instance.

UBool
NumberFormat::isGroupingUsed() const
{
    return fGroupingUsed;
}
 
// -------------------------------------
// Sets to use the thousand/10 thousand grouping in the 
// NumberFormat instance.
 
void
NumberFormat::setGroupingUsed(UBool newValue)
{
    fGroupingUsed = newValue;
}
 
// -------------------------------------
// Gets the maximum number of digits for the integral part for
// this NumberFormat instance.
 
int32_t NumberFormat::getMaximumIntegerDigits() const
{
    return fMaxIntegerDigits;
}
 
// -------------------------------------
// Sets the maximum number of digits for the integral part for
// this NumberFormat instance.
 
void
NumberFormat::setMaximumIntegerDigits(int32_t newValue)
{
    fMaxIntegerDigits = uprv_max(0, uprv_min(newValue, fgMaxIntegerDigits));
    if(fMinIntegerDigits > fMaxIntegerDigits)
        fMinIntegerDigits = fMaxIntegerDigits;
}
 
// -------------------------------------
// Gets the minimum number of digits for the integral part for
// this NumberFormat instance.
 
int32_t
NumberFormat::getMinimumIntegerDigits() const
{
    return fMinIntegerDigits;
}
 
// -------------------------------------
// Sets the minimum number of digits for the integral part for
// this NumberFormat instance.
 
void
NumberFormat::setMinimumIntegerDigits(int32_t newValue)
{
    fMinIntegerDigits = uprv_max(0, uprv_min(newValue, fgMinIntegerDigits));
    if(fMinIntegerDigits > fMaxIntegerDigits)
        fMaxIntegerDigits = fMinIntegerDigits;
}
 
// -------------------------------------
// Gets the maximum number of digits for the fractional part for
// this NumberFormat instance.
 
int32_t
NumberFormat::getMaximumFractionDigits() const
{
    return fMaxFractionDigits;
}
 
// -------------------------------------
// Sets the maximum number of digits for the fractional part for
// this NumberFormat instance.
 
void
NumberFormat::setMaximumFractionDigits(int32_t newValue)
{
    fMaxFractionDigits = uprv_max(0, uprv_min(newValue, fgMaxIntegerDigits));
    if(fMaxFractionDigits < fMinFractionDigits)
        fMinFractionDigits = fMaxFractionDigits;
}
 
// -------------------------------------
// Gets the minimum number of digits for the fractional part for
// this NumberFormat instance.
 
int32_t
NumberFormat::getMinimumFractionDigits() const
{
    return fMinFractionDigits;
}
 
// -------------------------------------
// Sets the minimum number of digits for the fractional part for
// this NumberFormat instance.
 
void
NumberFormat::setMinimumFractionDigits(int32_t newValue)
{
    fMinFractionDigits = uprv_max(0, uprv_min(newValue, fgMinIntegerDigits));
    if (fMaxFractionDigits < fMinFractionDigits)
        fMaxFractionDigits = fMinFractionDigits;
}
 
// -------------------------------------
// Creates the NumberFormat instance of the specified style (number, currency,
// or percent) for the desired locale.
 
NumberFormat*
NumberFormat::createInstance(const Locale& desiredLocale, 
                             EStyles style, 
                             UErrorCode& status)
{
    if (U_FAILURE(status)) return NULL;

    if (style < 0 || style >= kStyleCount) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }

    ResourceBundle resource((char *)0, desiredLocale, status);
    NumberFormat* f;

    if (U_FAILURE(status))
    {
        // We don't appear to have resource data available -- use the last-resort data
        status = U_USING_FALLBACK_ERROR;
        
        // Use the DecimalFormatSymbols constructor which uses last-resort data
        DecimalFormatSymbols* symbolsToAdopt = new DecimalFormatSymbols(status);
        if (symbolsToAdopt == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        if (U_FAILURE(status)) {
            delete symbolsToAdopt; // This should never happen
            return NULL;
        }

        // Creates a DecimalFormat instance with the last resort number patterns.
        f = new DecimalFormat(fgLastResortNumberPatterns[style], symbolsToAdopt, status);
        if (f == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        if (U_FAILURE(status)) {
            delete f;
            f = NULL;
        }
        return f;
    }

    ResourceBundle numberPatterns(resource.get(DecimalFormat::fgNumberPatterns, status));
    // If not all the styled patterns exists for the NumberFormat in this locale,
    // sets the status code to failure and returns nil.
    //if (patternCount < fgNumberPatternsCount) status = U_INVALID_FORMAT_ERROR;
    if (numberPatterns.getSize() < fgNumberPatternsCount)
        status = U_INVALID_FORMAT_ERROR;
    if (U_FAILURE(status))
        return NULL;

    // Loads the decimal symbols of the desired locale.
    DecimalFormatSymbols* symbolsToAdopt = new DecimalFormatSymbols(desiredLocale, status);
    if (symbolsToAdopt == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    if (U_FAILURE(status)) {
        delete symbolsToAdopt;
        return NULL;
    }

    // Creates the specified decimal format style of the desired locale.
    if (style < numberPatterns.getSize()) {
        const UnicodeString pattern(numberPatterns.getStringEx(style, status));
        if (U_SUCCESS(status)) {
            f = new DecimalFormat(pattern, symbolsToAdopt, status);
        }
        else {
            return NULL;
        }
    }
    else {
        // If the requested style doesn't exist, use a last-resort style.
        // This is to support scientific styles before we have all the
        // resource data in place.
        f = new DecimalFormat(fgLastResortNumberPatterns[style], symbolsToAdopt, status);
    }

    if (f == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    if (U_FAILURE(status)) {
        delete f;
        f = NULL;
    }
    return f;
}

U_NAMESPACE_END

//eof
