/*
*******************************************************************************
* 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)
: fLocale(Locale::getDefault()),  // Uses the default locale
  fOffsets(NULL),
  fCount(0),
  fArgumentNumbers(NULL)
{
    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)
: fLocale(newLocale),  // Uses the default locale
  fOffsets(NULL),
  fCount(0),
  fArgumentNumbers(NULL)
{
    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),
  fLocale(that.fLocale),
  fPattern(that.fPattern),
  fOffsets(new int32_t[that.fCount]),
  fCount(that.fCount),
  fArgumentNumbers(new int32_t[that.fCount]),
  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;
        }
        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
