/*
*******************************************************************************
*   Copyright (C) 1996-2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
* Modification History:
*
*   Date        Name        Description
*   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
*******************************************************************************
*/

#include "unicode/unum.h"

#include "unicode/uloc.h"
#include "unicode/numfmt.h"
#include "unicode/decimfmt.h"
#include "unicode/rbnf.h"
#include "unicode/ustring.h"
#include "unicode/fmtable.h"
#include "unicode/dcfmtsym.h"
#include "cpputils.h"
U_NAMESPACE_USE
/*
U_CAPI UNumberFormat*
unum_open(    UNumberFormatStyle    style,
        const   char*        locale,
        UErrorCode*        status)
{
  if(U_FAILURE(*status))
    return 0;
  UNumberFormat *retVal = 0;
  
  switch(style) {
  case UNUM_DECIMAL:
    if(locale == 0)
      retVal = (UNumberFormat*)NumberFormat::createInstance(*status);
    else
      retVal = (UNumberFormat*)NumberFormat::createInstance(Locale(locale),
                                *status);
    break;

  case UNUM_CURRENCY:
    if(locale == 0)
      retVal = (UNumberFormat*)NumberFormat::createCurrencyInstance(*status);
    else
      retVal = (UNumberFormat*)NumberFormat::createCurrencyInstance(Locale(locale),
                                    *status);
    break;

  case UNUM_PERCENT:
    if(locale == 0)
      retVal = (UNumberFormat*)NumberFormat::createPercentInstance(*status);
    else
      retVal = (UNumberFormat*)NumberFormat::createPercentInstance(Locale(locale),
                                *status);
    break;

  case UNUM_SPELLOUT:
    // Todo: TBD: Add spellout support
    //retVal = (UNumberFormat*)new NumberSpelloutFormat();
    //break;
    *status = U_UNSUPPORTED_ERROR;
    return 0;

  default:
    *status = U_UNSUPPORTED_ERROR;
    return 0;
  }

  if(retVal == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  return retVal;
}

U_CAPI UNumberFormat*
unum_openPattern(    const    UChar*            pattern,
            int32_t            patternLength,
            const    char*        locale,
            UErrorCode*        status)
{
    UParseError parseError;
    return unum_openPatternWithError( pattern,patternLength,locale,&parseError,status);
}*/


U_CAPI UNumberFormat* U_EXPORT2
unum_open(  UNumberFormatStyle    style,  
            const    UChar*    pattern,
            int32_t            patternLength,
            const    char*     locale,
            UParseError*       parseErr,
            UErrorCode*        status)
{

  if(U_FAILURE(*status))
  { 
      return 0;
  }
  if(style!=UNUM_IGNORE){
       UNumberFormat *retVal = 0;
  
      switch(style) {
      case UNUM_DECIMAL:
        if(locale == 0)
          retVal = (UNumberFormat*)NumberFormat::createInstance(*status);
        else
          retVal = (UNumberFormat*)NumberFormat::createInstance(Locale(locale),
                                    *status);
        break;

      case UNUM_CURRENCY:
        if(locale == 0)
          retVal = (UNumberFormat*)NumberFormat::createCurrencyInstance(*status);
        else
          retVal = (UNumberFormat*)NumberFormat::createCurrencyInstance(Locale(locale),
                                        *status);
        break;

      case UNUM_PERCENT:
        if(locale == 0)
          retVal = (UNumberFormat*)NumberFormat::createPercentInstance(*status);
        else
          retVal = (UNumberFormat*)NumberFormat::createPercentInstance(Locale(locale),
                                    *status);
        break;

      case UNUM_SCIENTIFIC:
        if(locale == 0)
          retVal = (UNumberFormat*)NumberFormat::createScientificInstance(*status);
        else
          retVal = (UNumberFormat*)NumberFormat::createScientificInstance(Locale(locale),
                                    *status);
        break;

      case UNUM_SPELLOUT:
#if U_HAVE_RBNF
        return (UNumberFormat*)new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale(locale), *status);
#else
        // fall through
#endif
      default:
        *status = U_UNSUPPORTED_ERROR;
        return 0;
      }

      if(retVal == 0) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
      }

      return retVal;
  }else{
      /* we don't support RBNF patterns yet */
      UParseError tErr;
      int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
      const UnicodeString pat((UChar*)pattern, len, len);
      DecimalFormatSymbols *syms = 0;
      
      if(parseErr==NULL){
          parseErr = &tErr;
      }
      
      if(locale == 0)
        syms = new DecimalFormatSymbols(*status);
      else
        syms = new DecimalFormatSymbols(Locale(locale),
                        *status);
  
      if(syms == 0) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
      }

      DecimalFormat *fmt = 0;
      fmt = new DecimalFormat(pat, syms, *parseErr, *status);
      if(fmt == 0) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        delete syms;
        return 0;
      }

      return (UNumberFormat*) fmt;
  }
}

U_CAPI void U_EXPORT2
unum_close(UNumberFormat* fmt)
{
 
  delete (NumberFormat*) fmt;
}

U_CAPI UNumberFormat* U_EXPORT2
unum_clone(const UNumberFormat *fmt,
       UErrorCode *status)
{
 
  if(U_FAILURE(*status)) return 0;

  Format *res = ((DecimalFormat*)fmt)->clone();
  
  if(res == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  return (UNumberFormat*) res;
}

U_CAPI int32_t U_EXPORT2
unum_format(    const    UNumberFormat*    fmt,
        int32_t            number,
        UChar*            result,
        int32_t            resultLength,
        UFieldPosition    *pos,
        UErrorCode*        status)
{
 
  if(U_FAILURE(*status)) return -1;

  UnicodeString res(result, 0, resultLength);
  FieldPosition fp;
  
  if(pos != 0)
    fp.setField(pos->field);
  
  ((NumberFormat*)fmt)->format(number, res, fp);
  
  if(pos != 0) {
    pos->beginIndex = fp.getBeginIndex();
    pos->endIndex = fp.getEndIndex();
  }
  
  return res.extract(result, resultLength, *status);
}

U_CAPI int32_t U_EXPORT2
unum_formatDouble(    const    UNumberFormat*  fmt,
            double          number,
            UChar*          result,
            int32_t         resultLength,
            UFieldPosition  *pos, /* 0 if ignore */
            UErrorCode*     status)
{
 
  if(U_FAILURE(*status)) return -1;

  UnicodeString res(result, 0, resultLength);
  FieldPosition fp;
  
  if(pos != 0)
    fp.setField(pos->field);
  
  ((NumberFormat*)fmt)->format(number, res, fp);
  
  if(pos != 0) {
    pos->beginIndex = fp.getBeginIndex();
    pos->endIndex = fp.getEndIndex();
  }
  
  return res.extract(result, resultLength, *status);
}

U_CAPI int32_t U_EXPORT2
unum_parse(    const   UNumberFormat*  fmt,
        const   UChar*          text,
        int32_t         textLength,
        int32_t         *parsePos /* 0 = start */,
        UErrorCode      *status)
{
 
  if(U_FAILURE(*status)) return 0;

  int32_t len = (textLength == -1 ? u_strlen(text) : textLength);
  const UnicodeString src((UChar*)text, len, len);
  ParsePosition pp;
  Formattable res;

  if(parsePos != 0)
    pp.setIndex(*parsePos);

  ((NumberFormat*)fmt)->parse(src, res, pp);

  if(parsePos != 0) {
    if(pp.getErrorIndex() == -1)
      *parsePos = pp.getIndex();
    else {
      *parsePos = pp.getErrorIndex();
      *status = U_PARSE_ERROR;
    }
  }

  /* return the actual type of the result, cast to a long */
  return (res.getType() == Formattable::kLong) 
    ? res.getLong() 
    : (int32_t) res.getDouble();
}

U_CAPI double U_EXPORT2
unum_parseDouble(    const   UNumberFormat*  fmt,
            const   UChar*          text,
            int32_t         textLength,
            int32_t         *parsePos /* 0 = start */,
            UErrorCode      *status)
{
 
  if(U_FAILURE(*status))
      return 0;

  int32_t len = (textLength < 0 ? u_strlen(text) : textLength);
  const UnicodeString src((UChar*)text, len, len);
  ParsePosition pp;
  Formattable res;

  if(parsePos != 0)
    pp.setIndex(*parsePos);

  ((NumberFormat*)fmt)->parse(src, res, pp);

  if(parsePos != 0) {
    if(pp.getErrorIndex() == -1)
      *parsePos = pp.getIndex();
    else {
      *parsePos = pp.getErrorIndex();
      *status = U_PARSE_ERROR;
    }
  }
  
  /* return the actual type of the result, cast to a double */
  return (res.getType() == Formattable::kDouble) 
    ? res.getDouble() 
    : (double) res.getLong();
}

U_CAPI const char* U_EXPORT2
unum_getAvailable(int32_t index)
{
 
  return uloc_getAvailable(index);
}

U_CAPI int32_t U_EXPORT2
unum_countAvailable()
{
 
  return uloc_countAvailable();
}

U_CAPI int32_t U_EXPORT2
unum_getAttribute(const UNumberFormat*          fmt,
          UNumberFormatAttribute  attr)
{
 
  switch(attr) {
  case UNUM_PARSE_INT_ONLY:
    return ((NumberFormat*)fmt)->isParseIntegerOnly();
    
  case UNUM_GROUPING_USED:
    return ((NumberFormat*)fmt)->isGroupingUsed();
    
  case UNUM_DECIMAL_ALWAYS_SHOWN:
    return ((DecimalFormat*)fmt)->isDecimalSeparatorAlwaysShown();    
    
  case UNUM_MAX_INTEGER_DIGITS:
    return ((NumberFormat*)fmt)->getMaximumIntegerDigits();
    
  case UNUM_MIN_INTEGER_DIGITS:
    return ((NumberFormat*)fmt)->getMinimumIntegerDigits();
    
  case UNUM_INTEGER_DIGITS:
    // TBD: what should this return?
    return ((NumberFormat*)fmt)->getMinimumIntegerDigits();
    
  case UNUM_MAX_FRACTION_DIGITS:
    return ((NumberFormat*)fmt)->getMaximumFractionDigits();
    
  case UNUM_MIN_FRACTION_DIGITS:
    return ((NumberFormat*)fmt)->getMinimumFractionDigits();
    
  case UNUM_FRACTION_DIGITS:
    // TBD: what should this return?
    return ((NumberFormat*)fmt)->getMinimumFractionDigits();

  case UNUM_MULTIPLIER:
    return ((DecimalFormat*)fmt)->getMultiplier();    
    
  case UNUM_GROUPING_SIZE:
    return ((DecimalFormat*)fmt)->getGroupingSize();    

  case UNUM_ROUNDING_MODE:
    return ((DecimalFormat*)fmt)->getRoundingMode();

  case UNUM_FORMAT_WIDTH:
    return ((DecimalFormat*)fmt)->getFormatWidth();

  /** The position at which padding will take place. */
  case UNUM_PADDING_POSITION:
    return ((DecimalFormat*)fmt)->getPadPosition();

  default:
    break;
  }
  return -1;
}

U_CAPI void U_EXPORT2
unum_setAttribute(    UNumberFormat*          fmt,
            UNumberFormatAttribute  attr,
            int32_t                 newValue)
{
 
  switch(attr) {
  case UNUM_PARSE_INT_ONLY:
    ((NumberFormat*)fmt)->setParseIntegerOnly((UBool)newValue);
    break;

  case UNUM_GROUPING_USED:
    ((NumberFormat*)fmt)->setGroupingUsed((UBool)newValue);
    break;

  case UNUM_DECIMAL_ALWAYS_SHOWN:
    ((DecimalFormat*)fmt)->setDecimalSeparatorAlwaysShown((UBool)newValue);
    break;

  case UNUM_MAX_INTEGER_DIGITS:
    ((NumberFormat*)fmt)->setMaximumIntegerDigits(newValue);
    break;

  case UNUM_MIN_INTEGER_DIGITS:
    ((NumberFormat*)fmt)->setMinimumIntegerDigits(newValue);
    break;

  case UNUM_INTEGER_DIGITS:
    ((NumberFormat*)fmt)->setMinimumIntegerDigits(newValue);
    ((NumberFormat*)fmt)->setMaximumIntegerDigits(newValue);
    break;

  case UNUM_MAX_FRACTION_DIGITS:
    ((NumberFormat*)fmt)->setMaximumFractionDigits(newValue);
    break;

  case UNUM_MIN_FRACTION_DIGITS:
    ((NumberFormat*)fmt)->setMinimumFractionDigits(newValue);
    break;

  case UNUM_FRACTION_DIGITS:
    ((NumberFormat*)fmt)->setMinimumFractionDigits(newValue);
    ((NumberFormat*)fmt)->setMaximumFractionDigits(newValue);
    break;

  case UNUM_MULTIPLIER:
    ((DecimalFormat*)fmt)->setMultiplier(newValue);    
    break;

  case UNUM_GROUPING_SIZE:
    ((DecimalFormat*)fmt)->setGroupingSize(newValue);    
    break;

  case UNUM_ROUNDING_MODE:
      ((DecimalFormat*)fmt)->setRoundingMode((DecimalFormat::ERoundingMode)newValue);
    break;

  case UNUM_FORMAT_WIDTH:
    ((DecimalFormat*)fmt)->setFormatWidth(newValue);
    break;

  /** The position at which padding will take place. */
  case UNUM_PADDING_POSITION:
      ((DecimalFormat*)fmt)->setPadPosition((DecimalFormat::EPadPosition)newValue);
    break;

  case UNUM_SECONDARY_GROUPING_SIZE:
      ((DecimalFormat*)fmt)->setSecondaryGroupingSize(newValue);
    break;

  default:
    /* Shouldn't get here anyway */
    break;
  }
}

U_CAPI double U_EXPORT2
unum_getDoubleAttribute(const UNumberFormat*          fmt,
          UNumberFormatAttribute  attr)
{
 
  if (attr == UNUM_ROUNDING_INCREMENT) {
    return ((DecimalFormat*)fmt)->getRoundingIncrement();
  } else {
    return -1.0;
  }
}

U_CAPI void U_EXPORT2
unum_setDoubleAttribute(    UNumberFormat*          fmt,
            UNumberFormatAttribute  attr,
            double                 newValue)
{
 
  if (attr == UNUM_ROUNDING_INCREMENT) {   
    ((DecimalFormat*)fmt)->setRoundingIncrement(newValue);
  }
}

U_CAPI int32_t U_EXPORT2
unum_getTextAttribute(const UNumberFormat*  fmt,
            UNumberFormatTextAttribute      tag,
            UChar*                          result,
            int32_t                         resultLength,
            UErrorCode*                     status)
{
 
  if(U_FAILURE(*status))
      return -1;

  UnicodeString res(result, 0, resultLength);

  switch(tag) {
  case UNUM_POSITIVE_PREFIX:
    ((DecimalFormat*)fmt)->getPositivePrefix(res);
    break;

  case UNUM_POSITIVE_SUFFIX:
    ((DecimalFormat*)fmt)->getPositiveSuffix(res);
    break;

  case UNUM_NEGATIVE_PREFIX:
    ((DecimalFormat*)fmt)->getNegativePrefix(res);
    break;

  case UNUM_NEGATIVE_SUFFIX:
    ((DecimalFormat*)fmt)->getNegativeSuffix(res);
    break;

  case UNUM_PADDING_CHARACTER:
    res = ((DecimalFormat*)fmt)->getPadCharacterString();
    break;

  case UNUM_CURRENCY_CODE:
    res = UnicodeString(((DecimalFormat*)fmt)->getCurrency());
    break;

  default:
    *status = U_UNSUPPORTED_ERROR;
    return -1;
  }

  return res.extract(result, resultLength, *status);
}

U_CAPI void U_EXPORT2
unum_setTextAttribute(    UNumberFormat*                    fmt,
            UNumberFormatTextAttribute      tag,
            const    UChar*                            newValue,
            int32_t                            newValueLength,
            UErrorCode                        *status)
{
 
  if(U_FAILURE(*status)) return;

  int32_t len = (newValueLength == -1 ? u_strlen(newValue) : newValueLength);
  const UnicodeString val((UChar*)newValue, len, len);
  
  switch(tag) {
  case UNUM_POSITIVE_PREFIX:
    ((DecimalFormat*)fmt)->setPositivePrefix(val);
    break;

  case UNUM_POSITIVE_SUFFIX:
    ((DecimalFormat*)fmt)->setPositiveSuffix(val);
    break;

  case UNUM_NEGATIVE_PREFIX:
    ((DecimalFormat*)fmt)->setNegativePrefix(val);
    break;

  case UNUM_NEGATIVE_SUFFIX:
    ((DecimalFormat*)fmt)->setNegativeSuffix(val);
    break;

  case UNUM_PADDING_CHARACTER:
    ((DecimalFormat*)fmt)->setPadCharacter(*newValue);
    break;

  case UNUM_CURRENCY_CODE:
      ((DecimalFormat*)fmt)->setCurrency(newValue);
      break;

  default:
    *status = U_UNSUPPORTED_ERROR;
    break;
  }
}

U_CAPI int32_t U_EXPORT2
unum_toPattern(    const    UNumberFormat*          fmt,
        UBool                  isPatternLocalized,
        UChar*                  result,
        int32_t                 resultLength,
        UErrorCode*             status)
{
 
  if(U_FAILURE(*status)) return -1;

  UnicodeString pat(result, 0, resultLength);

  if(isPatternLocalized)
    ((DecimalFormat*)fmt)->toLocalizedPattern(pat);
  else
    ((DecimalFormat*)fmt)->toPattern(pat);

  return pat.extract(result, resultLength, *status);
}

#ifdef ICU_DECIMALFORMATSYMBOLS_USE_DEPRECATES
U_CAPI void
unum_getSymbols(const UNumberFormat* fmt,
        UNumberFormatSymbols *syms)
{
 
  UnicodeString temp;
  int32_t len;
  const DecimalFormatSymbols *dfs = 
    ((DecimalFormat*)fmt)->getDecimalFormatSymbols();
  
  syms->decimalSeparator     = dfs->getDecimalSeparator();
  syms->groupingSeparator     = dfs->getGroupingSeparator();
  syms->patternSeparator     = dfs->getPatternSeparator();
  syms->percent         = dfs->getPercent();
  syms->zeroDigit         = dfs->getZeroDigit();
  syms->digit             = dfs->getDigit();
  syms->plusSign          = dfs->getPlusSign();
  syms->minusSign         = dfs->getMinusSign();
  
  dfs->getCurrencySymbol(temp);
  len = uprv_min(temp.length(), UNFSYMBOLSMAXSIZE);
  //u_strncpy(syms->currency, temp.getUChars(), len);
  temp.extract(0,len,syms->currency);
  syms->currency[len > 0 ? len : 0] = 0x0000;

  dfs->getInternationalCurrencySymbol(temp);
  len = uprv_min(temp.length(), UNFSYMBOLSMAXSIZE);
  //u_strncpy(syms->intlCurrency, temp.getUChars(), len);
  temp.extract(0,len,syms->intlCurrency);
  syms->intlCurrency[len > 0 ? len : 0] = 0x0000;
  
  syms->monetarySeparator    = dfs->getMonetaryDecimalSeparator();
  syms->exponential         = dfs->getExponentialSymbol();
  syms->perMill         = dfs->getPerMill();
  syms->padEscape       = dfs->getPadEscape();

  dfs->getInfinity(temp);
  len = uprv_min(temp.length(), UNFSYMBOLSMAXSIZE);
  //u_strncpy(syms->infinity, temp.getUChars(), len);
  temp.extract(0,len,syms->infinity);
  syms->infinity[len > 0 ? len : 0] = 0x0000;

  dfs->getNaN(temp);
  len = uprv_min(temp.length(), UNFSYMBOLSMAXSIZE);
  //u_strncpy(syms->naN, temp.getUChars(), len);
  temp.extract(0,len,syms->naN);
  syms->naN[len > 0 ? len : 0] = 0x0000;
}

U_CAPI void
unum_setSymbols(            UNumberFormat*          fmt,
                    const   UNumberFormatSymbols*   symbolsToSet,
                    UErrorCode *status)
{
 
  if(U_FAILURE(*status)) return;

  DecimalFormatSymbols *syms = new DecimalFormatSymbols(*status);
  if(syms == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return;
  }

  syms->setDecimalSeparator(symbolsToSet->decimalSeparator);
  syms->setGroupingSeparator(symbolsToSet->groupingSeparator);
  syms->setPatternSeparator(symbolsToSet->patternSeparator);
  syms->setPercent(symbolsToSet->percent);
  syms->setZeroDigit(symbolsToSet->zeroDigit);
  syms->setDigit(symbolsToSet->digit);
  syms->setPlusSign(symbolsToSet->plusSign);
  syms->setMinusSign(symbolsToSet->minusSign);
  
  syms->setCurrencySymbol(symbolsToSet->currency);
  syms->setInternationalCurrencySymbol(symbolsToSet->intlCurrency);
  
  syms->setMonetaryDecimalSeparator(symbolsToSet->monetarySeparator);
  syms->setExponentialSymbol(symbolsToSet->exponential);
  syms->setPerMill(symbolsToSet->perMill);
  syms->setPadEscape(symbolsToSet->padEscape);

  syms->setInfinity(symbolsToSet->infinity);
  syms->setNaN(symbolsToSet->naN);

  ((DecimalFormat*)fmt)->adoptDecimalFormatSymbols(syms);
}

#endif /* ICU_DECIMALFORMATSYMBOLS_USE_DEPRECATES */


U_CAPI int32_t U_EXPORT2
unum_getSymbol(UNumberFormat *fmt,
               UNumberFormatSymbol symbol,
               UChar *buffer,
               int32_t size,
               UErrorCode *status) {
 
  if(status==NULL || U_FAILURE(*status)) {
    return 0;
  }

  if(fmt==NULL || (uint16_t)symbol>=UNUM_FORMAT_SYMBOL_COUNT) {
    *status=U_ILLEGAL_ARGUMENT_ERROR;
    return 0;
  }

  UnicodeString s=((DecimalFormat *)fmt)->getDecimalFormatSymbols()->getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol);
  return s.extract(buffer, size, *status);
}

U_CAPI void U_EXPORT2
unum_setSymbol(UNumberFormat *fmt,
               UNumberFormatSymbol symbol,
               const UChar *value,
               int32_t length,
               UErrorCode *status) {
 
  if(status==NULL || U_FAILURE(*status)) {
    return;
  }

  if(fmt==NULL || (uint16_t)symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL || length<-1) {
    *status=U_ILLEGAL_ARGUMENT_ERROR;
    return;
  }

  DecimalFormatSymbols symbols(*((DecimalFormat *)fmt)->getDecimalFormatSymbols());
  symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol,
        length>=0 ? UnicodeString(value, length) : UnicodeString(value));
  ((DecimalFormat *)fmt)->setDecimalFormatSymbols(symbols);
}

/*
U_CAPI void
unum_applyPattern(            UNumberFormat     *format,
                    UBool          localized,
                    const   UChar           *pattern,
                    int32_t         patternLength
                    )
{
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;
    unum_applyPatternWithError(format,localized,pattern,patternLength,&parseError,&status);
}
*/

U_CAPI void U_EXPORT2
unum_applyPattern(  UNumberFormat  *format,
                    UBool          localized,
                    const UChar    *pattern,
                    int32_t        patternLength,
                    UParseError    *parseError,
                    UErrorCode*    status)
{
 
  UErrorCode tStatus = U_ZERO_ERROR;
  UParseError tParseError;
  
  if(parseError == NULL){
      parseError = &tParseError;
  }
  
  if(status==NULL){
      status = &tStatus;
  }

  int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
  const UnicodeString pat((UChar*)pattern, len, len);

  // Verify if the object passed is a DecimalFormat object
  if(((NumberFormat*)format)->getDynamicClassID()!= DecimalFormat::getStaticClassID()){
      *status = U_ILLEGAL_ARGUMENT_ERROR;
      return;
  }
  
  if(localized)
    ((DecimalFormat*)format)->applyLocalizedPattern(pat,*parseError, *status);
  else
    ((DecimalFormat*)format)->applyPattern(pat,*parseError, *status);
}

