/*
******************************************************************************
*                                                                            *
* 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;
}
