/*
*******************************************************************************
* 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 "mutex.h"
 
// *****************************************************************************
// class MessageFormat
// *****************************************************************************
 
// -------------------------------------
char MessageFormat::fgClassID = 0; // Value is irrelevant
 
// This global NumberFormat instance is shared by all MessageFormat to 
// convert a number to(format)/from(parse) a string.
NumberFormat* MessageFormat::fgNumberFormat = 0;

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

MessageFormat::MessageFormat(const UnicodeString& pattern,
                             UErrorCode& success)
: fOffsets(NULL),
  fArgumentNumbers(NULL),
  fLocale(Locale::getDefault()),  // Uses the default locale
  fCount(0)
{
    fCount = kMaxFormat;
    fOffsets = new int32_t[fCount];
    fArgumentNumbers = new 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)
: fOffsets(NULL),
  fArgumentNumbers(NULL),
  fLocale(newLocale),  // Uses the default locale
  fCount(0)
{
    fCount = kMaxFormat;
    fOffsets = new int32_t[fCount];
    fArgumentNumbers = new 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()
{
    for (int32_t i = 0; i < fCount; i++)
        delete fFormats[i];
    delete [] fOffsets;
    delete [] fArgumentNumbers;
    fCount = 0;
}

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

MessageFormat::MessageFormat(const MessageFormat& that)
    : Format(that),
      fOffsets(NULL),
      fCount(that.fCount),
      fLocale(that.fLocale),
      fMaxOffset(that.fMaxOffset),
      fArgumentNumbers(NULL),
      fPattern(that.fPattern)
{
    fOffsets = new int32_t[fCount];
    fArgumentNumbers = new int32_t[fCount];
    // 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;
        }
        delete [] fOffsets; fOffsets = NULL;
        delete [] fArgumentNumbers; fArgumentNumbers = NULL;
        fPattern = that.fPattern;
        fLocale = that.fLocale;
        fCount = that.fCount;
        fMaxOffset = that.fMaxOffset;
        fOffsets = new int32_t[fCount];
        fArgumentNumbers = new 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;
}
 
// -------------------------------------
// 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 == 0x0027 /*'\''*/) {
                if (i + 1 < newPattern.length()
                    && newPattern[i+1] == 0x0027 /*'\''*/) {
                    segments[part] += ch;  // handle doubles
                    ++i;
                } else {
                    inQuote = !inQuote;
                }
            } else if (ch == 0x007B /*'{'*/ && !inQuote) {
                part = 1;
            } else {
                segments[part] += ch;
            }
        } else  if (inQuote) {              // just copy quotes in parts
            segments[part] += ch;
            if (ch == 0x0027 /*'\''*/) {
                inQuote = FALSE;
            }
        } else {
            switch (ch) {
            case 0x002C /*','*/:
                if (part < 3)
                    part += 1;
                else
                    segments[part] += ch;
                break;
            case 0x007B /*'{'*/:
                ++braceStack;
                segments[part] += ch;
                break;
            case 0x007D /*'}'*/:
                if (braceStack == 0) {
                    part = 0;
                    makeFormat(i, formatNumber, segments, success);
                    if(U_FAILURE(success))
                        return;
                    formatNumber++;
                } else {
                    --braceStack;
                    segments[part] += ch;
                }
                break;
            case 0x0027 /*'\''*/:
                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];
}
 
// -------------------------------------
// 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 += (UChar)0x007B /*'{'*/;
    // {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);
      
      if (formatAlias == *numberTemplate) {
    result += ",number";
      } 
      else if (formatAlias == *currencyTemplate) {
    result += ",number,currency";
      } 
      else if (formatAlias == *percentTemplate) {
    result += ",number,percent";
      } 
      else if (formatAlias == *integerTemplate) {
    result += ",number,integer";
      } 
      else {
    UnicodeString buffer;
    result += ",number,";
    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);
      
      
      if (formatAlias == *defaultDateTemplate) {
    result += ",date";
      } 
      else if (formatAlias == *shortDateTemplate) {
    result += ",date,short";
      } 
      else if (formatAlias == *defaultDateTemplate) {
    result += ",date,medium";
      } 
      else if (formatAlias == *longDateTemplate) {
    result += ",date,long";
      } 
      else if (formatAlias == *fullDateTemplate) {
    result += ",date,full";
      } 
      else if (formatAlias == *defaultTimeTemplate) {
    result += ",time";
      } 
      else if (formatAlias == *shortTimeTemplate) {
    result += ",time,short";
      } 
      else if (formatAlias == *defaultTimeTemplate) {
    result += ",time,medium";
      } 
      else if (formatAlias == *longTimeTemplate) {
    result += ",time,long";
      } 
      else if (formatAlias == *fullTimeTemplate) {
    result += ",time,full";
      } 
      else {
    UnicodeString buffer;
    result += ",date,";
    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 += ",choice,";
      result += ((ChoiceFormat*)fFormats[i])->toPattern(buffer);
    } 
    else {
      //result += ", unknown";
    }
    result += (UChar)0x007D /*'}'*/;
  }
  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 += "{";
            UnicodeString temp;
            result += itos(argumentNumber, temp);
            result += "}";
            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("{") >= 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;
}

// MessageFormat Type List  Number, Date, Time or Choice
const UnicodeString MessageFormat::fgTypeList[] = {
    UnicodeString(), UnicodeString(), UNICODE_STRING("number", 6), UnicodeString(),
    UNICODE_STRING("date", 4), UnicodeString(), UNICODE_STRING("time", 4), UnicodeString(),
    UNICODE_STRING("choice", 6)
};
 
// NumberFormat modifier list, default, currency, percent or integer
const UnicodeString MessageFormat::fgModifierList[] = {
    UnicodeString(), UnicodeString(), UNICODE_STRING("currency", 8), UnicodeString(),
    UNICODE_STRING("percent", 7), UnicodeString(), UNICODE_STRING("integer", 7), UnicodeString(),
    UnicodeString()
};
 
// DateFormat modifier list, default, short, medium, long or full
const UnicodeString MessageFormat::fgDateModifierList[] = {
    UnicodeString(), UnicodeString(), UNICODE_STRING("short", 5), UnicodeString(),
    UNICODE_STRING("medium", 6), UnicodeString(), UNICODE_STRING("long", 4), UnicodeString(),
    UNICODE_STRING("full", 4)
};
 
const int32_t MessageFormat::fgListLength= 9;

// -------------------------------------
// 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[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("{");
                // {sfb} check this later
    UnicodeString temp1;
    temp += itos(fArgumentNumbers[i], temp1);
    temp += "}";
    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,
                    UErrorCode& status)
{
    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;
}

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

/**
 * 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))
        return (string = "<ERROR>"); // _REVISIT_ maybe toPattern should take an errorcode.

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

    releaseNumberFormat(myFormat);

    return retval;
}

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

    // get the number
    int32_t argumentNumber;
    int32_t oldMaxOffset = fMaxOffset;
    argumentNumber = stoi(segments[1], success); // always unlocalized!
    if (argumentNumber < 0 || argumentNumber > 9) {
        success = U_INVALID_FORMAT_ERROR;
        return;
    }
    fMaxOffset = offsetNumber;
    fOffsets[offsetNumber] = segments[0].length();
    fArgumentNumbers[offsetNumber] = argumentNumber;

    // now get the format
    Format *newFormat = NULL;
    switch (findKeyword(segments[2], fgTypeList)) {
    case 0:
        break;
    case 1: case 2:// number
        switch (findKeyword(segments[3], fgModifierList)) {
        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
            newFormat = createIntegerFormat(fLocale, success);
            break;
        default: // pattern
            newFormat = NumberFormat::createInstance(fLocale, success);
            if(U_FAILURE(success)) {
                newFormat = NULL;
                return;
            }
            if(newFormat->getDynamicClassID() == DecimalFormat::getStaticClassID())
                ((DecimalFormat*)newFormat)->applyPattern(segments[3], success);
            if(U_FAILURE(success)) {
                fMaxOffset = oldMaxOffset;
                success = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
            break;
        }
        break;

    case 3: case 4: // date
        switch (findKeyword(segments[3], fgDateModifierList)) {
        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->getDynamicClassID() == SimpleDateFormat::getStaticClassID())
                    ((SimpleDateFormat*)newFormat)->applyPattern(segments[3]);
                if(U_FAILURE(success)) {
                    fMaxOffset = oldMaxOffset;
                    success = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
            break;
        }
        break;
    case 5: case 6:// time
        switch (findKeyword(segments[3], fgDateModifierList)) {
        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->getDynamicClassID() == SimpleDateFormat::getStaticClassID())
                    ((SimpleDateFormat*)newFormat)->applyPattern(segments[3]);
                if(U_FAILURE(success)) {
                    fMaxOffset = oldMaxOffset;
                    success = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
            break;
        }
        break;
    case 7: case 8:// choice
            newFormat = new ChoiceFormat(segments[3], success);
        if(U_FAILURE(success)) {
            fMaxOffset = oldMaxOffset;
            success = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
        break;
    default:
        fMaxOffset = oldMaxOffset;
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

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

}
 
// -------------------------------------
// Finds the string, s, in the string array, list. 
int32_t MessageFormat::findKeyword(const UnicodeString& s, 
                           const UnicodeString* list)
{
  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 < fgListLength; ++i) {
    if (buffer == 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 (UTextOffset i = start; i < end; ++i) {
    UChar ch = source[i];
    if (ch == 0x007B /*'{'*/) {
      target += "'{'";
      gotLB = TRUE;
    } 
    else if (ch == 0x007D /*'}'*/) {
      if(gotLB) {
    target += "}";
    gotLB = FALSE;
      }
      else
    // orig code.
    target += "'}'";
    } 
    else if (ch == 0x0027 /*'\''*/) {
      target += "''";
    } 
    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;
}

//eof
