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

#include "utypeinfo.h"  // for 'typeid' to work

#include "unicode/tmutfmt.h"

#if !UCONFIG_NO_FORMATTING

#include "uvector.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "hash.h"
#include "uresimp.h"
#include "unicode/msgfmt.h"
#include "uassert.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(), UTMUTFMT_FULL_STYLE, status);
}


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


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


TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
:   MeasureFormat(other),
    fNumberFormat(NULL),
    fPluralRules(NULL),
    fStyle(UTMUTFMT_FULL_STYLE)
{
    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 (UTimeUnitFormatStyle style = UTMUTFMT_FULL_STYLE; style < UTMUTFMT_FORMAT_STYLE_COUNT;
                 style = (UTimeUnitFormatStyle)(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 (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
            resultNumber = 0;
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
            resultNumber = 1;
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
            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, UTimeUnitFormatStyle style, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    if (style < UTMUTFMT_FULL_STYLE || style > UTMUTFMT_ABBREVIATED_STYLE) {
        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);

    UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
    StringEnumeration* keywords = fPluralRules->getKeywords(err);
    if (U_FAILURE(err)) {
        return;
    }
    UnicodeString* pluralCount;
    while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
      pluralCounts.addElement(pluralCount, err);
    }
    readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
    checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
    readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCounts, err);
    checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
    delete keywords;
}


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(UTimeUnitFormatStyle style, const char* key,
                                      const UVector& pluralCounts, 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 char*  pluralCount;
            for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) {
                // resource of count to pattern
                UnicodeString pattern =
                    ures_getNextUnicodeString(countsToPatternRB, &pluralCount, &status);
                if (U_FAILURE(status)) {
                    continue;
                }
                UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
                if (!pluralCounts.contains(&pluralCountUniStr)) {
                  continue;
                }
                MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err);
                if ( U_SUCCESS(err) ) {
                  if (fNumberFormat != NULL) {
                    messageFormat->setFormat(0, *fNumberFormat);
                  }
                  MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr);
                  if (formatters == NULL) {
                    formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
                    formatters[UTMUTFMT_FULL_STYLE] = NULL;
                    formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
                    countToPatterns->put(pluralCountUniStr, 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(UTimeUnitFormatStyle 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 UnicodeString* pluralCount;
        while ((pluralCount = keywords->snext(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
                        const char* localeName = fLocale.getName();
                        CharString pluralCountChars;
                        pluralCountChars.appendInvariantChars(*pluralCount, err);
                        searchInLocaleChain(style, key, localeName,
                                            (TimeUnit::UTimeUnitFields)i, 
                                            *pluralCount, pluralCountChars.data(), 
                                            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(UTimeUnitFormatStyle style, const char* key, const char* localeName,
                                TimeUnit::UTimeUnitFields srcTimeUnitField,
                                const UnicodeString& srcPluralCount,
                                const char* searchPluralCount, 
                                Hashtable* countToPatterns,
                                UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    UErrorCode status = U_ZERO_ERROR;
    char parentLocale[ULOC_FULLNAME_CAPACITY];
    uprv_strcpy(parentLocale, localeName);
    int32_t locNameLen;
    U_ASSERT(countToPatterns != NULL);
    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(UnicodeString(TRUE, pattern, ptLength), 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(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
                    formatters[UTMUTFMT_FULL_STYLE] = NULL;
                    formatters[UTMUTFMT_ABBREVIATED_STYLE] = 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);
        status = U_ZERO_ERROR;
        if ( locNameLen ==0 ) {
            break;
        }
    }

    // if no unitsShort resource was found even after fallback to root locale
    // then search the units resource fallback from the current level to root
    if ( locNameLen == 0 && uprv_strcmp(key, gShortUnitsTag) == 0) {
#ifdef TMUTFMT_DEBUG
        std::cout << "loop into searchInLocaleChain since Short-Long-Alternative \n";
#endif
        char pLocale[ULOC_FULLNAME_CAPACITY];
        uprv_strcpy(pLocale, localeName);
        // Add an underscore at the tail of locale name,
        // so that searchInLocaleChain will check the current locale before falling back
        uprv_strcat(pLocale, "_");
        searchInLocaleChain(style, gUnitsTag, pLocale, srcTimeUnitField, srcPluralCount,
                             searchPluralCount, countToPatterns, err);
        MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
        if (formatters != NULL && formatters[style] != NULL) {
            return;
        }
    }

    // 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;
        const UChar *pattern = NULL;
        if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) {
            pattern = DEFAULT_PATTERN_FOR_SECOND;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MINUTE ) {
            pattern = DEFAULT_PATTERN_FOR_MINUTE;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_HOUR ) {
            pattern = DEFAULT_PATTERN_FOR_HOUR;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) {
            pattern = DEFAULT_PATTERN_FOR_WEEK;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) {
            pattern = DEFAULT_PATTERN_FOR_DAY;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) {
            pattern = DEFAULT_PATTERN_FOR_MONTH;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) {
            pattern = DEFAULT_PATTERN_FOR_YEAR;
        }
        if (pattern != NULL) {
            messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), 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 = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
                formatters[UTMUTFMT_FULL_STYLE] = NULL;
                formatters[UTMUTFMT_ABBREVIATED_STYLE] = 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, localeName, 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[UTMUTFMT_FULL_STYLE]->setFormat(0, format);
            pattern[UTMUTFMT_ABBREVIATED_STYLE]->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[UTMUTFMT_FULL_STYLE];
            delete value[UTMUTFMT_ABBREVIATED_STYLE];
            //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(UTMUTFMT_FORMAT_STYLE_COUNT*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;
    }
    if ( U_FAILURE(status) ) {
        delete hTable; 
        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
