/*
*******************************************************************************
* Copyright (C) 2007-2009, 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 "uhash.h"
#include "uvector.h"

U_NAMESPACE_BEGIN

/*
 * Character node used by TextTrieMap
 */
struct CharacterNode {
    // No constructor or destructor.
    // We malloc and free an uninitalized array of CharacterNode objects
    // and clear and delete them ourselves.

    void clear();
    void deleteValues();

    void addValue(void *value, UErrorCode &status);
    inline UBool hasValues() const;
    inline int32_t countValues() const;
    inline const void *getValue(int32_t index) const;

    void     *fValues;      // Union of one single value vs. UVector of values.
    UChar    fCharacter;    // UTF-16 code unit.
    uint16_t fFirstChild;   // 0 if no children.
    uint16_t fNextSibling;  // 0 terminates the list.
    UBool    fHasValuesVector;
    UBool    fPadding;

    // No value:   fValues == NULL               and  fHasValuesVector == FALSE
    // One value:  fValues == value              and  fHasValuesVector == FALSE
    // >=2 values: fValues == UVector of values  and  fHasValuesVector == TRUE
};

inline UBool CharacterNode::hasValues() const {
    return (UBool)(fValues != NULL);
}

inline int32_t CharacterNode::countValues() const {
    return
        fValues == NULL ? 0 :
        !fHasValuesVector ? 1 :
        ((const UVector *)fValues)->size();
}

inline const void *CharacterNode::getValue(int32_t index) const {
    if (!fHasValuesVector) {
        return fValues;  // Assume index == 0.
    } else {
        return ((const UVector *)fValues)->elementAt(index);
    }
}

/*
 * Search result handler callback interface used by TextTrieMap search.
 */
class TextTrieMapSearchResultHandler : public UMemory {
public:
    virtual UBool handleMatch(int32_t matchLength,
                              const CharacterNode *node, UErrorCode& status) = 0;
    virtual ~TextTrieMapSearchResultHandler(); //added to avoid warning
};


/*
 * ZSFStringPool   Pool of (UChar *) strings.  Provides for sharing of repeated
 *                 strings within ZoneStringFormats.
 */
class ZSFStringPoolChunk;
class ZSFStringPool: public UMemory {
  public:
    ZSFStringPool(UErrorCode &status);
    ~ZSFStringPool();

    /* Get the pooled string that is equal to the supplied string s.
     * Copy the string into the pool if it is not already present.
     *
     * Life time of the returned string is that of the pool.
     */
    const UChar *get(const UChar *s, UErrorCode &status);

    /* Get the pooled string that is equal to the supplied string s.
     * Copy the string into the pool if it is not already present.
     */
    const UChar *get(const UnicodeString &s, UErrorCode &status);

    /* Adopt a string into the pool, without copying it.
     * Used for strings from resource bundles, which will persist without copying.
     */
    const UChar *adopt(const UChar *s, UErrorCode &status);

    /* Freeze the string pool.  Discards the hash table that is used
     * for looking up a string.  All pointers to pooled strings remain valid.
     */
    void freeze();

  private:
    ZSFStringPoolChunk   *fChunks;
    UHashtable           *fHash;
};


/**
 * 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, ZSFStringPool &sp, UErrorCode &status);
    void search(const UnicodeString &text, int32_t start,
        TextTrieMapSearchResultHandler *handler, UErrorCode& status) const;
    int32_t isEmpty() const;

private:
    UBool           fIgnoreCase;
    CharacterNode   *fNodes;
    int32_t         fNodesCapacity;
    int32_t         fNodesCount;

    UVector         *fLazyContents;
    UBool           fIsEmpty;      

    UBool growNodes();
    CharacterNode* addChildNode(CharacterNode *parent, UChar c, UErrorCode &status);
    CharacterNode* getChildNode(CharacterNode *parent, UChar c) const;

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


// 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, ZSFStringPool &sp, UErrorCode &status);

    const UChar   *fId;
    const UChar   *fStr;
    TimeZoneTranslationType fType;
};

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

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

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();

    /* Gets zone string format from cache if available, create it if not cached. */
    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;

    /* TODO:  There is no implementation for this function.  Delete declaration? */
    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;
    UHashtable      *fTzidToStrings;
    UHashtable      *fMzidToStrings;

    TextTrieMap      fZoneStringsTrie;
    ZSFStringPool    fStringPool;

    UResourceBundle *fZoneStringsArray;
    UResourceBundle *fMetazoneItem;
    UResourceBundle *fZoneItem;

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


/*
 * ZoneStrings 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,
                ZSFStringPool &sp,
                UErrorCode    &status);
    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:
    const UChar   **fStrings;
    int32_t         fStringsCount;
    UBool           fIsCommonlyUsed;
    const UChar * **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 CharacterNode *node, 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
