/*
*******************************************************************************
* Copyright (C) 1997-2005, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File MSGFMT.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   03/20/97    helena      Finished first cut of implementation.
*   04/10/97    aliu        Made to work on AIX.  Added stoi to replace wtoi.
*   06/11/97    helena      Fixed addPattern to take the pattern correctly.
*   06/17/97    helena      Fixed the getPattern to return the correct pattern.
*   07/09/97    helena      Made ParsePosition into a class.
*   02/22/99    stephen     Removed character literals for EBCDIC safety
********************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/msgfmt.h"
#include "unicode/decimfmt.h"
#include "unicode/datefmt.h"
#include "unicode/smpdtfmt.h"
#include "unicode/choicfmt.h"
#include "unicode/ustring.h"
#include "unicode/ucnv_err.h"
#include "unicode/uchar.h"
#include "unicode/umsg.h"
#include "unicode/rbnf.h"
#include "ustrfmt.h"
#include "cmemory.h"
#include "util.h"
#include "uassert.h"

// *****************************************************************************
// class MessageFormat
// *****************************************************************************

#define COMMA             ((UChar)0x002C)
#define SINGLE_QUOTE      ((UChar)0x0027)
#define LEFT_CURLY_BRACE  ((UChar)0x007B)
#define RIGHT_CURLY_BRACE ((UChar)0x007D)

//---------------------------------------
// static data

static const UChar ID_EMPTY[]     = {
    0 /* empty string, used for default so that null can mark end of list */
};

static const UChar ID_NUMBER[]    = {
    0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0  /* "number" */
};
static const UChar ID_DATE[]      = {
    0x64, 0x61, 0x74, 0x65, 0              /* "date" */
};
static const UChar ID_TIME[]      = {
    0x74, 0x69, 0x6D, 0x65, 0              /* "time" */
};
static const UChar ID_CHOICE[]    = {
    0x63, 0x68, 0x6F, 0x69, 0x63, 0x65, 0  /* "choice" */
};
static const UChar ID_SPELLOUT[]  = {
    0x73, 0x70, 0x65, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0 /* "spellout" */
};
static const UChar ID_ORDINAL[]   = {
    0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0 /* "ordinal" */
};
static const UChar ID_DURATION[]  = {
    0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0 /* "duration" */
};

// MessageFormat Type List  Number, Date, Time or Choice
static const UChar * const TYPE_IDS[] = {
    ID_EMPTY,
    ID_NUMBER,
    ID_DATE,    
    ID_TIME,
    ID_CHOICE,
    ID_SPELLOUT,
    ID_ORDINAL,
    ID_DURATION,
    NULL,
};
 
static const UChar ID_CURRENCY[]  = {
    0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x63, 0x79, 0  /* "currency" */
};
static const UChar ID_PERCENT[]   = {
    0x70, 0x65, 0x72, 0x63, 0x65, 0x6E, 0x74, 0        /* "percent" */
};
static const UChar ID_INTEGER[]   = {
    0x69, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0        /* "integer" */
};

// NumberFormat modifier list, default, currency, percent or integer
static const UChar * const NUMBER_STYLE_IDS[] = {
    ID_EMPTY,
    ID_CURRENCY,
    ID_PERCENT,
    ID_INTEGER,
    NULL,
};

static const UChar ID_SHORT[]     = {
    0x73, 0x68, 0x6F, 0x72, 0x74, 0        /* "short" */
};
static const UChar ID_MEDIUM[]    = {
    0x6D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0  /* "medium" */
};
static const UChar ID_LONG[]      = {
    0x6C, 0x6F, 0x6E, 0x67, 0              /* "long" */
};
static const UChar ID_FULL[]      = {
    0x66, 0x75, 0x6C, 0x6C, 0              /* "full" */
};

// DateFormat modifier list, default, short, medium, long or full
static const UChar * const DATE_STYLE_IDS[] = {
    ID_EMPTY,
    ID_SHORT,
    ID_MEDIUM,
    ID_LONG,
    ID_FULL,
    NULL,
};
 
static const DateFormat::EStyle DATE_STYLES[] = {
    DateFormat::kDefault,
    DateFormat::kShort,
    DateFormat::kMedium,
    DateFormat::kLong,
    DateFormat::kFull,
};

static const int32_t DEFAULT_INITIAL_CAPACITY = 10;

U_NAMESPACE_BEGIN

// -------------------------------------
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MessageFormat)

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

/**
 * Convert a string to an unsigned decimal, ignoring rule whitespace.
 * @return a non-negative number if successful, or a negative number
 *         upon failure.
 */
static int32_t stou(const UnicodeString& string) {
    int32_t n = 0;
    int32_t count = 0;
    UChar32 c;
    for (int32_t i=0; i<string.length(); i+=U16_LENGTH(c)) {
        c = string.char32At(i);
        if (uprv_isRuleWhiteSpace(c)) {
            continue;
        }
        int32_t d = u_digit(c, 10);
        if (d < 0 || ++count > 10) {
            return -1;
        }
        n = 10*n + d;
    }
    return n;
}

/**
 * Convert an integer value to a string and append the result to
 * the given UnicodeString.
 */
static UnicodeString& itos(int32_t i, UnicodeString& appendTo) {
    UChar temp[16];
    uprv_itou(temp,16,i,10,0); // 10 == radix
    appendTo.append(temp);
    return appendTo;
}

// -------------------------------------
// Creates a MessageFormat instance based on the pattern.

MessageFormat::MessageFormat(const UnicodeString& pattern,
                             UErrorCode& success)
: fLocale(Locale::getDefault()),  // Uses the default locale
  formatAliases(NULL),
  formatAliasesCapacity(0),
  subformats(NULL),
  subformatCount(0),
  subformatCapacity(0),
  argTypes(NULL),
  argTypeCount(0),
  argTypeCapacity(0),
  defaultNumberFormat(NULL),
  defaultDateFormat(NULL)
{
    if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
        !allocateArgTypes(DEFAULT_INITIAL_CAPACITY)) {
        success = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    applyPattern(pattern, success);
    setLocaleIDs(fLocale.getName(), fLocale.getName());
}
 
MessageFormat::MessageFormat(const UnicodeString& pattern,
                             const Locale& newLocale,
                             UErrorCode& success)
: fLocale(newLocale),
  formatAliases(NULL),
  formatAliasesCapacity(0),
  subformats(NULL),
  subformatCount(0),
  subformatCapacity(0),
  argTypes(NULL),
  argTypeCount(0),
  argTypeCapacity(0),
  defaultNumberFormat(NULL),
  defaultDateFormat(NULL)
{
    if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
        !allocateArgTypes(DEFAULT_INITIAL_CAPACITY)) {
        success = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    applyPattern(pattern, success);
    setLocaleIDs(fLocale.getName(), fLocale.getName());
}

MessageFormat::MessageFormat(const UnicodeString& pattern,
                             const Locale& newLocale,
                             UParseError& parseError,
                             UErrorCode& success)
: fLocale(newLocale),
  formatAliases(NULL),
  formatAliasesCapacity(0),
  subformats(NULL),
  subformatCount(0),
  subformatCapacity(0),
  argTypes(NULL),
  argTypeCount(0),
  argTypeCapacity(0),
  defaultNumberFormat(NULL),
  defaultDateFormat(NULL)
{
    if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
        !allocateArgTypes(DEFAULT_INITIAL_CAPACITY)) {
        success = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    applyPattern(pattern, parseError, success);
    setLocaleIDs(fLocale.getName(), fLocale.getName());
}

MessageFormat::MessageFormat(const MessageFormat& that)
: Format(that),
  formatAliases(NULL),
  formatAliasesCapacity(0),
  subformats(NULL),
  subformatCount(0),
  subformatCapacity(0),
  argTypes(NULL),
  argTypeCount(0),
  argTypeCapacity(0),
  defaultNumberFormat(NULL),
  defaultDateFormat(NULL)
{
    *this = that;
}

MessageFormat::~MessageFormat()
{
    int32_t idx;
    for (idx = 0; idx < subformatCount; idx++) {
        delete subformats[idx].format;
    }
    uprv_free(subformats);
    subformats = NULL;
    subformatCount = subformatCapacity = 0;

    uprv_free(argTypes);
    argTypes = NULL;
    argTypeCount = argTypeCapacity = 0;

    uprv_free(formatAliases);

    delete defaultNumberFormat;
    delete defaultDateFormat;
}

//--------------------------------------------------------------------
// Variable-size array management

/**
 * Allocate subformats[] to at least the given capacity and return
 * TRUE if successful.  If not, leave subformats[] unchanged.
 *
 * If subformats is NULL, allocate it.  If it is not NULL, enlarge it
 * if necessary to be at least as large as specified.
 */
UBool MessageFormat::allocateSubformats(int32_t capacity) {
    if (subformats == NULL) {
        subformats = (Subformat*) uprv_malloc(sizeof(*subformats) * capacity);
        subformatCapacity = capacity;
        subformatCount = 0;
        if (subformats == NULL) {
            subformatCapacity = 0;
            return FALSE;
        }
    } else if (subformatCapacity < capacity) {
        if (capacity < 2*subformatCapacity) {
            capacity = 2*subformatCapacity;
        }
        Subformat* a = (Subformat*)
            uprv_realloc(subformats, sizeof(*subformats) * capacity);
        if (a == NULL) {
            return FALSE; // request failed
        }
        subformats = a;
        subformatCapacity = capacity;
    }
    return TRUE;
}

/**
 * Allocate argTypes[] to at least the given capacity and return
 * TRUE if successful.  If not, leave argTypes[] unchanged.
 *
 * If argTypes is NULL, allocate it.  If it is not NULL, enlarge it
 * if necessary to be at least as large as specified.
 */
UBool MessageFormat::allocateArgTypes(int32_t capacity) {
    if (argTypes == NULL) {
        argTypes = (Formattable::Type*) uprv_malloc(sizeof(*argTypes) * capacity);
        argTypeCount = 0;
        argTypeCapacity = capacity;
        if (argTypes == NULL) {
            argTypeCapacity = 0;
            return FALSE;
        }
        for (int32_t i=0; i<capacity; ++i) {
            argTypes[i] = Formattable::kString;
        }
    } else if (argTypeCapacity < capacity) {
        if (capacity < 2*argTypeCapacity) {
            capacity = 2*argTypeCapacity;
        }
        Formattable::Type* a = (Formattable::Type*)
            uprv_realloc(argTypes, sizeof(*argTypes) * capacity);
        if (a == NULL) {
            return FALSE; // request failed
        }
        for (int32_t i=argTypeCapacity; i<capacity; ++i) {
            a[i] = Formattable::kString;
        }
        argTypes = a;
        argTypeCapacity = capacity;
    }
    return TRUE;
}

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

const MessageFormat&
MessageFormat::operator=(const MessageFormat& that)
{
    // Reallocate the arrays BEFORE changing this object
    if (this != &that &&
        allocateSubformats(that.subformatCount) &&
        allocateArgTypes(that.argTypeCount)) {

        // Calls the super class for assignment first.
        Format::operator=(that);

        fPattern = that.fPattern;
        setLocale(that.fLocale);
        
        int32_t j;
        for (j=0; j<subformatCount; ++j) {
            delete subformats[j].format;
        }
        subformatCount = 0;
        
        for (j=0; j<that.subformatCount; ++j) {
            // Subformat::operator= does NOT delete this.format
            subformats[j] = that.subformats[j];
        }
        subformatCount = that.subformatCount;
        
        for (j=0; j<that.argTypeCount; ++j) {
            argTypes[j] = that.argTypes[j];
        }
        argTypeCount = that.argTypeCount;
    }
    return *this;
}

UBool
MessageFormat::operator==(const Format& rhs) const 
{
    if (this == &rhs) return TRUE;
    
    MessageFormat& that = (MessageFormat&)rhs;

    // Check class ID before checking MessageFormat members
    if (!Format::operator==(rhs) ||
        fPattern != that.fPattern ||
        fLocale != that.fLocale) {
        return FALSE;
    }

    int32_t j;
    for (j=0; j<subformatCount; ++j) {
        if (subformats[j] != that.subformats[j]) {
            return FALSE;
        }
    }

    return TRUE;
}

// -------------------------------------
// Creates a copy of this MessageFormat, the caller owns the copy.
 
Format*
MessageFormat::clone() const
{
    return new MessageFormat(*this);
}
 
// -------------------------------------
// Sets the locale of this MessageFormat object to theLocale.
 
void
MessageFormat::setLocale(const Locale& theLocale)
{
    if (fLocale != theLocale) {
        delete defaultNumberFormat;
        defaultNumberFormat = NULL;
        delete defaultDateFormat;
        defaultDateFormat = NULL;
    }
    fLocale = theLocale;
    setLocaleIDs(fLocale.getName(), fLocale.getName());
}
 
// -------------------------------------
// Gets the locale of this MessageFormat object.
 
const Locale&
MessageFormat::getLocale() const
{
    return fLocale;
}




void
MessageFormat::applyPattern(const UnicodeString& newPattern, 
                            UErrorCode& status)
{
    UParseError parseError;
    applyPattern(newPattern,parseError,status);
}


// -------------------------------------
// Applies the new pattern and returns an error if the pattern
// is not correct.
void
MessageFormat::applyPattern(const UnicodeString& pattern, 
                            UParseError& parseError,
                            UErrorCode& ec)
{    
    if(U_FAILURE(ec)) {
        return;
    }
    // The pattern is broken up into segments.  Each time a subformat
    // is encountered, 4 segments are recorded.  For example, consider
    // the pattern:
    //  "There {0,choice,0.0#are no files|1.0#is one file|1.0<are {0, number} files} on disk {1}."
    // The first set of segments is:
    //  segments[0] = "There "
    //  segments[1] = "0"
    //  segments[2] = "choice"
    //  segments[3] = "0.0#are no files|1.0#is one file|1.0<are {0, number} files"

    // During parsing, the plain text is accumulated into segments[0].
    // Segments 1..3 are used to parse each subpattern.  Each time a
    // subpattern is parsed, it creates a format object that is stored
    // in the subformats array, together with an offset and argument
    // number.  The offset into the plain text stored in
    // segments[0].

    // Quotes in segment 0 are handled normally.  They are removed.
    // Quotes may not occur in segments 1 or 2.
    // Quotes in segment 3 are parsed and _copied_.  This makes
    //  subformat patterns work, e.g., {1,number,'#'.##} passes
    //  the pattern "'#'.##" to DecimalFormat.

    UnicodeString segments[4];
    int32_t part = 0; // segment we are in, 0..3
    // Record the highest argument number in the pattern.  (In the
    // subpattern {3,number} the argument number is 3.)
    int32_t formatNumber = 0;
    UBool inQuote = FALSE;
    int32_t braceStack = 0;
    // Clear error struct
    parseError.offset = -1;
    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
    int32_t patLen = pattern.length();
    int32_t i;

    for (i=0; i<subformatCount; ++i) {
        delete subformats[i].format;
    }
    subformatCount = 0;
    argTypeCount = 0;

    for (i=0; i<patLen; ++i) {
        UChar ch = pattern[i];
        if (part == 0) {
            // In segment 0, recognize and remove quotes
            if (ch == SINGLE_QUOTE) {
                if (i+1 < patLen && pattern[i+1] == SINGLE_QUOTE) {
                    segments[0] += ch;
                    ++i;
                } else {
                    inQuote = !inQuote;
                }
            } else if (ch == LEFT_CURLY_BRACE && !inQuote) {
                // The only way we get from segment 0 to 1 is via an
                // unquoted '{'.
                part = 1;
            } else {
                segments[0] += ch;
            }
        } else if (inQuote) {
            // In segments 1..3, recognize quoted matter, and copy it
            // into the segment, together with the quotes.  This takes
            // care of '' as well.
            segments[part] += ch;
            if (ch == SINGLE_QUOTE) {
                inQuote = FALSE;
            }
        } else {
            // We have an unquoted character in segment 1..3
            switch (ch) {
            case COMMA:
                // Commas bump us to the next segment, except for segment 3,
                // which can contain commas.  See example above.
                if (part < 3)
                    part += 1;
                else
                    segments[3] += ch;
                break;
            case LEFT_CURLY_BRACE:
                // Handle '{' within segment 3.  The initial '{'
                // before segment 1 is handled above.
                if (part != 3) {
                    ec = U_PATTERN_SYNTAX_ERROR;
                    goto SYNTAX_ERROR;
                }
                ++braceStack;
                segments[part] += ch;
                break;
            case RIGHT_CURLY_BRACE:
                if (braceStack == 0) {
                    makeFormat(formatNumber, segments, parseError,ec);
                    if (U_FAILURE(ec)){
                        goto SYNTAX_ERROR;
                    }
                    formatNumber++;
                    segments[1].remove();
                    segments[2].remove();
                    segments[3].remove();
                    part = 0;
                } else {
                    --braceStack;
                    segments[part] += ch;
                }
                break;
            case SINGLE_QUOTE:
                inQuote = TRUE;
                // fall through (copy quote chars in segments 1..3)
            default:
                segments[part] += ch;
                break;
            }
        }
    }
    if (braceStack != 0 || part != 0) {
        // Unmatched braces in the pattern
        ec = U_UNMATCHED_BRACES;
        goto SYNTAX_ERROR;
    }
    fPattern = segments[0];
    return;

 SYNTAX_ERROR:
    syntaxError(pattern, i, parseError);
    for (i=0; i<subformatCount; ++i) {
        delete subformats[i].format;
    }
    argTypeCount = subformatCount = 0;
}
// -------------------------------------
// Converts this MessageFormat instance to a pattern. 

UnicodeString&
MessageFormat::toPattern(UnicodeString& appendTo) const {
    // later, make this more extensible
    int32_t lastOffset = 0;
    int32_t i;
    for (i=0; i<subformatCount; ++i) {
        copyAndFixQuotes(fPattern, lastOffset, subformats[i].offset, appendTo);
        lastOffset = subformats[i].offset;
        appendTo += LEFT_CURLY_BRACE;
        itos(subformats[i].arg, appendTo);
        Format* fmt = subformats[i].format;
        if (fmt == NULL) {
            // do nothing, string format
        } 
        else if (fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
            
            UErrorCode ec = U_ZERO_ERROR;
            NumberFormat& formatAlias = *(NumberFormat*)fmt;
            NumberFormat *defaultTemplate = NumberFormat::createInstance(fLocale, ec);
            NumberFormat *currencyTemplate = NumberFormat::createCurrencyInstance(fLocale, ec);
            NumberFormat *percentTemplate = NumberFormat::createPercentInstance(fLocale, ec);
            NumberFormat *integerTemplate = createIntegerFormat(fLocale, ec);
 
            appendTo += COMMA;
            appendTo += ID_NUMBER;
            if (formatAlias != *defaultTemplate) {
                appendTo += COMMA;
                if (formatAlias == *currencyTemplate) {
                    appendTo += ID_CURRENCY;
                } 
                else if (formatAlias == *percentTemplate) {
                    appendTo += ID_PERCENT;
                } 
                else if (formatAlias == *integerTemplate) {
                    appendTo += ID_INTEGER;
                } 
                else {
                    UnicodeString buffer;
                    appendTo += ((DecimalFormat*)fmt)->toPattern(buffer);
                }
            }
            
            delete defaultTemplate;
            delete currencyTemplate;
            delete percentTemplate;
            delete integerTemplate;
        } 
        else if (fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
            DateFormat& formatAlias = *(DateFormat*)fmt;
            DateFormat *defaultDateTemplate = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
            DateFormat *shortDateTemplate = DateFormat::createDateInstance(DateFormat::kShort, fLocale);
            DateFormat *longDateTemplate = DateFormat::createDateInstance(DateFormat::kLong, fLocale);
            DateFormat *fullDateTemplate = DateFormat::createDateInstance(DateFormat::kFull, fLocale);
            DateFormat *defaultTimeTemplate = DateFormat::createTimeInstance(DateFormat::kDefault, fLocale);
            DateFormat *shortTimeTemplate = DateFormat::createTimeInstance(DateFormat::kShort, fLocale);
            DateFormat *longTimeTemplate = DateFormat::createTimeInstance(DateFormat::kLong, fLocale);
            DateFormat *fullTimeTemplate = DateFormat::createTimeInstance(DateFormat::kFull, fLocale);
            
            
            appendTo += COMMA;
            if (formatAlias == *defaultDateTemplate) {
                appendTo += ID_DATE;
            } 
            else if (formatAlias == *shortDateTemplate) {
                appendTo += ID_DATE;
                appendTo += COMMA;
                appendTo += ID_SHORT;
            } 
            else if (formatAlias == *defaultDateTemplate) {
                appendTo += ID_DATE;
                appendTo += COMMA;
                appendTo += ID_MEDIUM;
            } 
            else if (formatAlias == *longDateTemplate) {
                appendTo += ID_DATE;
                appendTo += COMMA;
                appendTo += ID_LONG;
            } 
            else if (formatAlias == *fullDateTemplate) {
                appendTo += ID_DATE;
                appendTo += COMMA;
                appendTo += ID_FULL;
            } 
            else if (formatAlias == *defaultTimeTemplate) {
                appendTo += ID_TIME;
            } 
            else if (formatAlias == *shortTimeTemplate) {
                appendTo += ID_TIME;
                appendTo += COMMA;
                appendTo += ID_SHORT;
            } 
            else if (formatAlias == *defaultTimeTemplate) {
                appendTo += ID_TIME;
                appendTo += COMMA;
                appendTo += ID_MEDIUM;
            } 
            else if (formatAlias == *longTimeTemplate) {
                appendTo += ID_TIME;
                appendTo += COMMA;
                appendTo += ID_LONG;
            } 
            else if (formatAlias == *fullTimeTemplate) {
                appendTo += ID_TIME;
                appendTo += COMMA;
                appendTo += ID_FULL;
            } 
            else {
                UnicodeString buffer;
                appendTo += ID_DATE;
                appendTo += COMMA;
                appendTo += ((SimpleDateFormat*)fmt)->toPattern(buffer);
            }
            
            delete defaultDateTemplate;
            delete shortDateTemplate;
            delete longDateTemplate;
            delete fullDateTemplate;
            delete defaultTimeTemplate;
            delete shortTimeTemplate;
            delete longTimeTemplate;
            delete fullTimeTemplate;
            // {sfb} there should be a more efficient way to do this!
        } 
        else if (fmt->getDynamicClassID() == ChoiceFormat::getStaticClassID()) {
            UnicodeString buffer;
            appendTo += COMMA;
            appendTo += ID_CHOICE;
            appendTo += COMMA;
            appendTo += ((ChoiceFormat*)fmt)->toPattern(buffer);
        } 
        else {
            //appendTo += ", unknown";
        }
        appendTo += RIGHT_CURLY_BRACE;
    }
    copyAndFixQuotes(fPattern, lastOffset, fPattern.length(), appendTo);
    return appendTo;
}
 
// -------------------------------------
// Adopts the new formats array and updates the array count.
// This MessageFormat instance owns the new formats.
 
void
MessageFormat::adoptFormats(Format** newFormats,
                            int32_t count) {
    if (newFormats == NULL || count < 0) {
        return;
    }
    
    int32_t i;
    if (allocateSubformats(count)) {
        for (i=0; i<subformatCount; ++i) {
            delete subformats[i].format;
        }
        for (i=0; i<count; ++i) {
            subformats[i].format = newFormats[i];
        }
        subformatCount = count;
    } else {
        // An adopt method must always take ownership.  Delete
        // the incoming format objects and return unchanged.
        for (i=0; i<count; ++i) {
            delete newFormats[i];
        }
    }

    // TODO: What about the .offset and .arg fields?
}   

// -------------------------------------
// Sets the new formats array and updates the array count.
// This MessageFormat instance maks a copy of the new formats.
 
void
MessageFormat::setFormats(const Format** newFormats,
                          int32_t count) {
    if (newFormats == NULL || count < 0) {
        return;
    }

    if (allocateSubformats(count)) {
        int32_t i; 
        for (i=0; i<subformatCount; ++i) {
            delete subformats[i].format;
        }
        subformatCount = 0;

        for (i=0; i<count; ++i) {
            subformats[i].format = newFormats[i] ? newFormats[i]->clone() : NULL;
        }
        subformatCount = count;
    }

    // TODO: What about the .offset and .arg fields?
}   
 
// -------------------------------------
// Adopt a single format.
// Do nothing is the format number is not less than the array count.
 
void
MessageFormat::adoptFormat(int32_t n, Format *newFormat) {
    if (n < 0 || n >= subformatCount) {
        delete newFormat;
    } else {
        delete subformats[n].format;
        subformats[n].format = newFormat;
    }
}

// -------------------------------------
// Set a single format.
// Do nothing is the variable is not less than the array count.
 
void
MessageFormat::setFormat(int32_t n, const Format& newFormat) {
    if (n >= 0 && n < subformatCount) {
        delete subformats[n].format;
        if (&newFormat == NULL) {
            // This should never happen -- but we'll be nice if it does
            subformats[n].format = NULL;
        } else {
            subformats[n].format = newFormat.clone();
        }
    }
}
 
// -------------------------------------
// Gets the format array.
 
const Format**
MessageFormat::getFormats(int32_t& cnt) const
{
    // This old API returns an array (which we hold) of Format*
    // pointers.  The array is valid up to the next call to any
    // method on this object.  We construct and resize an array
    // on demand that contains aliases to the subformats[i].format
    // pointers.
    MessageFormat* t = (MessageFormat*) this;
    cnt = 0;
    if (formatAliases == NULL) {
        t->formatAliasesCapacity = (subformatCount<10) ? 10 : subformatCount;
        Format** a = (Format**)
            uprv_malloc(sizeof(Format*) * formatAliasesCapacity);
        if (a == NULL) {
            return NULL;
        }
        t->formatAliases = a;        
    } else if (subformatCount > formatAliasesCapacity) {
        Format** a = (Format**)
            uprv_realloc(formatAliases, sizeof(Format*) * subformatCount);
        if (a == NULL) {
            return NULL;
        }
        t->formatAliases = a;
        t->formatAliasesCapacity = subformatCount;
    }
    for (int32_t i=0; i<subformatCount; ++i) {
        t->formatAliases[i] = subformats[i].format;
    }
    cnt = subformatCount;
    return (const Format**)formatAliases;
}
 
// -------------------------------------
// Formats the source Formattable array and copy into the result buffer.
// Ignore the FieldPosition result for error checking.
 
UnicodeString&
MessageFormat::format(const Formattable* source,
                      int32_t cnt, 
                      UnicodeString& appendTo, 
                      FieldPosition& ignore, 
                      UErrorCode& success) const
{
    if (U_FAILURE(success)) 
        return appendTo;
    
    return format(source, cnt, appendTo, ignore, 0, success);
}
 
// -------------------------------------
// Internally creates a MessageFormat instance based on the
// pattern and formats the arguments Formattable array and 
// copy into the appendTo buffer.
 
UnicodeString&
MessageFormat::format(  const UnicodeString& pattern,
                        const Formattable* arguments,
                        int32_t cnt,
                        UnicodeString& appendTo, 
                        UErrorCode& success)
{
    MessageFormat temp(pattern, success);
    FieldPosition ignore(0);
    temp.format(arguments, cnt, appendTo, ignore, success);
    return appendTo;
}
 
// -------------------------------------
// Formats the source Formattable object and copy into the 
// appendTo buffer.  The Formattable object must be an array
// of Formattable instances, returns error otherwise.
 
UnicodeString&
MessageFormat::format(const Formattable& source, 
                      UnicodeString& appendTo, 
                      FieldPosition& ignore, 
                      UErrorCode& success) const
{
    int32_t cnt;

    if (U_FAILURE(success)) 
        return appendTo;
    if (source.getType() != Formattable::kArray) {
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    const Formattable* tmpPtr = source.getArray(cnt);
    
    return format(tmpPtr, cnt, appendTo, ignore, 0, success);
}
 
// -------------------------------------
// Formats the arguments Formattable array and copy into the appendTo buffer.
// Ignore the FieldPosition result for error checking.

UnicodeString&
MessageFormat::format(const Formattable* arguments, 
                      int32_t cnt, 
                      UnicodeString& appendTo, 
                      FieldPosition& status, 
                      int32_t recursionProtection,
                      UErrorCode& success) const 
{
    // Allow NULL array only if cnt == 0
    if (cnt < 0 || (cnt && arguments == NULL)) {
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    
    int32_t lastOffset = 0;
    for (int32_t i=0; i<subformatCount; ++i) {
        // Append the prefix of current format element.
        appendTo.append(fPattern, lastOffset, subformats[i].offset - lastOffset);
        lastOffset = subformats[i].offset;
        int32_t argumentNumber = subformats[i].arg;
        // Checks the scope of the argument number.
        if (argumentNumber >= cnt) {
            appendTo += LEFT_CURLY_BRACE;
            itos(argumentNumber, appendTo);
            appendTo += RIGHT_CURLY_BRACE;
            continue;
        }

        const Formattable *obj = arguments + argumentNumber;
        Formattable::Type type = obj->getType();

        // Recursively calling the format process only if the current
        // format argument refers to a ChoiceFormat object.
        Format* fmt = subformats[i].format;
        if (fmt != NULL) {
            UnicodeString arg;
            fmt->format(*obj, arg, success);

            // Needs to reprocess the ChoiceFormat option by using the
            // MessageFormat pattern application.
            if (fmt->getDynamicClassID() == ChoiceFormat::getStaticClassID() &&
                arg.indexOf(LEFT_CURLY_BRACE) >= 0) {
                MessageFormat temp(arg, fLocale, success);
                // TODO: Implement recursion protection
                temp.format(arguments, cnt, appendTo, status, recursionProtection, success);
                if (U_FAILURE(success)) { 
                    return appendTo; 
                }
            }
            else {
                appendTo += arg;
            }
        }
        // If the obj data type is a number, use a NumberFormat instance.
        else if ((type == Formattable::kDouble) || 
                 (type == Formattable::kLong) ||
                 (type == Formattable::kInt64)) {

            const NumberFormat* nf = getDefaultNumberFormat(success);
            if (nf == NULL) { 
                return appendTo; 
            }
            if (type == Formattable::kDouble) {
                nf->format(obj->getDouble(), appendTo);
            } else if (type == Formattable::kLong) {
                nf->format(obj->getLong(), appendTo);
            } else {
                nf->format(obj->getInt64(), appendTo);
            }
        }
        // If the obj data type is a Date instance, use a DateFormat instance.
        else if (type == Formattable::kDate) {
            const DateFormat* df = getDefaultDateFormat(success);
            if (df == NULL) { 
                return appendTo; 
            }
            df->format(obj->getDate(), appendTo);
        }
        else if (type == Formattable::kString) {
            appendTo += obj->getString();
        }
        else {
            success = U_ILLEGAL_ARGUMENT_ERROR;
            return appendTo;
        }
    }
    // Appends the rest of the pattern characters after the real last offset.
    appendTo.append(fPattern, lastOffset, 0x7fffffff);
    return appendTo;
}


// -------------------------------------
// Parses the source pattern and returns the Formattable objects array,
// the array count and the ending parse position.  The caller of this method 
// owns the array.
 
Formattable*
MessageFormat::parse(const UnicodeString& source, 
                     ParsePosition& pos,
                     int32_t& count) const
{
    // Allocate at least one element.  Allocating an array of length
    // zero causes problems on some platforms (e.g. Win32).
    Formattable *resultArray = new Formattable[argTypeCount ? argTypeCount : 1];
    int32_t patternOffset = 0;
    int32_t sourceOffset = pos.getIndex();
    ParsePosition tempPos(0);
    count = 0; // {sfb} reset to zero
    int32_t len;
    for (int32_t i = 0; i < subformatCount; ++i) {
        // match up to format
        len = subformats[i].offset - patternOffset;
        if (len == 0 || 
            fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
            sourceOffset += len;
            patternOffset += len;
        } 
        else {
            goto PARSE_ERROR;
        }
        
        // now use format
        Format* fmt = subformats[i].format;
        int32_t arg = subformats[i].arg;
        if (fmt == NULL) {   // string format
            // if at end, use longest possible match
            // otherwise uses first match to intervening string
            // does NOT recursively try all possibilities
            int32_t tempLength = (i+1<subformatCount) ?
                subformats[i+1].offset : fPattern.length();
            
            int32_t next;
            if (patternOffset >= tempLength) {
                next = source.length();
            }
            else {
                UnicodeString buffer;
                fPattern.extract(patternOffset,tempLength - patternOffset, buffer);
                next = source.indexOf(buffer, sourceOffset);
            }
            
            if (next < 0) {
                goto PARSE_ERROR;
            } 
            else {
                UnicodeString buffer;
                source.extract(sourceOffset,next - sourceOffset, buffer);
                UnicodeString strValue = buffer;
                UnicodeString temp(LEFT_CURLY_BRACE);
                // {sfb} check this later
                itos(arg, temp);
                temp += RIGHT_CURLY_BRACE;
                if (strValue != temp) {
                    source.extract(sourceOffset,next - sourceOffset, buffer);
                    resultArray[arg].setString(buffer);
                    // {sfb} not sure about this
                    if ((arg + 1) > count) {
                        count = arg + 1;
                    }
                }
                sourceOffset = next;
            }
        } 
        else {
            tempPos.setIndex(sourceOffset);
            fmt->parseObject(source, resultArray[arg], tempPos);
            if (tempPos.getIndex() == sourceOffset) {
                goto PARSE_ERROR;
            }
            
            if ((arg + 1) > count) {
                count = arg + 1;
            }
            sourceOffset = tempPos.getIndex(); // update
        }
    }
    len = fPattern.length() - patternOffset;
    if (len == 0 || 
        fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
        pos.setIndex(sourceOffset + len);
        return resultArray;
    }
    // else fall through...

 PARSE_ERROR:
    pos.setErrorIndex(sourceOffset);
    delete [] resultArray;
    count = 0;
    return NULL; // leave index as is to signal error
}
 
// -------------------------------------
// Parses the source string and returns the array of 
// Formattable objects and the array count.  The caller 
// owns the returned array.
 
Formattable*
MessageFormat::parse(const UnicodeString& source, 
                     int32_t& cnt,
                     UErrorCode& success) const
{
    ParsePosition status(0);
    // Calls the actual implementation method and starts
    // from zero offset of the source text.
    Formattable* result = parse(source, status, cnt);
    if (status.getIndex() == 0) {
        success = U_MESSAGE_PARSE_ERROR;
        delete[] result;
        return NULL;
    }
    return result;
}
 
// -------------------------------------
// Parses the source text and copy into the result buffer.
 
void
MessageFormat::parseObject( const UnicodeString& source,
                            Formattable& result,
                            ParsePosition& status) const
{
    int32_t cnt = 0;
    Formattable* tmpResult = parse(source, status, cnt);
    if (tmpResult != NULL) 
        result.adoptArray(tmpResult, cnt);
}
  
UnicodeString 
MessageFormat::autoQuoteApostrophe(const UnicodeString& pattern, UErrorCode& status) {
  UnicodeString result;
  if (U_SUCCESS(status)) {
    int32_t plen = pattern.length();
    const UChar* pat = pattern.getBuffer();
    int32_t blen = plen * 2 + 1; // space for null termination, convenience
    UChar* buf = result.getBuffer(blen);
    if (buf == NULL) {
      status = U_MEMORY_ALLOCATION_ERROR;
    } else {
      int32_t len = umsg_autoQuoteApostrophe(pat, plen, buf, blen, &status);
      result.releaseBuffer(U_SUCCESS(status) ? len : 0);
    }
  }
  if (U_FAILURE(status)) {
    result.setToBogus();
  }
  return result;
}

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

static Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const UnicodeString& defaultRuleSet, UErrorCode& ec) {
    RuleBasedNumberFormat* fmt = new RuleBasedNumberFormat(tag, locale, ec);
    if (U_SUCCESS(ec) && defaultRuleSet.length() > 0) {
        fmt->setDefaultRuleSet(defaultRuleSet, ec);
    if (U_FAILURE(ec)) { // ignore unrecognized default rule set
        ec = U_ZERO_ERROR;
    }
    }
    return fmt;
}
 
/**
 * Reads the segments[] array (see applyPattern()) and parses the
 * segments[1..3] into a Format* object.  Stores the format object in
 * the subformats[] array.  Updates the argTypes[] array type
 * information for the corresponding argument.
 *
 * @param formatNumber index into subformats[] for this format
 * @param segments array of strings with the parsed pattern segments
 * @param parseError parse error data (output param)
 * @param ec error code
 */
void
MessageFormat::makeFormat(int32_t formatNumber, 
                          UnicodeString* segments,
                          UParseError& parseError,
                          UErrorCode& ec) {
    if (U_FAILURE(ec)) {
        return;
    }

    // Parse the argument number
    int32_t argumentNumber = stou(segments[1]); // always unlocalized!
    if (argumentNumber < 0) {
        ec = U_INVALID_FORMAT_ERROR;
        return;
    }

    // Parse the format, recording the argument type and creating a
    // new Format object (except for string arguments).
    Formattable::Type argType;
    Format *fmt = NULL;
    int32_t typeID, styleID;
    DateFormat::EStyle style;

    switch (typeID = findKeyword(segments[2], TYPE_IDS)) {

    case 0: // string
        argType = Formattable::kString;
        break;

    case 1: // number
        argType = Formattable::kDouble;

        switch (findKeyword(segments[3], NUMBER_STYLE_IDS)) {
        case 0: // default
            fmt = NumberFormat::createInstance(fLocale, ec);
            break;
        case 1: // currency
            fmt = NumberFormat::createCurrencyInstance(fLocale, ec);
            break;
        case 2: // percent
            fmt = NumberFormat::createPercentInstance(fLocale, ec);
            break;
        case 3: // integer
            argType = Formattable::kLong;
            fmt = createIntegerFormat(fLocale, ec);
            break;
        default: // pattern
            fmt = NumberFormat::createInstance(fLocale, ec);
            if (fmt &&
                fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
                ((DecimalFormat*)fmt)->applyPattern(segments[3],parseError,ec);
            }
            break;
        }
        break;

    case 2: // date
    case 3: // time
        argType = Formattable::kDate;
        styleID = findKeyword(segments[3], DATE_STYLE_IDS);
        style = (styleID >= 0) ? DATE_STYLES[styleID] : DateFormat::kDefault;

        if (typeID == 2) {
            fmt = DateFormat::createDateInstance(style, fLocale);
        } else {
            fmt = DateFormat::createTimeInstance(style, fLocale);
        }

        if (styleID < 0 &&
            fmt != NULL &&
            fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
            ((SimpleDateFormat*)fmt)->applyPattern(segments[3]);
        }
        break;

    case 4: // choice
        argType = Formattable::kDouble;

        fmt = new ChoiceFormat(segments[3], parseError, ec);
        break;

    case 5: // spellout
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_SPELLOUT, fLocale, segments[3], ec);
        break;
    case 6: // ordinal
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_ORDINAL, fLocale, segments[3], ec);
        break;
    case 7: // duration
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_DURATION, fLocale, segments[3], ec);
        break;
    default:
        argType = Formattable::kString;
        ec = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }

    if (fmt==NULL && argType!=Formattable::kString && U_SUCCESS(ec)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }
    
    if (!allocateSubformats(formatNumber+1) ||
        !allocateArgTypes(argumentNumber+1)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }

    if (U_FAILURE(ec)) {
        delete fmt;
        return;
    }

    // Parse succeeded; record results in our arrays
    subformats[formatNumber].format = fmt;
    subformats[formatNumber].offset = segments[0].length();
    subformats[formatNumber].arg = argumentNumber;
    subformatCount = formatNumber+1;

    // Careful here: argumentNumber may in general arrive out of
    // sequence, e.g., "There was {2} on {0,date} (see {1,number})."
    argTypes[argumentNumber] = argType;
    if (argumentNumber+1 > argTypeCount) {
        argTypeCount = argumentNumber+1;
    }
}
 
// -------------------------------------
// Finds the string, s, in the string array, list. 
int32_t MessageFormat::findKeyword(const UnicodeString& s, 
                                   const UChar * const *list)
{
    if (s.length() == 0)
        return 0; // default

    UnicodeString buffer = s;
    // Trims the space characters and turns all characters
    // in s to lower case.
    buffer.trim().toLower("");
    for (int32_t i = 0; list[i]; ++i) {
        if (!buffer.compare(list[i], u_strlen(list[i]))) {
            return i;
        }
    }
    return -1;
}
  
// -------------------------------------
// Checks the range of the source text to quote the special
// characters, { and ' and copy to target buffer.
 
void
MessageFormat::copyAndFixQuotes(const UnicodeString& source, 
                                int32_t start, 
                                int32_t end, 
                                UnicodeString& appendTo)
{
    UBool gotLB = FALSE;
    
    for (int32_t i = start; i < end; ++i) {
        UChar ch = source[i];
        if (ch == LEFT_CURLY_BRACE) {
            appendTo += SINGLE_QUOTE;
            appendTo += LEFT_CURLY_BRACE;
            appendTo += SINGLE_QUOTE;
            gotLB = TRUE;
        } 
        else if (ch == RIGHT_CURLY_BRACE) {
            if(gotLB) {
                appendTo += RIGHT_CURLY_BRACE;
                gotLB = FALSE;
            }
            else {
                // orig code.
                appendTo += SINGLE_QUOTE;
                appendTo += RIGHT_CURLY_BRACE;
                appendTo += SINGLE_QUOTE;
            }
        } 
        else if (ch == SINGLE_QUOTE) {
            appendTo += SINGLE_QUOTE;
            appendTo += SINGLE_QUOTE;
        } 
        else {
            appendTo += ch;
        }
    }
}

/**
 * Convenience method that ought to be in NumberFormat
 */
NumberFormat* 
MessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) const {
    NumberFormat *temp = NumberFormat::createInstance(locale, status);
    if (temp != NULL && temp->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
        DecimalFormat *temp2 = (DecimalFormat*) temp;
        temp2->setMaximumFractionDigits(0);
        temp2->setDecimalSeparatorAlwaysShown(FALSE);
        temp2->setParseIntegerOnly(TRUE);
    }

    return temp;
}

/**
 * Return the default number format.  Used to format a numeric
 * argument when subformats[i].format is NULL.  Returns NULL
 * on failure.
 *
 * Semantically const but may modify *this.
 */
const NumberFormat* MessageFormat::getDefaultNumberFormat(UErrorCode& ec) const {
    if (defaultNumberFormat == NULL) {
        MessageFormat* t = (MessageFormat*) this;
        t->defaultNumberFormat = NumberFormat::createInstance(fLocale, ec);
        if (U_FAILURE(ec)) { 
            delete t->defaultNumberFormat;
            t->defaultNumberFormat = NULL;
        } else if (t->defaultNumberFormat == NULL) {
            ec = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    return defaultNumberFormat;
}

/**
 * Return the default date format.  Used to format a date
 * argument when subformats[i].format is NULL.  Returns NULL
 * on failure.
 *
 * Semantically const but may modify *this.
 */
const DateFormat* MessageFormat::getDefaultDateFormat(UErrorCode& ec) const {
    if (defaultDateFormat == NULL) {
        MessageFormat* t = (MessageFormat*) this;
        t->defaultDateFormat = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale);
        if (t->defaultDateFormat == NULL) {
            ec = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    return defaultDateFormat;
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
