/*
 **********************************************************************
 *   Copyright (C) 1997-1999, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
*
* File locid.cpp
*
* Created by: Richard Gillam
*
* Modification History:
*
*   Date        Name        Description
*   02/11/97    aliu        Changed gLocPath to fgDataDirectory and added 
*                           methods to get and set it.
*   04/02/97    aliu        Made operator!= inline; fixed return value 
*                           of getName().
*   04/15/97    aliu        Cleanup for AIX/Win32.
*   04/24/97    aliu        Numerous changes per code review.
*   08/18/98    stephen     Changed getDisplayName()
*                           Added SIMPLIFIED_CHINESE, TRADITIONAL_CHINESE
*                           Added getISOCountries(), getISOLanguages(),
*                           getLanguagesForCountry()
*   03/16/99    bertrand    rehaul.
*   07/21/99    stephen     Added U_CFUNC setDefault
*   11/09/99    weiv        Added const char * getName() const;
*   04/12/00    srl         removing unicodestring api's and cached hash code
*******************************************************************************
*/



#include "uhash.h"
#include "unicode/locid.h"
#include "unicode/uloc.h"
#include "unicode/resbund.h"
#include "uresimp.h"
#include "mutex.h"
#include "unicode/unicode.h"
#include "cmemory.h"
#include "cstring.h"

/**
 * static variables
 */
Locale Locale::fgDefaultLocale;

Locale*            Locale::localeList = NULL;
int32_t            Locale::localeListCount;
UnicodeString*    Locale::isoLanguages = NULL;
int32_t            Locale::isoLanguagesCount;
UnicodeString*    Locale::isoCountries = NULL;;
int32_t            Locale::isoCountriesCount;




/**
 * Constant definitions
 */
const Locale  Locale::ENGLISH("en");
const Locale  Locale::FRENCH("fr");
const Locale  Locale::GERMAN("de");
const Locale  Locale::ITALIAN("it");
const Locale  Locale::JAPANESE("ja");
const Locale  Locale::KOREAN("ko");
const Locale  Locale::CHINESE("zh");
const Locale  Locale::SIMPLIFIED_CHINESE("zh", "CN");
const Locale  Locale::TRADITIONAL_CHINESE("zh", "TW");

// Useful constant for country.

const Locale  Locale::FRANCE    ("fr", "FR");
const Locale  Locale::GERMANY   ("de", "DE"); 
const Locale  Locale::ITALY     ("it", "IT");
const Locale  Locale::JAPAN     ("ja", "JP");
const Locale  Locale::KOREA     ("ko", "KR");
const Locale  Locale::CHINA     ("zh", "CN");
const Locale  Locale::PRC       ("zh", "CN");
const Locale  Locale::TAIWAN    ("zh", "TW");
const Locale  Locale::UK        ("en", "GB");
const Locale  Locale::US        ("en", "US");
const Locale  Locale::CANADA    ("en", "CA");
const Locale  Locale::CANADA_FRENCH("fr", "CA");


    /**
     * Table mapping ISO country codes to the ISO language codes of the languages spoken
     * in those countries.
     * (Because the Java VM specification for building arrays and hashtables causes
     * code that builds the tables element by element to be produces, we compress the data
     * into a single encoded String, and lazy evaluate the table from it.)
     */
    UHashtable* Locale::ctry2LangMapping = 0;
    const UnicodeString Locale::compressedCtry2LangMapping = UnicodeString(
        "ADfresAEarenAFpsAGenAIrnALsqAMhyruANnlenAOptAResASensmATdeAUenAWnlenAZazhyru"
        "BAsrshhrslmksqBBenBDbnhibhenBEfrnldeBFfrBGbgtrBHarenBIrnfrswBJfrBMenBNmsenzh"
        "BOesayquBRptBSenBTdzenneBVnoBWentnBYberuBZenesCAenfrCCenCFfrsgCGfrCHfrdeitrm"
        "CIfrCKmienCLesCMenfrCNzhboCOesCResCUesCVptCXenCYeltrenCZcsskDEdeDJarfrsoDKda"
        "DMenfrDOesDZarfrECesquEEetruEGarenfrEHarfritERamtiarenitESeseucaglETamaren"
        "FIfisvFJenfjhiFKenFMenFOfodaFRfreubrcoFXfrGAfrGBengdcyGDenfrGEkahyruGFfrGHen"
        "GIenesGLdaikklGMenwoGNfrGPfrenGQesGRelGTesGUenGWptGYenhiurHKzhenHNesHRhrHTfr"
        "HUhuIDinennlIEengaILiwarjiINhienguknksmlmrneorpasatateIOenIQarkutkIRfaarku"
        "ISisITitfrdeJMenJOarJPjaKEenswKGkyKHkmKIenKMfrarKNenKPkoKRkoKWarenKYenKZkkru"
        "LAlofrLBarenfrLCenfrLIdeLKtasienLRenLSstenLTltruplLUfrdeLVlvltruLYarenit"
        "MAarfresMCfrenitMDmorobgMGmgenfrMKmkshtrMLfrMMmyMNmnruMOzhptMQfrMRarfrMSen"
        "MTmtenitMUenfrhiMWenMXesMYmsenMZptNAenafdeNEfrhaNFenNGenhayoNIesNLnlfyNOno"
        "NPneNRnaenNUenNZenmiOMarenPAesenPEesquayPFfrPGenPHentlesPKurenpspasdPLplPMfren"
        "PNenPResenPTptPWenPYesgnQAarenREfrtaROrohuRUruRWenfrrwSAarSBenSCenfrSDarsu"
        "SEsvSGzhenmstaSHenSIslSJnoSKskhuplshSLenSMitSNfrSOarenitsoSRnleneshiSTptSVes"
        "SYarSZenssTCenTDfrarTFfrTGfrTHthTJtgruuzTKenmiTMtkruTNarTOentoTRtrkuTTenTVen"
        "TWzhTZenswUAukruUGenswUMenUSenesUYesUZuzruVAlaitVCenVEesVGenVIenVNvizhfr"
        "VUenfrbiWFfrWSensmYEarYTfrmgswYUsrshmkhuZAafenZMenZRfrswZWensn",
        "");

/*Used for stack allocation of temporary buffers
 *can be tweaked  for speed and likelihood of resorting to heap allocation*/ 
#define BUFFER_SIZE 50

/*Character separating the posix id fields*/
const UChar sep = 0x005F; // '_'
const char sepchar = '_'; // In the platform codepage.

Locale::~Locale()
{   
  /*if fullName is on the heap, we delete it*/
  if (fullName != fullNameBuffer) 
    {
      delete []fullName;
    }
}

Locale::Locale()
{
    init(uloc_getDefault());
}

Locale::Locale( const   char * newLanguage, 
                const   char * newCountry, 
                const   char * newVariant) 
{
  char togo_stack[ULOC_FULLNAME_CAPACITY];
  char *togo;
  char *togo_heap = NULL;
  int32_t size;
  int32_t lsize = 0;
  int32_t csize = 0;
  int32_t vsize = 0;
  char    *p;

  if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
  {
    init(NULL); /* shortcut */
  }
  else
  {
    // Calculate the size of the resulting string.
    
    // Language
    if ( newLanguage != NULL )
      {
        lsize = uprv_strlen(newLanguage);
        size = lsize;
      }
    
    // _Country
    if ( newCountry != NULL )
      {
        csize = uprv_strlen(newCountry);
        size += csize;
      }

    // _Variant
    if ( newVariant != NULL )
      {
        // remove leading _'s
        while(newVariant[0] == sepchar)
          {
            newVariant++;
          }
    
        // remove trailing _'s
        vsize = uprv_strlen(newVariant);
        while( (vsize>1) && (newVariant[vsize-1] == sepchar) )
          {
            vsize--;
          }
      }

    if( vsize > 0 )
      {
        size += vsize;
      }
  
    // Separator rules:
    if ( vsize > 0 )
      {
        size += 2;  // at least: __v 
      }
    else if ( csize > 0 )
      {
        size += 1;  // at least: _v 
      }

    //  NOW we have the full locale string..

  /*if the whole string is longer than our internal limit, we need
  to go to the heap for temporary buffers*/
    if (size > ULOC_FULLNAME_CAPACITY)
      {
        togo_heap = new char[size+1];
        togo = togo_heap;
      }
    else
      {
        togo = togo_stack;
      }

    togo[0] = 0;

    // Now, copy it back.
    p = togo;
    if ( lsize != 0 )
      {
        uprv_strcpy(p, newLanguage);
        p += lsize;
      }

    if ( ( vsize != 0 ) || (csize != 0) )  // at least:  __v
      {                                      //            ^
        *p++ = sepchar;
      }

    if ( csize != 0 )
      { 

        uprv_strcpy(p, newCountry);
        p += csize;
      }

    if ( vsize != 0)
      {
        *p++ = sepchar; // at least: __v

        uprv_strncpy(p, newVariant, vsize);  // Must use strncpy because 
        p += vsize;                          // of trimming (above).
        *p = 0; // terminate
      }

    // Parse it, because for example 'language' might really be a complete 
    // string.
    init(togo);

    delete [] togo_heap; /* If it was needed */
  }
}

Locale::Locale(const    Locale& other)

{
  int j;
    /*Copy the language and country fields*/
  uprv_strcpy(language, other.language);
  uprv_strcpy(country, other.country);
  
  /*make fullName point to the heap if necessary*/
  if ((j=uprv_strlen(other.fullName)) > ULOC_FULLNAME_CAPACITY)
    {
      fullName = new char[j+1];
    }
  else fullName = fullNameBuffer;
  
  uprv_strcpy(fullName, other.fullName);
    
    /*Make the variant point to the same offset as the copied*/
  variant = fullName + (other.variant - other.fullName) ;
}

UBool
Locale::operator==( const   Locale& other) const
{
  if (uprv_strcmp(other.language, language) == 0)    
  {
    if (uprv_strcmp(other.country, country) == 0)    
    {
      if (uprv_strcmp(other.variant, variant) == 0)    return TRUE;
    }
  }
  
  return FALSE;
  
}

/*This function initializes a Locale from a C locale ID*/
Locale& Locale::init(const char* localeID)
{
  int k,l;
  UErrorCode err = U_ZERO_ERROR;

  if (localeID == NULL) localeID = uloc_getDefault();
  l = uloc_getLanguage(localeID, 
               this->language,
               ULOC_LANG_CAPACITY,
               &err);
 
  l += k = uloc_getCountry(localeID,
              this->country,
              ULOC_COUNTRY_CAPACITY,
              &err);
  
  l--; //adjust for the 2 zero terminators
  
  /*Go to heap for the fullName if necessary*/
  int j;
  if ((j=uprv_strlen(localeID)) > ULOC_FULLNAME_CAPACITY)
    {
      this->fullName = new char[j+1];
    }
  else this->fullName = this->fullNameBuffer;
  
  uprv_strcpy(this->fullName, localeID);
      
  /*Setting up the variant:
    -point to the zero terminator of fullName if there is none
    -point to the first character of the variant if ther is one
    */
  if (k > 1)  
    {
      if (this->fullName[l] == '\0') this->variant = this->fullName + l;
      else this->variant = this->fullName + l + 1 ;
    }
  else this->variant = this->fullName + l - 1;

  return *this;
}



Locale& Locale::operator=(const Locale& other)
{
  uprv_strcpy(language, other.language);
  uprv_strcpy(country, other.country);
  if (other.fullName == other.fullNameBuffer)    fullName = fullNameBuffer;
  else 
  {
    /*In case the assigner has some of its data on the heap
     * we need to do the same*/
    if (fullName != fullNameBuffer) delete []fullName;
    fullName = new char[(uprv_strlen(other.fullName)+1)];
  }
  uprv_strcpy(fullName, other.fullName);
  /*Make the variant point to the same offset as the assigner*/
  variant = fullName + (other.variant - other.fullName) ;

  return *this;
}

int32_t
Locale::hashCode() const 
{
  UnicodeString fullNameUString(language, "");
  return fullNameUString.append(UnicodeString(country, "")).append(UnicodeString(variant, "")).hashCode();
}


Locale&
Locale::getDefault() 
{
  return fgDefaultLocale;
}


void locale_set_default_internal(const char *id)
{
  Locale::getDefault().init(id);
}

/* sfb 07/21/99 */
U_CFUNC void
locale_set_default(const char *id)
{
  locale_set_default_internal(id);
}
/* end */


void 
Locale::setDefault( const   Locale&     newLocale, 
                            UErrorCode&  status) 
{
    if (U_FAILURE(status)) return;

    uloc_setDefault(newLocale.fullName, &status);
    
    fgDefaultLocale = newLocale;
}

const char *
Locale::getCountry() const
{
  return country;
}

const char *
Locale::getLanguage() const
{
  return language;
}

const char *
Locale::getVariant() const
{
  return variant;
}

#ifndef ICU_LOCID_NO_DEPRECATES
UnicodeString& 
Locale::getLanguage(UnicodeString& lang) const
{
  lang = language;
  return lang;
}

UnicodeString& 
Locale::getCountry(UnicodeString& cntry) const
{
  cntry = country;
  return cntry;
}

UnicodeString& 
Locale::getVariant(UnicodeString& var) const
{
  var = variant;
  return var;
}

UnicodeString& 
Locale::getName(UnicodeString& name) const
{
    name = UnicodeString(fullName,"");
  return name;
}
#endif

const char * 
Locale::getName() const
{
  return fullName;
}

const char *
Locale::getISO3Language() const
{
  return uloc_getISO3Language(fullName);
}


const char *
Locale::getISO3Country() const
{
  return uloc_getISO3Country(fullName);
}

#ifndef ICU_LOCID_NO_DEPRECATES
UnicodeString& 
Locale::getISO3Language(UnicodeString& lang, UErrorCode& status) const
{
    if(U_FAILURE(status))
      return lang;

    lang = uloc_getISO3Language(fullName);
    if (lang.length() == 0)
      status = U_MISSING_RESOURCE_ERROR;
    
    return lang;
}

UnicodeString& 
Locale::getISO3Country(UnicodeString& cntry, UErrorCode& status) const
{
    if(U_FAILURE(status))
        return cntry;

    cntry = uloc_getISO3Country(fullName);
    if (cntry.length() == 0)
        status = U_MISSING_RESOURCE_ERROR;

    return cntry;
}
#endif

/**
 * Return the LCID value as specified in the "LocaleID" resource for this
 * locale.  The LocaleID must be expressed as a hexadecimal number, from
 * one to four digits.  If the LocaleID resource is not present, or is
 * in an incorrect format, 0 is returned.  The LocaleID is for use in
 * Windows (it is an LCID), but is available on all platforms.
 */
uint32_t 
Locale::getLCID() const
{
    return uloc_getLCID(fullName);
}

UnicodeString& 
Locale::getDisplayLanguage(UnicodeString& dispLang) const
{
    return this->getDisplayLanguage(getDefault(), dispLang);
}

/*We cannot make any assumptions on the size of the output display strings
* Yet, since we are calling through to a C API, we need to set limits on
* buffer size. For all the following getDisplay functions we first attempt
* to fill up a stack allocated buffer. If it is to small we heap allocated
* the exact buffer we need copy it to the UnicodeString and delete it*/

UnicodeString&
Locale::getDisplayLanguage( const   Locale&         inLocale,
                UnicodeString&  dispLang) const
{
  UErrorCode status = U_ZERO_ERROR;
  UChar bufBuffer[BUFFER_SIZE];
  UChar* buf = bufBuffer;
  
  //  dispLang = "result";
  //  return dispLang;
  int size = uloc_getDisplayLanguage(fullName,
                     inLocale.fullName,
                     buf,
                     BUFFER_SIZE,
                     &status);
  

  if (status == U_BUFFER_OVERFLOW_ERROR)
    {
      status = U_ZERO_ERROR;
      buf = new UChar[size];
      
      uloc_getDisplayLanguage(fullName,
                  inLocale.fullName,
                  buf,
                  size,
                  &status);
      
    }
  
  dispLang = buf;

  if (buf != bufBuffer) delete []buf;
  
  return dispLang;
}

UnicodeString& 
Locale::getDisplayCountry(UnicodeString& dispCntry) const
{
    return this->getDisplayCountry(getDefault(), dispCntry);
}

UnicodeString& 
Locale::getDisplayCountry(  const   Locale&         inLocale,
                                    UnicodeString&  dispCntry) const
{
  UErrorCode status = U_ZERO_ERROR;
  UChar bufBuffer[BUFFER_SIZE];
  UChar* buf = bufBuffer;
  
  
  int size = uloc_getDisplayCountry(fullName,
                    inLocale.fullName,
                    buf,
                    BUFFER_SIZE,
                    &status);
  
  if (status == U_BUFFER_OVERFLOW_ERROR)
    {
      status = U_ZERO_ERROR;
      buf = new UChar[size];
      uloc_getDisplayCountry(fullName,
                 inLocale.fullName,
                 buf,
                 size,
                 &status);
      
      
    }

  
  dispCntry = buf;

  if (buf != bufBuffer) delete []buf;
  
  return dispCntry;
}

UnicodeString& 
Locale::getDisplayVariant(UnicodeString& dispVar) const
{
  return this->getDisplayVariant(getDefault(), dispVar);
  
}

UnicodeString& Locale::getDisplayVariant(const Locale& inLocale,
                     UnicodeString& dispVar) const
{
  UErrorCode status = U_ZERO_ERROR;
  UChar bufBuffer[BUFFER_SIZE];
  UChar* buf = bufBuffer;
  

  int size = uloc_getDisplayVariant(fullName,
                    inLocale.fullName,
                    buf,
                    BUFFER_SIZE,
                    &status);
  
  if (status == U_BUFFER_OVERFLOW_ERROR)
    {
      status = U_ZERO_ERROR;
      buf = new UChar[size];
      uloc_getDisplayVariant(fullName,
                 inLocale.fullName,
                 buf,
                 size,
                 &status);
      
    }
  
 
  dispVar = buf;
  
  if (buf != bufBuffer) delete []buf;
  
  return dispVar;
}

UnicodeString& 
Locale::getDisplayName( UnicodeString& name ) const
{
    return this->getDisplayName(getDefault(), name);
}

UnicodeString& 
Locale::getDisplayName( const   Locale&     inLocale,
            UnicodeString& result) const
{
  UErrorCode status = U_ZERO_ERROR;
  UChar bufBuffer[BUFFER_SIZE];
  UChar* buf = bufBuffer;
  
  int size = uloc_getDisplayName(fullName,
                 inLocale.fullName,
                 buf,
                 BUFFER_SIZE,
                 &status);
  
  if (status == U_BUFFER_OVERFLOW_ERROR)
    {
      status = U_ZERO_ERROR;
      
      buf = new UChar[size];
      uloc_getDisplayName(fullName,
              inLocale.fullName,
              buf,
              size,
              &status);    
    }

    result = buf;
  
  if (buf != bufBuffer) {delete []buf;}
  
  return result;
}

const Locale*
Locale::getAvailableLocales(int32_t& count) 
{
  // for now, there is a hardcoded list, so just walk through that list and set it up.
  if (localeList == 0) {
      UErrorCode status = U_ZERO_ERROR;
      ResourceBundle index(UnicodeString(""), Locale(kIndexLocaleName), status);
      ResourceBundle locales = index.get(kIndexTag, status);

      char name[96];
      locales.resetIterator();

      count = locales.getSize();

      Locale *newLocaleList = new Locale[count];

      int32_t i = 0;
      UnicodeString temp;
      while(locales.hasNext()) {
          temp = locales.getNextString(status);
          temp.extract(0, temp.length(), name);
          name[temp.length()] = '\0';
          newLocaleList[i++].setFromPOSIXID(name);
      }

      Mutex mutex;
      if(localeList != 0) {
    delete []newLocaleList;
      }
      else {
    localeListCount = count;
            localeList = newLocaleList;
      }
    }
  count = localeListCount;
  return localeList;
}

const char* const* Locale::getISOCountries()
{
  return uloc_getISOCountries();
}

const char* const* Locale::getISOLanguages()
{
  return uloc_getISOLanguages();
}


#ifndef ICU_LOCID_NO_DEPRECATES
/**
 * Returns a list of all 2-letter country codes defined in ISO 3166.
 * Can be used to create Locales.
 */
const UnicodeString*
Locale::getISOCountries(int32_t& count) 
{
  if(isoCountries == 0) {
    const char* const*    cResult = uloc_getISOCountries();
    int32_t tempCount;
    
    int i;
    tempCount = 0;
    for (i = 0; cResult[i] != NULL; i++)      ++tempCount;
    
    UnicodeString *temp = new UnicodeString [tempCount];
    
    for(i = 0; i < tempCount; ++i)
      temp[i] = cResult[i];
    
    Mutex mutex;        
    if(isoCountries != 0)
      delete [] temp;
    else {
      isoCountries = temp;
      isoCountriesCount = tempCount;
    }
  }
  
  count = isoCountriesCount;


  return isoCountries;
}

/**
 * Returns a list of all 2-letter language codes defined in ISO 639.
 * Can be used to create Locales.
 * [NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
 * The list this function returns includes both the new and the old codes for the
 * languages whose codes have changed.]
 */
const UnicodeString* 
Locale::getISOLanguages(int32_t& count) 
{
  if(isoLanguages == 0) {
    const char* const* cResult = uloc_getISOLanguages();
    int32_t tempCount;
    
    int i;
    tempCount = 0;
    for (i = 0; cResult[i] != NULL; i++)   ++tempCount;
    
    UnicodeString *temp = new UnicodeString [tempCount];
    
    for(i = 0; i < tempCount; ++i)
      temp[i] = cResult[i];
    
    Mutex mutex;        
    if(isoLanguages != 0)
      delete [] temp;
    else {
      isoLanguages = temp;
      isoLanguagesCount = tempCount;
    }
  }
  
  count = isoLanguagesCount;
  return isoLanguages;
}
#endif

/**
 * Given an ISO country code, returns an array of Strings containing the ISO
 * codes of the languages spoken in that country.  Official languages are listed
 * in the returned table before unofficial languages, but other than that, the
 * order of the returned list is indeterminate.  If the value the user passes in
 * for "country" is not a valid ISO 316 country code, or if we don't have language
 * information for the specified country, this function returns an empty array.
 *
 * [This function is not currently part of Locale's API, but is needed in the
 * implementation.  We hope to add it to the API in a future release.]
 */
const UnicodeString* 
Locale::getLanguagesForCountry(const UnicodeString& country, int32_t& count) 
{
  // To save on the size of a static array in the .class file, we keep the
  // data around encoded into a String.  The first time this function is called,
  // the String s parsed to produce a Hashtable, which is then used for all
  // lookups.
  if(ctry2LangMapping == 0) {
    UErrorCode err = U_ZERO_ERROR;
    UHashtable *temp = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &err);
    if (U_FAILURE(err)) 
      {
        count = 0;
        return NULL;
      }

    uhash_setKeyDeleter(temp, uhash_deleteUnicodeString);

    int32_t i = 0;
    int32_t j;
    int32_t count = sizeof(compressedCtry2LangMapping) / sizeof(compressedCtry2LangMapping[0]);
    while (i < count) {
      UnicodeString key;
      compressedCtry2LangMapping.extractBetween(i, i + 2, key);
      i += 2;
      for(j = i; j < count; j += 2)
        if(Unicode::isUpperCase(compressedCtry2LangMapping[j]))
          break;
      UnicodeString compressedValues;
      compressedCtry2LangMapping.extractBetween(i, j, compressedValues);
      UnicodeString *values = new UnicodeString[compressedValues.length() / 2];
      int32_t valLen = sizeof(values) / sizeof(values[0]);
      for (int32_t k = 0; k < valLen; ++k)
        compressedValues.extractBetween(k * 2, (k * 2) + 2, values[k]);
      uhash_put(temp, new UnicodeString(key), values, &err);
      i = j;
    }
    
    Mutex mutex;
    if(ctry2LangMapping != 0)
      uhash_close(temp);
    else
      ctry2LangMapping = temp;
  }

  const UnicodeString *result = (const UnicodeString*)uhash_get(ctry2LangMapping, &country);
  if(result == 0)
    count = 0;
  else
    count = sizeof(result) / sizeof(result[0]);
  
  return result;
}


// ================= privates =====================================




// Set the locale's data based on a posix id. 
void Locale::setFromPOSIXID(const char *posixID)
{
  init(posixID);  
}

#ifndef ICU_LOCID_NO_DEPRECATES
// Deprecated APIs
Locale::Locale( const   UnicodeString&  newLanguage)
{
  char myLocaleID[ULOC_FULLNAME_CAPACITY];

  myLocaleID[newLanguage.extract(0, 0x7fffffff, myLocaleID, "")] = '\0';
  init(myLocaleID);
}

Locale::Locale( const   UnicodeString&  newLanguage, 
                const   UnicodeString&  newCountry)
{
    UnicodeString togo(newLanguage);
    char myLocaleID[ULOC_FULLNAME_CAPACITY];
  
    if(newCountry.length()>0) {
        togo += sep;
        togo += newCountry;
    }

    myLocaleID[togo.extract(0, 0x7fffffff, myLocaleID, "")] = '\0';
    init(myLocaleID);
}


Locale::Locale( const   UnicodeString&  newLanguage, 
                const   UnicodeString&  newCountry, 
                const   UnicodeString&  newVariant) 
{
  UnicodeString togo(newLanguage);
  
  char myLocaleID[ULOC_FULLNAME_CAPACITY];
  UnicodeString newVariantCopy(newVariant);
  
  
  if (newCountry.length() > 0 ||
      newVariantCopy.length() > 0 )
    {
      togo += sep;
      togo += newCountry;
    }
  
  int vsize = newVariantCopy.length();
    if (vsize > 0)
      {
    int i = 0;
    //We need to trim variant codes : (_*)$var(_*) --> $var 
    while ((i<vsize) && newVariantCopy[i] == sep) newVariantCopy.remove(i++, 1);
    i = newVariantCopy.length() - 1;
    while (i && (newVariantCopy[i] == sep)) newVariantCopy.remove(i--, 1);
    
    togo += sep ;
    togo += newVariantCopy ;
      }
  
  int size = togo.length();

  /*if the variant is longer than our internal limit, we need
  to go to the heap for temporary buffers*/
  if (size > ULOC_FULLNAME_CAPACITY)
    {
      char *togo_heap = new char[size+1];
      togo.extract(0,size, togo_heap, "");
      togo_heap[size] = '\0';
      init(togo_heap);
      delete []togo_heap;
    }
  else 
    {
      togo.extract(0,size, myLocaleID, "");
      myLocaleID[size] = '\0';
      init(myLocaleID);
    }
  
}
#endif

//eof




