/*
 *******************************************************************************
 * Copyright (C) 2008-2010, Google, International Business Machines Corporation
 * and  others. All Rights Reserved.                                           
 *******************************************************************************
 */

#include <typeinfo>  // for 'typeid' to work

#include "unicode/tmutfmt.h"

#if !UCONFIG_NO_FORMATTING

#include "cmemory.h"
#include "cstring.h"
#include "hash.h"
#include "uresimp.h"
#include "unicode/msgfmt.h"

#define LEFT_CURLY_BRACKET  ((UChar)0x007B)
#define RIGHT_CURLY_BRACKET ((UChar)0x007D)
#define SPACE             ((UChar)0x0020)
#define DIGIT_ZERO        ((UChar)0x0030)
#define LOW_S             ((UChar)0x0073)
#define LOW_M             ((UChar)0x006D)
#define LOW_I             ((UChar)0x0069)
#define LOW_N             ((UChar)0x006E)
#define LOW_H             ((UChar)0x0068)
#define LOW_W             ((UChar)0x0077)
#define LOW_D             ((UChar)0x0064)
#define LOW_Y             ((UChar)0x0079)
#define LOW_Z             ((UChar)0x007A)
#define LOW_E             ((UChar)0x0065)
#define LOW_R             ((UChar)0x0072)
#define LOW_O             ((UChar)0x006F)
#define LOW_N             ((UChar)0x006E)
#define LOW_T             ((UChar)0x0074)


//TODO: define in compile time
//#define TMUTFMT_DEBUG 1

#ifdef TMUTFMT_DEBUG
#include <iostream>
#endif

U_NAMESPACE_BEGIN



UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnitFormat)

static const char gUnitsTag[] = "units";
static const char gShortUnitsTag[] = "unitsShort";
static const char gTimeUnitYear[] = "year";
static const char gTimeUnitMonth[] = "month";
static const char gTimeUnitDay[] = "day";
static const char gTimeUnitWeek[] = "week";
static const char gTimeUnitHour[] = "hour";
static const char gTimeUnitMinute[] = "minute";
static const char gTimeUnitSecond[] = "second";
static const char gPluralCountOther[] = "other";

static const UChar DEFAULT_PATTERN_FOR_SECOND[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_S, 0};
static const UChar DEFAULT_PATTERN_FOR_MINUTE[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, LOW_I, LOW_N, 0};
static const UChar DEFAULT_PATTERN_FOR_HOUR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_H, 0};
static const UChar DEFAULT_PATTERN_FOR_WEEK[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_W, 0};
static const UChar DEFAULT_PATTERN_FOR_DAY[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_D, 0};
static const UChar DEFAULT_PATTERN_FOR_MONTH[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, 0};
static const UChar DEFAULT_PATTERN_FOR_YEAR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_Y, 0};

static const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0};
static const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0};
static const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0};


TimeUnitFormat::TimeUnitFormat(UErrorCode& status)
:   fNumberFormat(NULL),
    fPluralRules(NULL) {
    create(Locale::getDefault(), kFull, status);
}


TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status)
:   fNumberFormat(NULL),
    fPluralRules(NULL) {
    create(locale, kFull, status);
}


TimeUnitFormat::TimeUnitFormat(const Locale& locale, EStyle style, UErrorCode& status)
:   fNumberFormat(NULL),
    fPluralRules(NULL) {
    create(locale, style, status);
}


TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
:   MeasureFormat(other),
    fNumberFormat(NULL),
    fPluralRules(NULL),
    fStyle(kFull)
{
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        fTimeUnitToCountToPatterns[i] = NULL;
    }
    *this = other;
}


TimeUnitFormat::~TimeUnitFormat() {
    delete fNumberFormat;
    fNumberFormat = NULL;
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
    delete fPluralRules;
    fPluralRules = NULL;
}


Format* 
TimeUnitFormat::clone(void) const {
    return new TimeUnitFormat(*this);
}


TimeUnitFormat& 
TimeUnitFormat::operator=(const TimeUnitFormat& other) {
    if (this == &other) {
        return *this;
    }
    delete fNumberFormat;
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
    delete fPluralRules;
    if (other.fNumberFormat) {
        fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
    } else {
        fNumberFormat = NULL;
    }
    fLocale = other.fLocale;
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        UErrorCode status = U_ZERO_ERROR;
        fTimeUnitToCountToPatterns[i] = initHash(status);
        if (U_SUCCESS(status)) {
            copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
        } else {
            delete fTimeUnitToCountToPatterns[i];
            fTimeUnitToCountToPatterns[i] = NULL;
        }
    } 
    if (other.fPluralRules) {
        fPluralRules = (PluralRules*)other.fPluralRules->clone();
    } else {
        fPluralRules = NULL;
    }
    fStyle = other.fStyle;
    return *this;
}


UBool 
TimeUnitFormat::operator==(const Format& other) const {
    if (typeid(*this) == typeid(other)) {
        TimeUnitFormat* fmt = (TimeUnitFormat*)&other;
        UBool ret =  ( ((fNumberFormat && fmt->fNumberFormat && *fNumberFormat == *fmt->fNumberFormat)
                            || fNumberFormat == fmt->fNumberFormat ) 
                        && fLocale == fmt->fLocale 
                        && ((fPluralRules && fmt->fPluralRules && *fPluralRules == *fmt->fPluralRules) 
                            || fPluralRules == fmt->fPluralRules) 
                        && fStyle == fmt->fStyle); 
        if (ret) {
            for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
                 i < TimeUnit::UTIMEUNIT_FIELD_COUNT && ret;
                 i = (TimeUnit::UTimeUnitFields)(i+1)) {
                ret = fTimeUnitToCountToPatterns[i]->equals(*(fmt->fTimeUnitToCountToPatterns[i]));
            }
        }
        return ret;
    }
    return false;
}


UnicodeString& 
TimeUnitFormat::format(const Formattable& obj, UnicodeString& toAppendTo,
                       FieldPosition& pos, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return toAppendTo;
    }
    if (obj.getType() == Formattable::kObject) {
        const UObject* formatObj = obj.getObject();
        const TimeUnitAmount* amount = dynamic_cast<const TimeUnitAmount*>(formatObj);
        if (amount != NULL){
            Hashtable* countToPattern = fTimeUnitToCountToPatterns[amount->getTimeUnitField()];
            double number;
            const Formattable& amtNumber = amount->getNumber();
            if (amtNumber.getType() == Formattable::kDouble) {
                number = amtNumber.getDouble();
            } else if (amtNumber.getType() == Formattable::kLong) {
                number = amtNumber.getLong();
            } else {
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return toAppendTo;
            }
            UnicodeString count = fPluralRules->select(number);
#ifdef TMUTFMT_DEBUG
            char result[1000];
            count.extract(0, count.length(), result, "UTF-8");
            std::cout << "number: " << number << "; format plural count: " << result << "\n";           
#endif
            MessageFormat* pattern = ((MessageFormat**)countToPattern->get(count))[fStyle];
            Formattable formattable[1];
            formattable[0].setDouble(number);
            return pattern->format(formattable, 1, toAppendTo, pos, status);
        }
    }
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return toAppendTo;
}


void 
TimeUnitFormat::parseObject(const UnicodeString& source, 
                            Formattable& result,
                            ParsePosition& pos) const {
    double resultNumber = -1; 
    UBool withNumberFormat = false;
    TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
    int32_t oldPos = pos.getIndex();
    int32_t newPos = -1;
    int32_t longestParseDistance = 0;
    UnicodeString* countOfLongestMatch = NULL;
#ifdef TMUTFMT_DEBUG
    char res[1000];
    source.extract(0, source.length(), res, "UTF-8");
    std::cout << "parse source: " << res << "\n";           
#endif
    // parse by iterating through all available patterns
    // and looking for the longest match.
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
        int32_t elemPos = -1;
        const UHashElement* elem = NULL;
        while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
            const UHashTok keyTok = elem->key;
            UnicodeString* count = (UnicodeString*)keyTok.pointer;
#ifdef TMUTFMT_DEBUG
            count->extract(0, count->length(), res, "UTF-8");
            std::cout << "parse plural count: " << res << "\n";           
#endif
            const UHashTok valueTok = elem->value;
            // the value is a pair of MessageFormat*
            MessageFormat** patterns = (MessageFormat**)valueTok.pointer;
            for (EStyle style = kFull; style < kTotal; style = (EStyle)(style + 1)) {
                MessageFormat* pattern = patterns[style];
                pos.setErrorIndex(-1);
                pos.setIndex(oldPos);
                // see if we can parse
                Formattable parsed;
                pattern->parseObject(source, parsed, pos);
                if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
                    continue;
                }
    #ifdef TMUTFMT_DEBUG
                std::cout << "parsed.getType: " << parsed.getType() << "\n";
    #endif
                double tmpNumber = 0;
                if (pattern->getArgTypeCount() != 0) {
                    // pattern with Number as beginning, such as "{0} d".
                    // check to make sure that the timeUnit is consistent
                    Formattable& temp = parsed[0];
                    if (temp.getType() == Formattable::kDouble) {
                        tmpNumber = temp.getDouble();
                    } else if (temp.getType() == Formattable::kLong) {
                        tmpNumber = temp.getLong();
                    } else {
                        continue;
                    }
                    UnicodeString select = fPluralRules->select(tmpNumber);
    #ifdef TMUTFMT_DEBUG
                    select.extract(0, select.length(), res, "UTF-8");
                    std::cout << "parse plural select count: " << res << "\n"; 
    #endif
                    if (*count != select) {
                        continue;
                    }
                }
                int32_t parseDistance = pos.getIndex() - oldPos;
                if (parseDistance > longestParseDistance) {
                    if (pattern->getArgTypeCount() != 0) {
                        resultNumber = tmpNumber;
                        withNumberFormat = true;
                    } else {
                        withNumberFormat = false;
                    }
                    resultTimeUnit = i;
                    newPos = pos.getIndex();
                    longestParseDistance = parseDistance;
                    countOfLongestMatch = count;
                }
            }
        }
    }
    /* After find the longest match, parse the number.
     * Result number could be null for the pattern without number pattern.
     * such as unit pattern in Arabic.
     * When result number is null, use plural rule to set the number.
     */
    if (withNumberFormat == false && longestParseDistance != 0) {
        // set the number using plurrual count
        if ( *countOfLongestMatch == PLURAL_COUNT_ZERO ) {
            resultNumber = 0;
        } else if ( *countOfLongestMatch == PLURAL_COUNT_ONE ) {
            resultNumber = 1;
        } else if ( *countOfLongestMatch == PLURAL_COUNT_TWO ) {
            resultNumber = 2;
        } else {
            // should not happen.
            // TODO: how to handle?
            resultNumber = 3;
        }
    }
    if (longestParseDistance == 0) {
        pos.setIndex(oldPos);
        pos.setErrorIndex(0);
    } else {
        UErrorCode status = U_ZERO_ERROR;
        TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUnit, status);
        if (U_SUCCESS(status)) {
            result.adoptObject(tmutamt);
            pos.setIndex(newPos);
            pos.setErrorIndex(-1);
        } else {
            pos.setIndex(oldPos);
            pos.setErrorIndex(0);
        }
    }
}


void
TimeUnitFormat::create(const Locale& locale, EStyle style, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    if (style < kFull || style > kAbbreviate) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    fStyle = style;
    fLocale = locale;
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        fTimeUnitToCountToPatterns[i] = NULL;
    }
    //TODO: format() and parseObj() are const member functions,
    //so, can not do lazy initialization in C++.
    //setup has to be done in constructors.
    //and here, the behavior is not consistent with Java.
    //In Java, create an empty instance does not setup locale as
    //default locale. If it followed by setNumberFormat(),
    //in format(), the locale will set up as the locale in fNumberFormat.
    //But in C++, this sets the locale as the default locale. 
    setup(status);
}

void 
TimeUnitFormat::setup(UErrorCode& err) {
    initDataMembers(err);
    readFromCurrentLocale(kFull, gUnitsTag, err);
    checkConsistency(kFull, gUnitsTag, err);
    readFromCurrentLocale(kAbbreviate, gShortUnitsTag, err);
    checkConsistency(kAbbreviate, gShortUnitsTag, err);
}


void
TimeUnitFormat::initDataMembers(UErrorCode& err){
    if (U_FAILURE(err)) {
        return;
    }
    if (fNumberFormat == NULL) {
        fNumberFormat = NumberFormat::createInstance(fLocale, err);
    }
    delete fPluralRules;
    fPluralRules = PluralRules::forLocale(fLocale, err);
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
}




void
TimeUnitFormat::readFromCurrentLocale(EStyle style, const char* key, UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    // fill timeUnitToCountToPatterns from resource file
    // err is used to indicate wrong status except missing resource.
    // status is an error code used in resource lookup.
    // status does not affect "err".
    UErrorCode status = U_ZERO_ERROR;
    UResourceBundle *rb, *unitsRes;
    rb = ures_open(NULL, fLocale.getName(), &status);
    unitsRes = ures_getByKey(rb, key, NULL, &status);
    if (U_FAILURE(status)) {
        ures_close(unitsRes);
        ures_close(rb);
        return;
    }
    int32_t size = ures_getSize(unitsRes);
    for ( int32_t index = 0; index < size; ++index) {
        // resource of one time unit
        UResourceBundle* oneTimeUnit = ures_getByIndex(unitsRes, index,
                                                       NULL, &status);
        if (U_SUCCESS(status)) {
            const char* timeUnitName = ures_getKey(oneTimeUnit);
            if (timeUnitName == NULL) {
                ures_close(oneTimeUnit);
                continue;
            }
            UResourceBundle* countsToPatternRB = ures_getByKey(unitsRes, 
                                                             timeUnitName, 
                                                             NULL, &status);
            if (countsToPatternRB == NULL || U_FAILURE(status)) {
                ures_close(countsToPatternRB);
                ures_close(oneTimeUnit);
                continue;
            }
            TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT;
            if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_YEAR;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_MONTH;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_DAY;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_HOUR;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_MINUTE;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_SECOND;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_WEEK;
            } else {
                ures_close(countsToPatternRB);
                ures_close(oneTimeUnit);
                continue;
            }
            Hashtable* countToPatterns = fTimeUnitToCountToPatterns[timeUnitField];
            if (countToPatterns == NULL) {
                countToPatterns = initHash(err);
                if (U_FAILURE(err)) {
                    ures_close(countsToPatternRB);
                    ures_close(oneTimeUnit);
                    delete countToPatterns;
                    break;
                }
            }
            int32_t count = ures_getSize(countsToPatternRB);
            const UChar* pattern;
            const char*  pluralCount;
            int32_t ptLength; 
            for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) {
                // resource of count to pattern
                pattern = ures_getNextString(countsToPatternRB, &ptLength,
                                             &pluralCount, &status);
                if (U_FAILURE(status)) {
                    continue;
                }
                MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err);
                if ( U_SUCCESS(err) ) {
                  if (fNumberFormat != NULL) {
                    messageFormat->setFormat(0, *fNumberFormat);
                  }
                  MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCount);
                  if (formatters == NULL) {
                    formatters = (MessageFormat**)uprv_malloc(kTotal*sizeof(MessageFormat*));
                    formatters[kFull] = NULL;
                    formatters[kAbbreviate] = NULL;
                    countToPatterns->put(pluralCount, formatters, err);
                    if (U_FAILURE(err)) {
                        uprv_free(formatters);
                    }
                  } 
                  if (U_SUCCESS(err)) {
                      //delete formatters[style];
                      formatters[style] = messageFormat;
                  }
                } 
                if (U_FAILURE(err)) {
                    ures_close(countsToPatternRB);
                    ures_close(oneTimeUnit);
                    ures_close(unitsRes);
                    ures_close(rb);
                    delete messageFormat;
                    delete countToPatterns;
                    return;
                }
            }
            if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) {
                fTimeUnitToCountToPatterns[timeUnitField] = countToPatterns;
            }
            ures_close(countsToPatternRB);
        }
        ures_close(oneTimeUnit);
    }
    ures_close(unitsRes);
    ures_close(rb);
}


void 
TimeUnitFormat::checkConsistency(EStyle style, const char* key, UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    // there should be patterns for each plural rule in each time unit.
    // For each time unit, 
    //     for each plural rule, following is unit pattern fall-back rule:
    //         ( for example: "one" hour )
    //         look for its unit pattern in its locale tree.
    //         if pattern is not found in its own locale, such as de_DE,
    //         look for the pattern in its parent, such as de,
    //         keep looking till found or till root.
    //         if the pattern is not found in root either,
    //         fallback to plural count "other",
    //         look for the pattern of "other" in the locale tree:
    //         "de_DE" to "de" to "root".
    //         If not found, fall back to value of 
    //         static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". 
    //
    // Following is consistency check to create pattern for each
    // plural rule in each time unit using above fall-back rule.
    //
    StringEnumeration* keywords = fPluralRules->getKeywords(err);
    if (U_SUCCESS(err)) {
        const char* pluralCount;
        while ((pluralCount = keywords->next(NULL, err)) != NULL) {
            if ( U_SUCCESS(err) ) {
                for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
                    // for each time unit, 
                    // get all the patterns for each plural rule in this locale.
                    Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
                    if ( countToPatterns == NULL ) {
                        countToPatterns = initHash(err);
                        if (U_FAILURE(err)) {
                            delete countToPatterns;
                            return;
                        }
                        fTimeUnitToCountToPatterns[i] = countToPatterns;
                    }
                    MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCount);
                    if( formatters == NULL || formatters[style] == NULL ) {
                        // look through parents
                        searchInLocaleChain(style, key,
                                            (TimeUnit::UTimeUnitFields)i, 
                                            pluralCount, pluralCount, 
                                            countToPatterns, err);
                    }
                }
            }
        }
    }
    delete keywords;
}



// srcPluralCount is the original plural count on which the pattern is
// searched for.
// searchPluralCount is the fallback plural count.
// For example, to search for pattern for ""one" hour",
// "one" is the srcPluralCount,
// if the pattern is not found even in root, fallback to 
// using patterns of plural count "other", 
// then, "other" is the searchPluralCount.
void 
TimeUnitFormat::searchInLocaleChain(EStyle style, const char* key,
                                TimeUnit::UTimeUnitFields srcTimeUnitField,
                                const char* srcPluralCount,
                                const char* searchPluralCount, 
                                Hashtable* countToPatterns,
                                UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    UErrorCode status = U_ZERO_ERROR;
    const char *locName = fLocale.getName();
    char parentLocale[ULOC_FULLNAME_CAPACITY];
    uprv_strcpy(parentLocale, locName);
    int32_t locNameLen;
    while ((locNameLen = uloc_getParent(parentLocale, parentLocale,
                                        ULOC_FULLNAME_CAPACITY, &status)) >= 0){
        // look for pattern for srcPluralCount in locale tree
        UResourceBundle *rb, *unitsRes, *countsToPatternRB;
        rb = ures_open(NULL, parentLocale, &status);
        unitsRes = ures_getByKey(rb, key, NULL, &status);
        const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status);
        countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status);
        const UChar* pattern;
        int32_t      ptLength;
        pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPluralCount, &ptLength, &status);
        if (U_SUCCESS(status)) {
            //found
            MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err);
            if (U_SUCCESS(err)) {
                if (fNumberFormat != NULL) {
                    messageFormat->setFormat(0, *fNumberFormat);
                }
                MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
                if (formatters == NULL) {
                    formatters = (MessageFormat**)uprv_malloc(kTotal*sizeof(MessageFormat*));
                    formatters[kFull] = NULL;
                    formatters[kAbbreviate] = NULL;
                    countToPatterns->put(srcPluralCount, formatters, err);
                    if (U_FAILURE(err)) {
                        uprv_free(formatters);
                        delete messageFormat;
                    }
                } 
                if (U_SUCCESS(err)) {
                    //delete formatters[style];
                    formatters[style] = messageFormat;
                }
            } else {
                delete messageFormat;
            }
            ures_close(countsToPatternRB);
            ures_close(unitsRes);
            ures_close(rb);
            return;
        }
        ures_close(countsToPatternRB);
        ures_close(unitsRes);
        ures_close(rb);
        if ( locNameLen ==0 ) {
            break;
        }
    }
    // if not found the pattern for this plural count at all,
    // fall-back to plural count "other"
    if ( uprv_strcmp(searchPluralCount, gPluralCountOther) == 0 ) {
        // set default fall back the same as the resource in root
        MessageFormat* messageFormat = NULL;
        if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_SECOND, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MINUTE ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MINUTE, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_HOUR ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_HOUR, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_WEEK, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_DAY, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MONTH, fLocale, err);
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) {
            messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_YEAR, fLocale, err);
        }
        if (U_SUCCESS(err)) {
            if (fNumberFormat != NULL && messageFormat != NULL) {
                messageFormat->setFormat(0, *fNumberFormat);
            }
            MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
            if (formatters == NULL) {
                //formatters = new MessageFormat*[kTotal];
                formatters = (MessageFormat**)uprv_malloc(2*sizeof(MessageFormat*));
                formatters[kFull] = NULL;
                formatters[kAbbreviate] = NULL;
                countToPatterns->put(srcPluralCount, formatters, err);
                if (U_FAILURE(err)) {
                    uprv_free(formatters);
                    delete messageFormat;
                }
            }
            if (U_SUCCESS(err)) {
                //delete formatters[style];
                formatters[style] = messageFormat;
            }
        } else {
            delete messageFormat;
        }
    } else {
        // fall back to rule "other", and search in parents
        searchInLocaleChain(style, key, srcTimeUnitField, srcPluralCount, 
                            gPluralCountOther, countToPatterns, err);
    }
}

void 
TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
    if (U_SUCCESS(status) && fLocale != locale) {
        fLocale = locale;
        setup(status);
    }
}


void 
TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
    if (U_FAILURE(status) || (fNumberFormat && format == *fNumberFormat)) {
        return;
    }
    delete fNumberFormat;
    fNumberFormat = (NumberFormat*)format.clone();
    // reset the number formatter in the fTimeUnitToCountToPatterns map
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        int32_t pos = -1;
        const UHashElement* elem = NULL;
        while ((elem = fTimeUnitToCountToPatterns[i]->nextElement(pos)) != NULL){
            const UHashTok keyTok = elem->value;
            MessageFormat** pattern = (MessageFormat**)keyTok.pointer;
            pattern[kFull]->setFormat(0, format);
            pattern[kAbbreviate]->setFormat(0, format);
        }
    }
}


void
TimeUnitFormat::deleteHash(Hashtable* htable) {
    int32_t pos = -1;
    const UHashElement* element = NULL;
    if ( htable ) {
        while ( (element = htable->nextElement(pos)) != NULL ) {
            const UHashTok valueTok = element->value;
            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
            delete value[kFull];
            delete value[kAbbreviate];
            //delete[] value;
            uprv_free(value);
        }
    }
    delete htable;
}


void
TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status) {
    if ( U_FAILURE(status) ) {
        return;
    }
    int32_t pos = -1;
    const UHashElement* element = NULL;
    if ( source ) {
        while ( (element = source->nextElement(pos)) != NULL ) {
            const UHashTok keyTok = element->key;
            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
            const UHashTok valueTok = element->value;
            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
            MessageFormat** newVal = (MessageFormat**)uprv_malloc(kTotal*sizeof(MessageFormat*));
            newVal[0] = (MessageFormat*)value[0]->clone();
            newVal[1] = (MessageFormat*)value[1]->clone();
            target->put(UnicodeString(*key), newVal, status);
            if ( U_FAILURE(status) ) {
                delete newVal[0];
                delete newVal[1];
                uprv_free(newVal);
                return;
            }
        }
    }
}


U_CDECL_BEGIN 

/**
 * set hash table value comparator
 *
 * @param val1  one value in comparison
 * @param val2  the other value in comparison
 * @return      TRUE if 2 values are the same, FALSE otherwise
 */
static UBool U_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2);

static UBool 
U_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2) {
    const MessageFormat** pattern1 = (const MessageFormat**)val1.pointer;
    const MessageFormat** pattern2 = (const MessageFormat**)val2.pointer;
    return *pattern1[0] == *pattern2[0] && *pattern1[1] == *pattern2[1];
}

U_CDECL_END


Hashtable*
TimeUnitFormat::initHash(UErrorCode& status) {
    if ( U_FAILURE(status) ) {
        return NULL;
    }
    Hashtable* hTable;
    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    hTable->setValueComparator(tmutfmtHashTableValueComparator);
    return hTable;
}


const char*
TimeUnitFormat::getTimeUnitName(TimeUnit::UTimeUnitFields unitField, 
                                UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    switch (unitField) {
      case TimeUnit::UTIMEUNIT_YEAR:
        return gTimeUnitYear;
      case TimeUnit::UTIMEUNIT_MONTH:
        return gTimeUnitMonth;
      case TimeUnit::UTIMEUNIT_DAY:
        return gTimeUnitDay;
      case TimeUnit::UTIMEUNIT_WEEK:
        return gTimeUnitWeek;
      case TimeUnit::UTIMEUNIT_HOUR:
        return gTimeUnitHour;
      case TimeUnit::UTIMEUNIT_MINUTE:
        return gTimeUnitMinute;
      case TimeUnit::UTIMEUNIT_SECOND:
        return gTimeUnitSecond;
      default:
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }
}

U_NAMESPACE_END

#endif
