/*
*******************************************************************************
* Copyright (C) 2007-2008, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/
#ifndef ZSTRFMT_H
#define ZSTRFMT_H

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/unistr.h"
#include "unicode/calendar.h"
#include "hash.h"
#include "uvector.h"

U_NAMESPACE_BEGIN

/*
 * Character node used by TextTrieMap
 */
class CharacterNode : public UMemory {
public:
    CharacterNode(UChar32 c, UErrorCode &status);
    virtual ~CharacterNode();

    inline UChar32 getCharacter(void) const;
    inline const UVector* getValues(void) const;
    inline const UVector* getChildNodes(void) const;

    void addValue(void *value, UErrorCode &status);
    CharacterNode* addChildNode(UChar32 c, UErrorCode &status);
    CharacterNode* getChildNode(UChar32 c) const;

private:
    UVector fChildren;
    UVector fValues;
    UChar32 fCharacter;
};

inline UChar32 CharacterNode::getCharacter(void) const {
    return fCharacter;
}

inline const UVector* CharacterNode::getValues(void) const {
    return &fValues;
}

inline const UVector* CharacterNode::getChildNodes(void) const {
    return &fChildren;
}

/*
 * Search result handler callback interface used by TextTrieMap search.
 */
class TextTrieMapSearchResultHandler : public UMemory {
public:
    virtual UBool handleMatch(int32_t matchLength,
        const UVector *values, UErrorCode& status) = 0;
};

/**
 * TextTrieMap is a trie implementation for supporting
 * fast prefix match for the string key.
 */
class TextTrieMap : public UMemory {
public:
    TextTrieMap(UBool ignoreCase);
    virtual ~TextTrieMap();

    void put(const UnicodeString &key, void *value, UErrorCode &status);
    void search(const UnicodeString &text, int32_t start,
        TextTrieMapSearchResultHandler *handler, UErrorCode& status) const;
    inline int32_t isEmpty() const;

private:
    UBool           fIgnoreCase;
    CharacterNode   *fRoot;

    void search(CharacterNode *node, const UnicodeString &text, int32_t start,
        int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const;
};

inline UChar32 TextTrieMap::isEmpty(void) const {
    return fRoot == NULL;
}

// Name types, these bit flag are used for zone string lookup
enum TimeZoneTranslationType {
    LOCATION        = 0x0001,
    GENERIC_LONG    = 0x0002,
    GENERIC_SHORT   = 0x0004,
    STANDARD_LONG   = 0x0008,
    STANDARD_SHORT  = 0x0010,
    DAYLIGHT_LONG   = 0x0020,
    DAYLIGHT_SHORT  = 0x0040
};

// Name type index, these constants are used for index in the zone strings array.
enum TimeZoneTranslationTypeIndex {
    ZSIDX_LOCATION = 0,
    ZSIDX_LONG_STANDARD,
    ZSIDX_SHORT_STANDARD,
    ZSIDX_LONG_DAYLIGHT,
    ZSIDX_SHORT_DAYLIGHT,
    ZSIDX_LONG_GENERIC,
    ZSIDX_SHORT_GENERIC,

    ZSIDX_COUNT
};

class MessageFormat;

/*
 * ZoneStringInfo is a class holding a localized zone string
 * information.
 */
class ZoneStringInfo : public UMemory {
public:
    virtual ~ZoneStringInfo();

    inline UnicodeString& getID(UnicodeString &result) const;
    inline UnicodeString& getString(UnicodeString &result) const;
    inline UBool isStandard(void) const;
    inline UBool isDaylight(void) const;
    inline UBool isGeneric(void) const;

private:
    friend class ZoneStringFormat;
    friend class ZoneStringSearchResultHandler;

    ZoneStringInfo(const UnicodeString &id, const UnicodeString &str, TimeZoneTranslationType type);

    UnicodeString   fId;
    UnicodeString   fStr;
    TimeZoneTranslationType fType;
};

inline UnicodeString& ZoneStringInfo::getID(UnicodeString &result) const {
    return result.setTo(fId);
}

inline UnicodeString& ZoneStringInfo::getString(UnicodeString &result) const {
    return result.setTo(fStr);
}

inline UBool ZoneStringInfo::isStandard(void) const {
    return (fType == STANDARD_LONG || fType == STANDARD_SHORT);
}

inline UBool ZoneStringInfo::isDaylight(void) const {
    return (fType == DAYLIGHT_LONG || fType == DAYLIGHT_SHORT);
}

inline UBool ZoneStringInfo::isGeneric(void) const {
    return (fType == LOCATION || fType == GENERIC_LONG || fType == GENERIC_SHORT);
}

class SafeZoneStringFormatPtr;

class ZoneStringFormat : public UMemory {
public:
    ZoneStringFormat(const UnicodeString* const* strings, int32_t rowCount, int32_t columnCount, UErrorCode &status);
    ZoneStringFormat(const Locale& locale, UErrorCode &status);
    virtual ~ZoneStringFormat();

    static SafeZoneStringFormatPtr* getZoneStringFormat(const Locale& locale, UErrorCode &status);

    /*
     * Create a snapshot of old zone strings array for the given date
     */
    UnicodeString** createZoneStringsArray(UDate date, int32_t &rowCount, int32_t &colCount, UErrorCode &status) const;

    const UnicodeString** getZoneStrings(int32_t &rowCount, int32_t &columnCount) const;

    UnicodeString& getSpecificLongString(const Calendar &cal,
        UnicodeString &result, UErrorCode &status) const;

    UnicodeString& getSpecificShortString(const Calendar &cal,
        UBool commonlyUsedOnly, UnicodeString &result, UErrorCode &status) const;

    UnicodeString& getGenericLongString(const Calendar &cal,
        UnicodeString &result, UErrorCode &status) const;

    UnicodeString& getGenericShortString(const Calendar &cal,
        UBool commonlyUsedOnly, UnicodeString &result, UErrorCode &status) const;

    UnicodeString& getGenericLocationString(const Calendar &cal,
        UnicodeString &result, UErrorCode &status) const;

    const ZoneStringInfo* findSpecificLong(const UnicodeString &text, int32_t start,
        int32_t &matchLength, UErrorCode &status) const;
    const ZoneStringInfo* findSpecificShort(const UnicodeString &text, int32_t start,
        int32_t &matchLength, UErrorCode &status) const;
    const ZoneStringInfo* findGenericLong(const UnicodeString &text, int32_t start,
        int32_t &matchLength, UErrorCode &status) const;
    const ZoneStringInfo* findGenericShort(const UnicodeString &text, int32_t start,
        int32_t &matchLength, UErrorCode &status) const;
    const ZoneStringInfo* findGenericLocation(const UnicodeString &text, int32_t start,
        int32_t &matchLength, UErrorCode &status) const;

    // Following APIs are not used by SimpleDateFormat, but public for testing purpose
    inline UnicodeString& getLongStandard(const UnicodeString &tzid, UDate date,
        UnicodeString &result) const;
    inline UnicodeString& getLongDaylight(const UnicodeString &tzid, UDate date,
        UnicodeString &result) const;
    inline UnicodeString& getLongGenericNonLocation(const UnicodeString &tzid, UDate date,
        UnicodeString &result) const;
    inline UnicodeString& getLongGenericPartialLocation(const UnicodeString &tzid, UDate date,
        UnicodeString &result) const;
    inline UnicodeString& getShortStandard(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
        UnicodeString &result) const;
    inline UnicodeString& getShortDaylight(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
        UnicodeString &result) const;
    inline UnicodeString& getShortGenericNonLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
        UnicodeString &result) const;
    inline UnicodeString& getShortGenericPartialLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
        UnicodeString &result) const;
    inline UnicodeString& getGenericLocation(const UnicodeString &tzid, UnicodeString &result) const;

private:
    Locale      fLocale;
    Hashtable   fTzidToStrings;
    Hashtable   fMzidToStrings;
    TextTrieMap fZoneStringsTrie;

    /*
     * Private method to get a zone string except generic partial location types.
     */
    UnicodeString& getString(const UnicodeString &tzid, TimeZoneTranslationTypeIndex typeIdx, UDate date,
        UBool commonlyUsedOnly, UnicodeString& result) const;

    /*
     * Private method to get a generic string, with fallback logic involved,
     * that is,
     * 
     * 1. If a generic non-location string is avaiable for the zone, return it.
     * 2. If a generic non-location string is associated with a metazone and 
     *    the zone never use daylight time around the given date, use the standard
     *    string (if available).
     *    
     *    Note: In CLDR1.5.1, the same localization is used for generic and standard.
     *    In this case, we do not use the standard string and do the rest.
     *    
     * 3. If a generic non-location string is associated with a metazone and
     *    the offset at the given time is different from the preferred zone for the
     *    current locale, then return the generic partial location string (if avaiable)
     * 4. If a generic non-location string is not available, use generic location
     *    string.
     */
    UnicodeString& getGenericString(const Calendar &cal, UBool isShort, UBool commonlyUsedOnly,
        UnicodeString &result, UErrorCode &status) const;

    /*
     * Private method to get a generic partial location string
     */
    UnicodeString& getGenericPartialLocationString(const UnicodeString &tzid, UBool isShort,
        UDate date, UBool commonlyUsedOnly, UnicodeString &result) const;

    /*
     * Find a prefix matching time zone for the given zone string types.
     * @param text The text contains a time zone string
     * @param start The start index within the text
     * @param types The bit mask representing a set of requested types
     * @param matchLength Receives the match length
     * @param status
     * @return If any zone string matched for the requested types, returns a
     * ZoneStringInfo for the longest match.  If no matches are found for
     * the requested types, returns a ZoneStringInfo for the longest match
     * for any other types.  If nothing matches at all, returns null.
     */
    const ZoneStringInfo* find(const UnicodeString &text, int32_t start, int32_t types,
        int32_t &matchLength, UErrorCode &status) const;

    UnicodeString& getRegion(UnicodeString &region) const;

    static MessageFormat* getFallbackFormat(const Locale &locale, UErrorCode &status);
    static MessageFormat* getRegionFormat(const Locale &locale, UErrorCode &status);
    static const UChar* getZoneStringFromBundle(const UResourceBundle *zoneitem, const char *key);
    static UBool isCommonlyUsed(const UResourceBundle *zoneitem);
    static UnicodeString& getLocalizedCountry(const UnicodeString &countryCode, const Locale &locale,
        UnicodeString &displayCountry);
};

inline UnicodeString&
ZoneStringFormat::getLongStandard(const UnicodeString &tzid, UDate date,
                                  UnicodeString &result) const {
    return getString(tzid, ZSIDX_LONG_STANDARD, date, FALSE /* not used */, result);
}

inline UnicodeString&
ZoneStringFormat::getLongDaylight(const UnicodeString &tzid, UDate date,
                                  UnicodeString &result) const {
    return getString(tzid, ZSIDX_LONG_DAYLIGHT, date, FALSE /* not used */, result);
}

inline UnicodeString&
ZoneStringFormat::getLongGenericNonLocation(const UnicodeString &tzid, UDate date,
                                            UnicodeString &result) const {
    return getString(tzid, ZSIDX_LONG_GENERIC, date, FALSE /* not used */, result);
}

inline UnicodeString&
ZoneStringFormat::getLongGenericPartialLocation(const UnicodeString &tzid, UDate date,
                                                UnicodeString &result) const {
    return getGenericPartialLocationString(tzid, FALSE, date, FALSE /* not used */, result);
}

inline UnicodeString&
ZoneStringFormat::getShortStandard(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
                                   UnicodeString &result) const {
    return getString(tzid, ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly, result);
}

inline UnicodeString&
ZoneStringFormat::getShortDaylight(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
                                   UnicodeString &result) const {
    return getString(tzid, ZSIDX_SHORT_DAYLIGHT, date, commonlyUsedOnly, result);
}

inline UnicodeString&
ZoneStringFormat::getShortGenericNonLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
                                             UnicodeString &result) const {
    return getString(tzid, ZSIDX_SHORT_GENERIC, date, commonlyUsedOnly, result);
}

inline UnicodeString&
ZoneStringFormat::getShortGenericPartialLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
                                                 UnicodeString &result) const {
    return getGenericPartialLocationString(tzid, TRUE, date, commonlyUsedOnly, result);
}

inline UnicodeString&
ZoneStringFormat::getGenericLocation(const UnicodeString &tzid, UnicodeString &result) const {
    return getString(tzid, ZSIDX_LOCATION, 0 /*not used*/, FALSE /*not used*/, result);
}


/*
 * ZooneStrings is a container of localized zone strings used by ZoneStringFormat
 */
class ZoneStrings : public UMemory {
public:
    ZoneStrings(UnicodeString *strings, int32_t stringsCount, UBool commonlyUsed,
        UnicodeString **genericPartialLocationStrings, int32_t genericRowCount, int32_t genericColCount);
    virtual ~ZoneStrings();

    UnicodeString& getString(int32_t typeIdx, UnicodeString &result) const;
    inline UBool isShortFormatCommonlyUsed(void) const;
    UnicodeString& getGenericPartialLocationString(const UnicodeString &mzid, UBool isShort,
        UBool commonlyUsedOnly, UnicodeString &result) const;

private:
    UnicodeString   *fStrings;
    int32_t         fStringsCount;
    UBool           fIsCommonlyUsed;
    UnicodeString   **fGenericPartialLocationStrings;
    int32_t         fGenericPartialLocationRowCount;
    int32_t         fGenericPartialLocationColCount;
};

inline UBool
ZoneStrings::isShortFormatCommonlyUsed(void) const {
    return fIsCommonlyUsed;
}

/*
 * ZoneStringSearchResultHandler is an implementation of
 * TextTrieMapSearchHandler.  This class is used by ZoneStringFormat
 * for collecting search results for localized zone strings.
 */
class ZoneStringSearchResultHandler : public TextTrieMapSearchResultHandler {
public:
    ZoneStringSearchResultHandler(UErrorCode &status);
    virtual ~ZoneStringSearchResultHandler();

    virtual UBool handleMatch(int32_t matchLength, const UVector *values, UErrorCode &status);
    int32_t countMatches(void);
    const ZoneStringInfo* getMatch(int32_t index, int32_t &matchLength);
    void clear(void);

private:
    UVector fResults;
    int32_t fMatchLen[ZSIDX_COUNT];
};


/*
 * ZoneStringFormat cache implementation
 */
class ZSFCacheEntry : public UMemory {
public:
    ~ZSFCacheEntry();

    void delRef(void);
    const ZoneStringFormat* getZoneStringFormat(void);

private:
    friend class ZSFCache;

    ZSFCacheEntry(const Locale &locale, ZoneStringFormat *zsf, ZSFCacheEntry *next);

    Locale              fLocale;
    ZoneStringFormat    *fZoneStringFormat;
    ZSFCacheEntry       *fNext;
    int32_t             fRefCount;
};

class SafeZoneStringFormatPtr : public UMemory {
public:
    ~SafeZoneStringFormatPtr();
    const ZoneStringFormat* get() const;

private:
    friend class ZSFCache;

    SafeZoneStringFormatPtr(ZSFCacheEntry *cacheEntry);

    ZSFCacheEntry   *fCacheEntry;
};

class ZSFCache : public UMemory {
public:
    ZSFCache(int32_t capacity);
    ~ZSFCache();

    SafeZoneStringFormatPtr* get(const Locale &locale, UErrorCode &status);

private:
    int32_t         fCapacity;
    ZSFCacheEntry   *fFirst;
};

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif // ZSTRFMT_H
