// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
******************************************************************************
*                                                                            *
* Copyright (C) 2003-2016, International Business Machines                   *
*                Corporation and others. All Rights Reserved.                *
*                                                                            *
******************************************************************************
*   file name:  ulocdata.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2003Oct21
*   created by: Ram Viswanadha,John Emmons
*/

#include "cmemory.h"
#include "unicode/ustring.h"
#include "unicode/ures.h"
#include "unicode/uloc.h"
#include "unicode/ulocdata.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "ulocimp.h"

#define MEASUREMENT_SYSTEM  "MeasurementSystem"
#define PAPER_SIZE          "PaperSize"

/** A locale data object.
 *  For usage in C programs.
 *  @draft ICU 3.4
 */
struct ULocaleData {
    /**
     * Controls the "No Substitute" behavior of this locale data object
     */
    UBool noSubstitute;

    /**
     * Pointer to the resource bundle associated with this locale data object
     */
    UResourceBundle *bundle;

    /**
     * Pointer to the lang resource bundle associated with this locale data object
     */
    UResourceBundle *langBundle;
};

U_CAPI ULocaleData* U_EXPORT2
ulocdata_open(const char *localeID, UErrorCode *status)
{
   ULocaleData *uld;

   if (U_FAILURE(*status)) {
       return NULL;
   }

   uld = (ULocaleData *)uprv_malloc(sizeof(ULocaleData));
   if (uld == NULL) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return(NULL);
   }

   uld->langBundle = NULL;

   uld->noSubstitute = FALSE;
   uld->bundle = ures_open(NULL, localeID, status);
   uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status);

   if (U_FAILURE(*status)) {
      uprv_free(uld);
      return NULL;
   }

   return uld;
}

U_CAPI void U_EXPORT2
ulocdata_close(ULocaleData *uld)
{
    if ( uld != NULL ) {
       ures_close(uld->langBundle);
       ures_close(uld->bundle);
       uprv_free(uld);
    }
}

U_CAPI void U_EXPORT2
ulocdata_setNoSubstitute(ULocaleData *uld, UBool setting)
{
   uld->noSubstitute = setting;
}

U_CAPI UBool U_EXPORT2
ulocdata_getNoSubstitute(ULocaleData *uld)
{
   return uld->noSubstitute;
}

U_CAPI USet* U_EXPORT2
ulocdata_getExemplarSet(ULocaleData *uld, USet *fillIn,
                        uint32_t options, ULocaleDataExemplarSetType extype, UErrorCode *status){

    static const char* const exemplarSetTypes[] = { "ExemplarCharacters", 
                                                    "AuxExemplarCharacters", 
                                                    "ExemplarCharactersIndex",
                                                    "ExemplarCharactersPunctuation"};
    const UChar *exemplarChars = NULL;
    int32_t len = 0;
    UErrorCode localStatus = U_ZERO_ERROR;

    if (U_FAILURE(*status))
        return NULL;

    exemplarChars = ures_getStringByKey(uld->bundle, exemplarSetTypes[extype], &len, &localStatus);
    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status))
        return NULL;

    if(fillIn != NULL)
        uset_applyPattern(fillIn, exemplarChars, len,
                          USET_IGNORE_SPACE | options, status);
    else
        fillIn = uset_openPatternOptions(exemplarChars, len,
                                         USET_IGNORE_SPACE | options, status);

    return fillIn;

}

U_CAPI int32_t U_EXPORT2
ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type,
                      UChar *result, int32_t resultLength, UErrorCode *status){

    static const char* const delimiterKeys[] =  {
        "quotationStart",
        "quotationEnd",
        "alternateQuotationStart",
        "alternateQuotationEnd"
    };

    UResourceBundle *delimiterBundle;
    int32_t len = 0;
    const UChar *delimiter = NULL;
    UErrorCode localStatus = U_ZERO_ERROR;

    if (U_FAILURE(*status))
        return 0;

    delimiterBundle = ures_getByKey(uld->bundle, "delimiters", NULL, &localStatus);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        ures_close(delimiterBundle);
        return 0;
    }

    delimiter = ures_getStringByKey(delimiterBundle, delimiterKeys[type], &len, &localStatus);
    ures_close(delimiterBundle);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        return 0;
    }

    u_strncpy(result,delimiter, resultLength);
    return len;
}

static UResourceBundle * measurementTypeBundleForLocale(const char *localeID, const char *measurementType, UErrorCode *status){
    char region[ULOC_COUNTRY_CAPACITY];
    UResourceBundle *rb;
    UResourceBundle *measTypeBundle = NULL;
    
    ulocimp_getRegionForSupplementalData(localeID, TRUE, region, ULOC_COUNTRY_CAPACITY, status);
    
    rb = ures_openDirect(NULL, "supplementalData", status);
    ures_getByKey(rb, "measurementData", rb, status);
    if (rb != NULL) {
        UResourceBundle *measDataBundle = ures_getByKey(rb, region, NULL, status);
        if (U_SUCCESS(*status)) {
        	measTypeBundle = ures_getByKey(measDataBundle, measurementType, NULL, status);
        }
        if (*status == U_MISSING_RESOURCE_ERROR) {
            *status = U_ZERO_ERROR;
            if (measDataBundle != NULL) {
                ures_close(measDataBundle);
            }
            measDataBundle = ures_getByKey(rb, "001", NULL, status);
            measTypeBundle = ures_getByKey(measDataBundle, measurementType, NULL, status);
        }
        ures_close(measDataBundle);
    }
    ures_close(rb);
    return measTypeBundle;
}

U_CAPI UMeasurementSystem U_EXPORT2
ulocdata_getMeasurementSystem(const char *localeID, UErrorCode *status){

    UResourceBundle* measurement=NULL;
    UMeasurementSystem system = UMS_LIMIT;

    if(status == NULL || U_FAILURE(*status)){
        return system;
    }

    measurement = measurementTypeBundleForLocale(localeID, MEASUREMENT_SYSTEM, status);
    system = (UMeasurementSystem) ures_getInt(measurement, status);

    ures_close(measurement);

    return system;

}

U_CAPI void U_EXPORT2
ulocdata_getPaperSize(const char* localeID, int32_t *height, int32_t *width, UErrorCode *status){
    UResourceBundle* paperSizeBundle = NULL;
    const int32_t* paperSize=NULL;
    int32_t len = 0;

    if(status == NULL || U_FAILURE(*status)){
        return;
    }

    paperSizeBundle = measurementTypeBundleForLocale(localeID, PAPER_SIZE, status);
    paperSize = ures_getIntVector(paperSizeBundle, &len,  status);

    if(U_SUCCESS(*status)){
        if(len < 2){
            *status = U_INTERNAL_PROGRAM_ERROR;
        }else{
            *height = paperSize[0];
            *width  = paperSize[1];
        }
    }

    ures_close(paperSizeBundle);

}

U_CAPI void U_EXPORT2
ulocdata_getCLDRVersion(UVersionInfo versionArray, UErrorCode *status) {
    UResourceBundle *rb = NULL;
    rb = ures_openDirect(NULL, "supplementalData", status);
    ures_getVersionByKey(rb, "cldrVersion", versionArray, status);
    ures_close(rb);
}

U_CAPI int32_t U_EXPORT2
ulocdata_getLocaleDisplayPattern(ULocaleData *uld,
                                 UChar *result,
                                 int32_t resultCapacity,
                                 UErrorCode *status) {
    UResourceBundle *patternBundle;
    int32_t len = 0;
    const UChar *pattern = NULL;
    UErrorCode localStatus = U_ZERO_ERROR;

    if (U_FAILURE(*status))
        return 0;

    patternBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        ures_close(patternBundle);
        return 0;
    }

    pattern = ures_getStringByKey(patternBundle, "pattern", &len, &localStatus);
    ures_close(patternBundle);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        return 0;
    }

    u_strncpy(result, pattern, resultCapacity);
    return len;
}


U_CAPI int32_t U_EXPORT2
ulocdata_getLocaleSeparator(ULocaleData *uld,
                            UChar *result,
                            int32_t resultCapacity,
                            UErrorCode *status)  {
    UResourceBundle *separatorBundle;
    int32_t len = 0;
    const UChar *separator = NULL;
    UErrorCode localStatus = U_ZERO_ERROR;
    UChar *p0, *p1;
    static const UChar sub0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 }; /* {0} */
    static const UChar sub1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 }; /* {1} */
    static const int32_t subLen = 3;

    if (U_FAILURE(*status))
        return 0;

    separatorBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        ures_close(separatorBundle);
        return 0;
    }

    separator = ures_getStringByKey(separatorBundle, "separator", &len, &localStatus);
    ures_close(separatorBundle);

    if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
        localStatus = U_MISSING_RESOURCE_ERROR;
    }

    if (localStatus != U_ZERO_ERROR) {
        *status = localStatus;
    }

    if (U_FAILURE(*status)){
        return 0;
    }

    /* For backwards compatibility, if we have a pattern, return the portion between {0} and {1} */
    p0=u_strstr(separator, sub0);
    p1=u_strstr(separator, sub1);
    if (p0!=NULL && p1!=NULL && p0<=p1) {
        separator = (const UChar *)p0 + subLen;
        len = p1 - separator;
        /* Desired separator is no longer zero-terminated; handle that if necessary */
        if (len < resultCapacity) {
            u_strncpy(result, separator, len);
            result[len] = 0;
            return len;
        }
    }

    u_strncpy(result, separator, resultCapacity);
    return len;
}
