/*
*******************************************************************************
* Copyright (C) 1997-1999, 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/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 "ustrfmt.h"
#include "cmemory.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 g_umsg_number[]    = {
    0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0  /* "number" */
};
static const UChar g_umsg_date[]      = {
    0x64, 0x61, 0x74, 0x65, 0  /* "date" */
};
static const UChar g_umsg_time[]      = {
    0x74, 0x69, 0x6D, 0x65, 0  /* "time" */
};
static const UChar g_umsg_choice[]    = {
    0x63, 0x68, 0x6F, 0x69, 0x63, 0x65, 0  /* "choice" */
};

// MessageFormat Type List  Number, Date, Time or Choice
static const UChar * const g_umsgTypeList[] = {
    NULL,           NULL,           g_umsg_number,
    NULL,           g_umsg_date,    NULL,
    g_umsg_time,    NULL,           g_umsg_choice
};
 
static const UChar g_umsg_currency[]  = {
    0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x63, 0x79, 0  /* "currency" */
};
static const UChar g_umsg_percent[]   = {
    0x70, 0x65, 0x72, 0x63, 0x65, 0x6E, 0x74, 0    /* "percent" */
};
static const UChar g_umsg_integer[]   = {
    0x69, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0    /* "integer" */
};

// NumberFormat modifier list, default, currency, percent or integer
static const UChar * const g_umsgModifierList[] = {
    NULL,           NULL,           g_umsg_currency,
    NULL,           g_umsg_percent, NULL,
    g_umsg_integer, NULL,           NULL
};
 
static const UChar g_umsg_short[]     = {
    0x73, 0x68, 0x6F, 0x72, 0x74, 0    /* "short" */
};
static const UChar g_umsg_medium[]    = {
    0x6D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0  /* "medium" */
};
static const UChar g_umsg_long[]      = {
    0x6C, 0x6F, 0x6E, 0x67, 0  /* "long" */
};
static const UChar g_umsg_full[]      = {
    0x66, 0x75, 0x6C, 0x6C, 0  /* "full" */
};

// DateFormat modifier list, default, short, medium, long or full
static const UChar * const g_umsgDateModifierList[] = {
    NULL,           NULL,           g_umsg_short,
    NULL,           g_umsg_medium,  NULL,
    g_umsg_long,    NULL,           g_umsg_full
};
 
static const int32_t g_umsgListLength = 9;


U_NAMESPACE_BEGIN

// -------------------------------------
const char MessageFormat::fgClassID = 0; // Value is irrelevant

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

MessageFormat::MessageFormat(const UnicodeString& pattern,
                             UErrorCode& success)
: fLocale(Locale::getDefault()),  // Uses the default locale
  fOffsets(NULL),
  fCount(kMaxFormat),
  fArgumentNumbers(NULL)
{
    fOffsets = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    fArgumentNumbers = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    for (int32_t i = 0; i < fCount; i++) {
        fFormats[i] = NULL;       // Format instances
        fOffsets[i] = 0;          // Starting offset
        fArgumentNumbers[i] = 0;  // Argument numbers.
    }
    applyPattern(pattern, success);
}
 
MessageFormat::MessageFormat(const UnicodeString& pattern,
                             const Locale& newLocale,
                             UErrorCode& success)
: fLocale(newLocale),  // Uses the default locale
  fOffsets(NULL),
  fCount(kMaxFormat),
  fArgumentNumbers(NULL)
{
    fOffsets = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    fArgumentNumbers = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    for (int32_t i = 0; i < fCount; i++) {
        fFormats[i] = NULL;       // Format instances
        fOffsets[i] = 0;          // Starting offset
        fArgumentNumbers[i] = 0;  // Argument numbers.
    }
    applyPattern(pattern, success);
}

MessageFormat::MessageFormat(const UnicodeString& pattern,
                             const Locale& newLocale,
                             UParseError& parseError,
                             UErrorCode& success)
: fLocale(newLocale),  // Uses the default locale
  fOffsets(NULL),
  fCount(kMaxFormat),
  fArgumentNumbers(NULL)
{
    fOffsets = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    fArgumentNumbers = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
    for (int32_t i = 0; i < fCount; i++) {
        fFormats[i] = NULL;       // Format instances
        fOffsets[i] = 0;          // Starting offset
        fArgumentNumbers[i] = 0;  // Argument numbers.
    }
    applyPattern(pattern,parseError, success);
}

MessageFormat::~MessageFormat()
{
    for (int32_t i = 0; i < fCount; i++) {
        if (fFormats[i]) {
            delete fFormats[i];
        }
    }
    uprv_free(fOffsets);
    uprv_free(fArgumentNumbers);
    fCount = 0;
}

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

MessageFormat::MessageFormat(const MessageFormat& that)
: Format(that),
  fLocale(that.fLocale),
  fPattern(that.fPattern),
  fOffsets((int32_t *)uprv_malloc(that.fCount * sizeof(int32_t))),
  fCount(that.fCount),
  fArgumentNumbers((int32_t *)uprv_malloc(that.fCount * sizeof(int32_t))),
  fMaxOffset(that.fMaxOffset)
{
    // Sets up the format instance array, offsets and argument numbers.
    for (int32_t i = 0; i < fCount; i++) {
        fFormats[i] = NULL; // init since delete may be called
        if (that.fFormats[i] != NULL) {
            setFormat(i, *(that.fFormats[i]) );  // setFormat clones the format
        }
        fOffsets[i] = that.fOffsets[i];
        fArgumentNumbers[i] = that.fArgumentNumbers[i];
    }
}

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

const MessageFormat&
MessageFormat::operator=(const MessageFormat& that)
{
    if (this != &that) {
        // Calls the super class for assignment first.
        Format::operator=(that);
        // Cleans up the format array and the offsets, argument numbers.
        for (int32_t j = 0; j < fCount; j++) {
            delete fFormats[j];
            fFormats[j] = NULL;
        }
        uprv_free(fOffsets);
        fOffsets = NULL;
        uprv_free(fArgumentNumbers);
        fArgumentNumbers = NULL;
        fPattern = that.fPattern;
        fLocale = that.fLocale;
        fCount = that.fCount;
        fMaxOffset = that.fMaxOffset;
        fOffsets = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
        fArgumentNumbers = (int32_t*) uprv_malloc( sizeof(int32_t) * fCount );
        // Sets up the format instance array, offsets and argument numbers.
        for (int32_t i = 0; i < fCount; i++) {
            if (that.fFormats[i] == NULL) {
                fFormats[i] = NULL;
            }else{
                adoptFormat(i, that.fFormats[i]->clone());
            }
            fOffsets[i] = that.fOffsets[i];
            fArgumentNumbers[i] = that.fArgumentNumbers[i];
        }
    }
    return *this;
}

UBool
MessageFormat::operator==(const Format& that) const 
{
    if (this == &that) return TRUE;
    // Are the instances derived from the same Format class?
    if (getStaticClassID() != that.getDynamicClassID()) return FALSE;  // not the same class
    // Calls the super class for equality check first.
    if (!Format::operator==(that)) return FALSE;
    MessageFormat& thatAlias = (MessageFormat&)that;
    // Checks the pattern, locale and array count of this MessageFormat object.
    if (fMaxOffset != thatAlias.fMaxOffset) return FALSE;
    if (fPattern != thatAlias.fPattern) return FALSE;
    if (fLocale != thatAlias.fLocale) return FALSE;
    if (fCount != thatAlias.fCount) return FALSE;
    // Checks each element in the arrays for equality last.
    for (int32_t i = 0; i < fCount; i++) {
        if ((fFormats[i] != thatAlias.fFormats[i]) ||
            (fOffsets[i] != thatAlias.fOffsets[i]) ||
            (fArgumentNumbers[i] != thatAlias.fArgumentNumbers[i]))
            return FALSE;
    }
    return TRUE;
}

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


#if 0 
// -------------------------------------
// Applies the new pattern and returns an error if the pattern
// is not correct.
// For example, consider the pattern, 
// "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}"
// The segments would look like the following,
// segments[0] == "There "
// segments[1] == "0"
// segments[2] == "{0,choice,0#are no files|1#is one file|1<are {0,number,integer}"
// segments[3] == " files"
 
void
MessageFormat::applyPattern(const UnicodeString& newPattern, 
                            UErrorCode& success)
{
    UnicodeString segments[4];
    int32_t part = 0;
    int32_t formatNumber = 0;
    UBool inQuote = FALSE;
    int32_t braceStack = 0;
    fMaxOffset = -1;
    for (int i = 0; i < newPattern.length(); ++i) {
        UChar ch = newPattern[i];
        if (part == 0) {
            if (ch == SINGLE_QUOTE) {
                if (i + 1 < newPattern.length()
                    && newPattern[i+1] == SINGLE_QUOTE) {
                    segments[part] += ch;  // handle doubles
                    ++i;
                } else {
                    inQuote = !inQuote;
                }
            } else if (ch == LEFT_CURLY_BRACE && !inQuote) {
                part = 1;
            } else {
                segments[part] += ch;
            }
        } else  if (inQuote) {              // just copy quotes in parts
            segments[part] += ch;
            if (ch == SINGLE_QUOTE) {
                inQuote = FALSE;
            }
        } else {
            switch (ch) {
            case COMMA:
                if (part < 3)
                    part += 1;
                else
                    segments[part] += ch;
                break;
            case LEFT_CURLY_BRACE:
                ++braceStack;
                segments[part] += ch;
                break;
            case RIGHT_CURLY_BRACE:
                if (braceStack == 0) {
                    part = 0;
                    makeFormat(/*i,*/ formatNumber, segments, success);
                    if(U_FAILURE(success))
                        return;
                    formatNumber++;
                } else {
                    --braceStack;
                    segments[part] += ch;
                }
                break;
            case SINGLE_QUOTE:
                inQuote = TRUE;
                // fall through, so we keep quotes in other parts
            default:
                segments[part] += ch;
                break;
            }
        }
    }
    if (braceStack == 0 && part != 0) {
        fMaxOffset = -1;
        success = U_INVALID_FORMAT_ERROR;
        return;
        //throw new IllegalArgumentException("Unmatched braces in the pattern.");
    }
    fPattern = segments[0];
}
#endif 


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


void
MessageFormat::applyPattern(const UnicodeString& newPattern, 
                            UParseError& parseError,
                            UErrorCode& success)
{
    
    if(U_FAILURE(success))
    {
        return;
    }
    UnicodeString segments[4];
    int32_t part = 0;
    int32_t maxFormatNumber = 0;
    int32_t formatNumber = 0;
    UBool inQuote = FALSE;
    int32_t braceStack = 0;
    int32_t i = 0;
    fMaxOffset = -1;
    // Clear error struct
    parseError.offset = -1;
    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
    int32_t patLen = newPattern.length();
    for (; i < patLen; ++i) {
        int32_t currFormatNumber;
        UChar ch = newPattern[i];
        if (part == 0) {
            if (ch == SINGLE_QUOTE) {
                if (i + 1 < patLen && newPattern[i+1] == SINGLE_QUOTE) {
                    segments[part] += ch;  // handle doubles
                    ++i;
                } else {
                    inQuote = !inQuote;
                }
            } else if (ch == LEFT_CURLY_BRACE && !inQuote) {
                part = 1;
            } else {
                segments[part] += ch;
            }
        } else  if (inQuote) {              // just copy quotes in parts
            segments[part] += ch;
            if (ch == SINGLE_QUOTE) {
                inQuote = FALSE;
            }
        } else {
            switch (ch) {
            case COMMA:
                if (part < 3)
                    part += 1;
                else
                    segments[part] += ch;
                break;
            case LEFT_CURLY_BRACE:
                ++braceStack;
                segments[part] += ch;
                break;
            case RIGHT_CURLY_BRACE:
                if (braceStack == 0) {
                    part = 0;
                    currFormatNumber = makeFormat(/*i,*/ formatNumber, segments, parseError,success);
                    if(U_FAILURE(success)){
                        syntaxError(newPattern,i,parseError);
                        return;
                    }
                    formatNumber++;
                    if (currFormatNumber > maxFormatNumber) {
                        maxFormatNumber = currFormatNumber;
                    }
                } else {
                    --braceStack;
                    segments[part] += ch;
                }
                break;
            case SINGLE_QUOTE:
                inQuote = TRUE;
                // fall through, so we keep quotes in other parts
            default:
                segments[part] += ch;
                break;
            }
        }
    }
    if (braceStack == 0 && part != 0) {
        fMaxOffset = -1;
        success = U_UNMATCHED_BRACES;
        syntaxError(newPattern,i,parseError);
        return;
        //throw new IllegalArgumentException("Unmatched braces in the pattern.");
    }
    fPattern = segments[0];
    fListCount = maxFormatNumber + 1;
}
// -------------------------------------
// Converts this MessageFormat instance to a pattern. 
UnicodeString&
MessageFormat::toPattern(UnicodeString& result) const
{
    // later, make this more extensible
    int32_t lastOffset = 0;
    for (int i = 0; i <= fMaxOffset; ++i) {
        copyAndFixQuotes(fPattern, lastOffset, fOffsets[i], result);
        lastOffset = fOffsets[i];
        result += LEFT_CURLY_BRACE;
        // {sfb} check this later
        //result += (UChar) (fArgumentNumbers[i] + '0');
        UnicodeString temp;
        result += itos(fArgumentNumbers[i], temp);
        if (fFormats[i] == NULL) {
            // do nothing, string format
        } 
        else if (fFormats[i]->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
            
            UErrorCode status = U_ZERO_ERROR;
            NumberFormat& formatAlias = *(NumberFormat*)fFormats[i];
            NumberFormat *numberTemplate = NumberFormat::createInstance(fLocale, status);
            NumberFormat *currencyTemplate = NumberFormat::createCurrencyInstance(fLocale, status);
            NumberFormat *percentTemplate = NumberFormat::createPercentInstance(fLocale, status);
            NumberFormat *integerTemplate = createIntegerFormat(fLocale, status);
 
            result += COMMA;
            result += g_umsg_number;
            if (formatAlias != *numberTemplate) {
                result += COMMA;
                if (formatAlias == *currencyTemplate) {
                    result += g_umsg_currency;
                } 
                else if (formatAlias == *percentTemplate) {
                    result += g_umsg_percent;
                } 
                else if (formatAlias == *integerTemplate) {
                    result += g_umsg_integer;
                } 
                else {
                    UnicodeString buffer;
                    result += ((DecimalFormat*)fFormats[i])->toPattern(buffer);
                }
            }
            
            delete numberTemplate;
            delete currencyTemplate;
            delete percentTemplate;
            delete integerTemplate;
        } 
        else if (fFormats[i]->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
            DateFormat& formatAlias = *(DateFormat*)fFormats[i];
            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);
            
            
            result += COMMA;
            if (formatAlias == *defaultDateTemplate) {
                result += g_umsg_date;
            } 
            else if (formatAlias == *shortDateTemplate) {
                result += g_umsg_date;
                result += COMMA;
                result += g_umsg_short;
            } 
            else if (formatAlias == *defaultDateTemplate) {
                result += g_umsg_date;
                result += COMMA;
                result += g_umsg_medium;
            } 
            else if (formatAlias == *longDateTemplate) {
                result += g_umsg_date;
                result += COMMA;
                result += g_umsg_long;
            } 
            else if (formatAlias == *fullDateTemplate) {
                result += g_umsg_date;
                result += COMMA;
                result += g_umsg_full;
            } 
            else if (formatAlias == *defaultTimeTemplate) {
                result += g_umsg_time;
            } 
            else if (formatAlias == *shortTimeTemplate) {
                result += g_umsg_time;
                result += COMMA;
                result += g_umsg_short;
            } 
            else if (formatAlias == *defaultTimeTemplate) {
                result += g_umsg_time;
                result += COMMA;
                result += g_umsg_medium;
            } 
            else if (formatAlias == *longTimeTemplate) {
                result += g_umsg_time;
                result += COMMA;
                result += g_umsg_long;
            } 
            else if (formatAlias == *fullTimeTemplate) {
                result += g_umsg_time;
                result += COMMA;
                result += g_umsg_full;
            } 
            else {
                UnicodeString buffer;
                result += g_umsg_date;
                result += COMMA;
                result += ((SimpleDateFormat*)fFormats[i])->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 (fFormats[i]->getDynamicClassID() == ChoiceFormat::getStaticClassID()) {
            UnicodeString buffer;
            result += COMMA;
            result += g_umsg_choice;
            result += COMMA;
            result += ((ChoiceFormat*)fFormats[i])->toPattern(buffer);
        } 
        else {
            //result += ", unknown";
        }
        result += RIGHT_CURLY_BRACE;
  }
  copyAndFixQuotes(fPattern, lastOffset, fPattern.length(), result);
  return result;
}
 
// -------------------------------------
// Adopts the new formats array and updates the array count.
// This MessageFormat instance owns the new formats.
 
void
MessageFormat::adoptFormats(Format** newFormats,
                            int32_t cnt)
{
    if(newFormats == NULL || cnt < 0)
        return;
    
    int32_t i;
    // Cleans up first.
    for (i = 0; i < fCount; i++)
        delete fFormats[i];
    fCount = (cnt > kMaxFormat) ? kMaxFormat : cnt;
    for (i = 0; i < fCount; i++)
        fFormats[i] = newFormats[i];
    for (i = kMaxFormat; i < cnt; i++) 
        delete newFormats[i];
}   
// -------------------------------------
// 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 cnt)
{
    if(newFormats == NULL || cnt < 0)
        return;

    int32_t i;
    // Cleans up first.
    for (i = 0; i < fCount; i++) {
        delete fFormats[i];
    }
    fCount = (cnt > kMaxFormat) ? kMaxFormat : cnt;
    for (i = 0; i < fCount; i++) {
        if (newFormats[i] == NULL) {
            fFormats[i] = NULL;
        }
        else{
            fFormats[i] = newFormats[i]->clone();
        }
    }
}   
 
// -------------------------------------
// Adopts the first *variable* formats in the format array.
// This MessageFormat instance owns the new formats.
// Do nothing is the variable is not less than the array count.
 
void
MessageFormat::adoptFormat(int32_t variable, Format *newFormat)
{
    if(variable < 0)
        return;
        
    if (variable < fCount) {
        // Deletes the old formats.
        delete fFormats[variable];
        fFormats[variable] = newFormat;
    }
}

// -------------------------------------
// Sets the first *variable* formats in the format array, this
// MessageFormat instance makes copies of the new formats.
// Do nothing is the variable is not less than the array count.
 
void
MessageFormat::setFormat(int32_t variable, const Format& newFormat)
{
    if (variable < fCount) {
        delete fFormats[variable];
        if (&(newFormat) == NULL) {
            fFormats[variable] = NULL;
        }
        else{
            fFormats[variable] = newFormat.clone();
        }
    }
}
 
// -------------------------------------
// Gets the format array.
 
const Format**
MessageFormat::getFormats(int32_t& cnt) const
{
    cnt = fCount;
    return (const Format**)fFormats;
}
 
// -------------------------------------
// 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& result, 
                      FieldPosition& ignore, 
                      UErrorCode& success) const
{
    if (U_FAILURE(success)) 
        return result;
    
    return format(source, cnt, result, ignore, 0, success);
}
 
// -------------------------------------
// Internally creates a MessageFormat instance based on the
// pattern and formats the arguments Formattable array and 
// copy into the result buffer.
 
UnicodeString&
MessageFormat::format(  const UnicodeString& pattern,
                        const Formattable* arguments,
                        int32_t cnt,
                        UnicodeString& result, 
                        UErrorCode& success)
{
    // {sfb} why does this use a local when so many other places use a static?
    MessageFormat *temp = new MessageFormat(pattern, success);
    if (U_FAILURE(success)) 
        return result;
    FieldPosition ignore(0);
    temp->format(arguments, cnt, result, ignore, success);
    delete temp;
    return result;
}
 
// -------------------------------------
// Formats the source Formattable object and copy into the 
// result buffer.  The Formattable object must be an array
// of Formattable instances, returns error otherwise.
 
UnicodeString&
MessageFormat::format(const Formattable& source, 
                      UnicodeString& result, 
                      FieldPosition& ignore, 
                      UErrorCode& success) const
{
    int32_t cnt;

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

UnicodeString&
MessageFormat::format(const Formattable* arguments, 
                      int32_t cnt, 
                      UnicodeString& result, 
                      FieldPosition& status, 
                      int32_t recursionProtection,
                      UErrorCode& success) const 
{
    if(/*arguments == NULL ||*/ cnt < 0) {
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    
    UnicodeString buffer;
    
    int32_t lastOffset = 0;
    for (int32_t i = 0; i <= fMaxOffset;++i) {
        // Cleans up the temp buffer for each formattable arguments.
        buffer.remove();
        // Append the prefix of current format element.
        fPattern.extract(lastOffset, fOffsets[i] - lastOffset, buffer);
        result += buffer;
        lastOffset = fOffsets[i];
        int32_t argumentNumber = fArgumentNumbers[i];
        // Checks the scope of the argument number.
        if (argumentNumber >= cnt) {
            /*success = U_ILLEGAL_ARGUMENT_ERROR;
            return result;*/
            result += LEFT_CURLY_BRACE;
            UnicodeString temp;
            result += itos(argumentNumber, temp);
            result += RIGHT_CURLY_BRACE;
            continue;
        }

        Formattable obj = arguments[argumentNumber];
        UnicodeString arg;
        UBool tryRecursion = FALSE;
        // Recursively calling the format process only if the current format argument
        // refers to a ChoiceFormat object.
        if (fFormats[i] != NULL) {
            fFormats[i]->format(obj, arg, success);
            tryRecursion = (fFormats[i]->getDynamicClassID() == ChoiceFormat::getStaticClassID());
        }
        // If the obj data type if a number, use a NumberFormat instance.
        else if ((obj.getType() == Formattable::kDouble) ||
                 (obj.getType() == Formattable::kLong)) {
            NumberFormat *numTemplate = NULL;
            numTemplate = NumberFormat::createInstance(fLocale, success);
            if (U_FAILURE(success)) { 
                delete numTemplate; 
                return result; 
            }
            numTemplate->format((obj.getType() == Formattable::kDouble) ? obj.getDouble() : obj.getLong(), arg);
            delete numTemplate;
            if (U_FAILURE(success)) 
                return result;
        }
        // If the obj data type is a Date instance, use a DateFormat instance.
        else if (obj.getType() == Formattable::kDate) {
            DateFormat *dateTemplate = NULL;
            dateTemplate = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale);
            dateTemplate->format(obj.getDate(), arg);
            delete dateTemplate;
        }
        else if (obj.getType() == Formattable::kString) {
            obj.getString(arg);
        }
        else {
#ifdef LIUDEBUG  
            cerr << "Unknown object of type:" << obj.getType() << endl;
#endif
            success = U_ILLEGAL_ARGUMENT_ERROR;
            return result;
        }
        // Needs to reprocess the ChoiceFormat option by using the MessageFormat
        // pattern application.
        if (tryRecursion && arg.indexOf(LEFT_CURLY_BRACE) >= 0) {
            MessageFormat *temp = NULL;
            temp = new MessageFormat(arg, fLocale, success);
            if (U_FAILURE(success)) 
                return result;
            temp->format(arguments, cnt, result, status, recursionProtection, success);
            if (U_FAILURE(success)) { 
                delete temp; 
                return result; 
            }
            delete temp;
        }
        else {
            result += arg;
        }
    }
    buffer.remove();
    // Appends the rest of the pattern characters after the real last offset.
    fPattern.extract(lastOffset, fPattern.length(), buffer);
    result += buffer;
    return result;
}


// -------------------------------------
// 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& status,
                     int32_t& count) const
{
    Formattable *resultArray = new Formattable[(size_t)kMaxFormat];
    int32_t patternOffset = 0;
    int32_t sourceOffset = status.getIndex();
    ParsePosition tempStatus(0);
    count = 0; // {sfb} reset to zero
    for (int32_t i = 0; i <= fMaxOffset; ++i) {
        // match up to format
        int32_t len = fOffsets[i] - patternOffset;
        if (len == 0 || 
            fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
            sourceOffset += len;
            patternOffset += len;
        } 
        else {
            status.setErrorIndex(sourceOffset);
            delete [] resultArray;
            count = 0;
            return NULL; // leave index as is to signal error
        }
        
        // now use format
        if (fFormats[i] == 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 != fMaxOffset) ? fOffsets[i+1] : 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) {
                status.setErrorIndex(sourceOffset);
                delete [] resultArray;
                count = 0;
                return NULL; // leave index as is to signal error
            } 
            else {
                UnicodeString buffer;
                source.extract(sourceOffset,next - sourceOffset, buffer);
                UnicodeString strValue = buffer;
                UnicodeString temp(LEFT_CURLY_BRACE);
                // {sfb} check this later
                UnicodeString temp1;
                temp += itos(fArgumentNumbers[i], temp1);
                temp += RIGHT_CURLY_BRACE;
                if (strValue != temp) {
                    source.extract(sourceOffset,next - sourceOffset, buffer);
                    resultArray[fArgumentNumbers[i]].setString(buffer);
                    // {sfb} not sure about this
                    if ((fArgumentNumbers[i] + 1) > count) {
                        count = (fArgumentNumbers[i] + 1);
                    }
                }
                sourceOffset = next;
            }
        } 
        else {
            tempStatus.setIndex(sourceOffset);
            fFormats[i]->parseObject(source, resultArray[fArgumentNumbers[i]], tempStatus);
            if (tempStatus.getIndex() == sourceOffset) {
                status.setErrorIndex(sourceOffset);
                delete [] resultArray;
                count = 0;
                return NULL; // leave index as is to signal error
            }
            
            if ((fArgumentNumbers[i] + 1) > count)
                count = (fArgumentNumbers[i] + 1);
            
            sourceOffset = tempStatus.getIndex(); // update
        }
    }
    int32_t len = fPattern.length() - patternOffset;
    if (len == 0 || 
        fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
        status.setIndex(sourceOffset + len);
    } 
    else {
        status.setErrorIndex(sourceOffset);
        delete [] resultArray;
        count = 0;
        return NULL; // leave index as is to signal error
    }
    
    return resultArray;
}
 
// -------------------------------------
// 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;
        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);
}
  
// -------------------------------------
// NumberFormat cache management

/*
NumberFormat* 
MessageFormat::getNumberFormat(UErrorCode &status)
{
    NumberFormat *theFormat = 0;

    if (fgNumberFormat != 0) // if there's something in the cache
    {
        Mutex lock;

        if (fgNumberFormat != 0) // Someone might have grabbed it.
        {
            theFormat = fgNumberFormat;
            fgNumberFormat = 0; // We have exclusive right to this formatter.
        }
    }

    if(theFormat == 0) // If we weren't able to pull it out of the cache, then we have to create it.
    {
        theFormat = NumberFormat::createInstance(Locale::US, status);
        if(U_FAILURE(status))
            return 0;
        theFormat->setParseIntegerOnly(TRUE);
    }

    return theFormat;
}

void          
MessageFormat::releaseNumberFormat(NumberFormat *adopt)
{
    if(fgNumberFormat == 0) // If the cache is empty we must add it back.
    {
        Mutex lock;

        if(fgNumberFormat == 0)
        {
            fgNumberFormat = adopt;
            adopt = 0;
        }
    }

    delete adopt;
}
*/

/**
 * Converts a string to an integer value using a default NumberFormat object
 * which is static (shared by all MessageFormat instances).  This replaces
 * a call to wtoi().
 */
int32_t
MessageFormat::stoi(const UnicodeString& string)
{
    /*
    NumberFormat *myFormat = getNumberFormat(status);

    if(U_FAILURE(status))
        return -1; // OK?

    Formattable result;
    // Uses the global number formatter to parse the string.
    // Note: We assume here that parse() is thread-safe.
    myFormat->parse(string, result, status);
    releaseNumberFormat(myFormat);

    int32_t value = 0;
    if (U_SUCCESS(status) && result.getType() == Formattable::kLong)
        value = result.getLong();


    return value;
    */
    
    /* this ignores any white spaces between '{' and digit char
     * so now we can have {  0, date} {0 , date }
     */
    for(int i=0;i<string.length();i++){
        UChar32 ch = string.char32At(i);
        if(u_isdigit(ch)){
            return u_charDigitValue(ch);
        }else if(!u_isspace(ch)){
            break;
        }

    }
    return -1;
}

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

/**
 * Converts an integer value to a string using a default NumberFormat object
 * which is static (shared by all MessageFormat instances).  This replaces
 * a call to wtoi().
 */
UnicodeString&
MessageFormat::itos(int32_t i,
                    UnicodeString& string)
{
    /*
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *myFormat = getNumberFormat(status);

    if(U_FAILURE(status)) {
        // "<ERROR>" 
        static const UChar ERROR[] = {0x3C, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3E, 0};

        return string = ERROR; // TODO: maybe toPattern should take an errorcode.
    }

    UnicodeString &retval = myFormat->format(i, string);

    releaseNumberFormat(myFormat);
    return retval;
    */
    UChar temp[10] = { '\0' };
    uprv_itou(temp,i,16,0);
    string.append(temp);
    return string;
}

// -------------------------------------
// Checks which format instance we are really using based on the segments.
 
int32_t
MessageFormat::makeFormat(/*int32_t position, */
                          int32_t offsetNumber, 
                          UnicodeString* segments,
                          UParseError& parseError,
                          UErrorCode& success)
{
    if(U_FAILURE(success))
        return -1;

    // get the number
    int32_t argumentNumber = stoi(segments[1]); // always unlocalized!
    int32_t oldMaxOffset = fMaxOffset;
    if (argumentNumber < 0 || argumentNumber > 9) {
        success = U_INVALID_FORMAT_ERROR;
        return argumentNumber;
    }
    fMaxOffset = offsetNumber;
    fOffsets[offsetNumber] = segments[0].length();
    fArgumentNumbers[offsetNumber] = argumentNumber;
    int test = 0;
    // now get the format
    Format *newFormat = NULL;
    switch (findKeyword(segments[2], g_umsgTypeList)) {
    case 0:
        fFormatTypeList[argumentNumber] = Formattable::kString;
        break;
    case 1: case 2:// number
        test=findKeyword(segments[3], g_umsgModifierList);
        fFormatTypeList[argumentNumber] = Formattable::kDouble;

        switch (test) {
        case 0: // default;
            newFormat = NumberFormat::createInstance(fLocale, success);
            break;
        case 1: case 2:// currency
            newFormat = NumberFormat::createCurrencyInstance(fLocale, success);
            break;
        case 3: case 4:// percent
            newFormat = NumberFormat::createPercentInstance(fLocale, success);
            break;
        case 5: case 6:// integer
            fFormatTypeList[argumentNumber] = Formattable::kLong;
            newFormat = createIntegerFormat(fLocale, success);
            break;
        default: // pattern
            newFormat = NumberFormat::createInstance(fLocale, success);
            if(U_FAILURE(success)) {
                newFormat = NULL;
                return argumentNumber;
            }
            if(newFormat->getDynamicClassID() == DecimalFormat::getStaticClassID()){
                ((DecimalFormat*)newFormat)->applyPattern(segments[3],parseError,success);
            }
            if(U_FAILURE(success)) {
                fMaxOffset = oldMaxOffset;
                return argumentNumber;
            }
            break;
        }
        break;

    case 3: case 4: // date
        fFormatTypeList[argumentNumber] = Formattable::kDate;

        switch (findKeyword(segments[3], g_umsgDateModifierList)) {
        case 0: // default
            newFormat = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
            break;
        case 1: case 2: // short
            newFormat = DateFormat::createDateInstance(DateFormat::kShort, fLocale);
            break;
        case 3: case 4: // medium
            newFormat = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
            break;
        case 5: case 6: // long
            newFormat = DateFormat::createDateInstance(DateFormat::kLong, fLocale);
            break;
        case 7: case 8: // full
            newFormat = DateFormat::createDateInstance(DateFormat::kFull, fLocale);
            break;
        default:
            newFormat = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
            if(newFormat && newFormat->getDynamicClassID() == SimpleDateFormat::getStaticClassID()){
                    ((SimpleDateFormat*)newFormat)->applyPattern(segments[3]);
            }
            break;
        }
        if (!newFormat) {
            /* TODO: get the real error from createDateInstance */
            success = U_MEMORY_ALLOCATION_ERROR;
        }
        break;
    case 5: case 6:// time

        fFormatTypeList[argumentNumber]= Formattable::kDate;
        
        switch (findKeyword(segments[3], g_umsgDateModifierList)) {
        case 0: // default
            newFormat = DateFormat::createTimeInstance(DateFormat::kDefault, fLocale);
            break;
        case 1: case 2: // short
            newFormat = DateFormat::createTimeInstance(DateFormat::kShort, fLocale);
            break;
        case 3: case 4: // medium
            newFormat = DateFormat::createTimeInstance(DateFormat::kDefault, fLocale);
            break;
        case 5: case 6: // long
            newFormat = DateFormat::createTimeInstance(DateFormat::kLong, fLocale);
            break;
        case 7: case 8: // full
            newFormat = DateFormat::createTimeInstance(DateFormat::kFull, fLocale);
            break;
        default:
            newFormat = DateFormat::createTimeInstance(DateFormat::kDefault, fLocale);
            if(newFormat && newFormat->getDynamicClassID() == SimpleDateFormat::getStaticClassID()){
                    ((SimpleDateFormat*)newFormat)->applyPattern(segments[3]);
            }
            break;
        }
        if (!newFormat) {
            /* TODO: get the real error from createTimeInstance */
            success = U_MEMORY_ALLOCATION_ERROR;
        }
        break;
    case 7: case 8:// choice
        fFormatTypeList[argumentNumber] = Formattable::kDouble;

        newFormat = new ChoiceFormat(segments[3], parseError, success);
        if(U_FAILURE(success)) {
            fMaxOffset = oldMaxOffset;
            return argumentNumber;
        }
        break;
    default:
        fMaxOffset = oldMaxOffset;
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return argumentNumber;
    }

    if(newFormat != NULL) {
        delete fFormats[offsetNumber];
        fFormats[offsetNumber] = newFormat;
    }
    segments[1].remove();   // throw away other segments
    segments[2].remove();
    segments[3].remove();

    return argumentNumber;
}
 
// -------------------------------------
// 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;

    UnicodeString buffer = s;
    // Trims the space characters and turns all characters
    // in s to lower case.
    buffer.trim().toLower();
    for (int32_t i = 0; i < g_umsgListLength; ++i) {
        if (list[i] && !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& target)
{
    UBool gotLB = FALSE;
    
    for (int32_t i = start; i < end; ++i) {
        UChar ch = source[i];
        if (ch == LEFT_CURLY_BRACE) {
            target += SINGLE_QUOTE;
            target += LEFT_CURLY_BRACE;
            target += SINGLE_QUOTE;
            gotLB = TRUE;
        } 
        else if (ch == RIGHT_CURLY_BRACE) {
            if(gotLB) {
                target += RIGHT_CURLY_BRACE;
                gotLB = FALSE;
            }
            else {
                // orig code.
                target += SINGLE_QUOTE;
                target += RIGHT_CURLY_BRACE;
                target += SINGLE_QUOTE;
            }
        } 
        else if (ch == SINGLE_QUOTE) {
            target += SINGLE_QUOTE;
            target += SINGLE_QUOTE;
        } 
        else {
            target += 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->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
        DecimalFormat *temp2 = (DecimalFormat*) temp;
        temp2->setMaximumFractionDigits(0);
        temp2->setDecimalSeparatorAlwaysShown(FALSE);
        temp2->setParseIntegerOnly(TRUE);
    }

    return temp;
}

U_NAMESPACE_END

//eof
