/*
 *******************************************************************************
 * Copyright (C) 2007-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;

import com.ibm.icu.impl.ZoneMeta.OlsonToMetaMappingEntry;
import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.util.BasicTimeZone;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.TimeZoneTransition;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/**
 * @author yoshito
 *
 */
public class ZoneStringFormat {

    private static final int millisPerHour = 60 * 60 * 1000;
    private static final int millisPerMinute = 60 * 1000;
    private static final int millisPerSecond = 1000;
    private static final String DEFAULT_DIGIT_STRING = "0123456789";
    private static final String DEFAULT_GMT_FORMAT = "GMT{0}";
    private static final String DEFAULT_HOUR_FORMAT = "+HH:mm;-HH:mm";
    
    /**
     * Constructs a ZoneStringFormat by zone strings array.
     * The internal structure of zoneStrings is compatible with
     * the one used by getZoneStrings/setZoneStrings in DateFormatSymbols.
     * 
     * @param zoneStrings zone strings
     */
    public ZoneStringFormat(String[][] zoneStrings) {
        tzidToStrings = new HashMap<String, ZoneStrings>();
        zoneStringsTrie = new TextTrieMap<ZoneStringInfo>(true);
        for (int i = 0; i < zoneStrings.length; i++) {
            String tzid = zoneStrings[i][0];
            String[] names = new String[ZSIDX_MAX];
            for (int j = 1; j < zoneStrings[i].length; j++) {
                if (zoneStrings[i][j] != null) {
                    int typeIdx = getNameTypeIndex(j);
                    if (typeIdx != -1) {
                        names[typeIdx] = zoneStrings[i][j];

                        // Put the name into the trie
                        int type = getNameType(typeIdx);
                        ZoneStringInfo zsinfo = new ZoneStringInfo(tzid, zoneStrings[i][j], type);
                        zoneStringsTrie.put(zoneStrings[i][j], zsinfo);
                    }
                    
                }
            }
            ZoneStrings zstrings = new ZoneStrings(names, true, null);
            tzidToStrings.put(tzid, zstrings);
        }
        isFullyLoaded = true;
    }

    /**
     * Gets an instance of ZoneStringFormat for the specified locale
     * @param locale the locale
     * @return An instance of ZoneStringFormat for the locale
     */
    public static ZoneStringFormat getInstance(ULocale locale) {
        ZoneStringFormat zzf = ZSFORMAT_CACHE.get(locale);
        if (zzf == null) {
            zzf = new ZoneStringFormat(locale);
            ZSFORMAT_CACHE.put(locale, zzf);
        }
        return zzf;
    }

    public String[][] getZoneStrings() {
        return getZoneStrings(System.currentTimeMillis());
    }

    private boolean inDaylightTime(TimeZone tz, long date) {
        int[] offsets = {0,0};
        tz.getOffset(date, false, offsets);
        return (offsets[1] != 0);
    }
    // APIs used by SimpleDateFormat to get a zone string
    public String getSpecificLongString(TimeZone tz, long date) {
        
        return getString(tz.getID(), inDaylightTime(tz,date) ? ZSIDX_LONG_DAYLIGHT : ZSIDX_LONG_STANDARD, date, false /* not used */);
    }

    public String getSpecificShortString(TimeZone tz, long date, boolean commonlyUsedOnly) {
        return getString(tz.getID(), inDaylightTime(tz,date) ? ZSIDX_SHORT_DAYLIGHT : ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly);
    }

    public String getGenericLongString(TimeZone tz, long date) {
        return getGenericString(tz, date, false /* long */, false /* not used */);
    }

    public String getGenericShortString(TimeZone tz, long date, boolean commonlyUsedOnly) {
        return getGenericString(tz, date, true /* long */, commonlyUsedOnly);
    }

    public String getGenericLocationString(TimeZone tz, long date) {
        return getString(tz.getID(), ZSIDX_LOCATION, date, false /* not used */);
    }
    public String getLongGMTString( TimeZone tz, long date, boolean daylight ) {
        int offset;
        if (daylight && tz.useDaylightTime()) {
            offset = tz.getRawOffset() + tz.getDSTSavings();
        } else {
            offset = tz.getRawOffset();
        }
        return getLongGMTString(tz,date,offset);
    }
    
    public String getLongGMTString( TimeZone tz, long date ) {
        return getLongGMTString(tz,date,tz.getOffset(date));
    }
    
    public String getLongGMTString( TimeZone tz, long date, int offsetIn) {
        // Note: This code is optimized for performance, but as a result, it makes assumptions
        // about the content and structure of the underlying CLDR data.
        // Specifically, it assumes that the H or HH in the pattern occurs before the mm,
        // and that there are no quoted literals in the pattern that contain H or m.
        // As of CLDR 1.8.1, all of the data conforms to these rules, so we should probably be OK.
        
        StringBuffer buf = new StringBuffer();
        int offset = offsetIn;
        int hfPosition = 0;
        if (offset < 0) {
            offset = -offset;
            hfPosition = 1;
        }
            
        int offsetH = offset / millisPerHour;
        offset = offset % millisPerHour;
        int offsetM = offset / millisPerMinute;
        offset = offset % millisPerMinute;
        int offsetS = offset / millisPerSecond;

        int subPosition = gmtFormat.indexOf("{0}");
        for ( int i = 0 ; i < gmtFormat.length(); i++ ) {
            if ( i == subPosition ) {
                String hmString = hourFormats[hfPosition];
                for ( int j = 0 ; j < hmString.length() ; j++) {
                    switch (hmString.charAt(j)) {
                    case 'H':
                        if ( j+1 < hmString.length() && hmString.charAt(j+1) == 'H' ) {
                            j++;
                            if (offsetH < 10) {
                                buf.append(digitString.charAt(0));
                            }
                        }
                        if ( offsetH >= 10 ) {
                            buf.append(digitString.charAt(offsetH/10));
                        }
                        buf.append(digitString.charAt(offsetH%10));
                        break;
                    case 'm':
                        if ( j+1 < hmString.length() && hmString.charAt(j+1) == 'm' ) {
                            j++;
                        }
                        buf.append(digitString.charAt(offsetM/10));
                        buf.append(digitString.charAt(offsetM%10));
                        if ( offsetS > 0 ) {
                            int lastH = hmString.lastIndexOf('H');
                            int firstm = hmString.indexOf('m');
                            if ( lastH + 1 < firstm ) {
                                buf.append(hmString.substring(lastH+1,firstm));
                            }
                            buf.append(digitString.charAt(offsetS/10));
                            buf.append(digitString.charAt(offsetS%10));
                        }
                        break;
                    default:
                        buf.append(hmString.charAt(j));
                        break;
                    }
                }
                i += 3;
            } else {
                buf.append(gmtFormat.charAt(i));
            }
        }
        return buf.toString();
    }
    public String getShortGMTString( TimeZone tz, long date, boolean daylight ) {
        int offset;
        if (daylight && tz.useDaylightTime()) {
            offset = tz.getRawOffset() + tz.getDSTSavings();
        } else {
            offset = tz.getRawOffset();
        }
        return getShortGMTString(tz,date,offset);
    }
    
    public String getShortGMTString( TimeZone tz, long date ) {
        return getShortGMTString(tz,date,tz.getOffset(date));
    }
  
    public String getShortGMTString( TimeZone tz, long date, int offset ) {
        StringBuffer buf = new StringBuffer();
        // RFC822 format, must use ASCII digits
        int val = offset;
        char sign = '+';
        if (val < 0) {
            val = -val;
            sign = '-';
        }
        buf.append(sign);

        int offsetH = val / millisPerHour;
        val = val % millisPerHour;
        int offsetM = val / millisPerMinute;
        val = val % millisPerMinute;
        int offsetS = val / millisPerSecond;

        int num = 0, denom = 0;
        if (offsetS == 0) {
            val = offsetH*100 + offsetM; // HHmm
            num = val % 10000;
            denom = 1000;
        } else {
            val = offsetH*10000 + offsetM*100 + offsetS; // HHmmss
            num = val % 1000000;
            denom = 100000;
        }
        while (denom >= 1) {
            char digit = (char)((num / denom) + '0');
            buf.append(digit);
            num = num % denom;
            denom /= 10;
        }
        return buf.toString();
    }
    // APIs used by SimpleDateFormat to lookup a zone string
    public static class ZoneStringInfo {
        private String id;
        private String str;
        private int type;

        private ZoneStringInfo(String id, String str, int type) {
            this.id = id;
            this.str = str;
            this.type = type;
        }

        public String getID() {
            return id;
        }

        public String getString() {
            return str;
        }

        public boolean isStandard() {
            if ((type & STANDARD_LONG) != 0 || (type & STANDARD_SHORT) != 0) {
                return true;
            }
            return false;
        }

        public boolean isDaylight() {
            if ((type & DAYLIGHT_LONG) != 0 || (type & DAYLIGHT_SHORT) != 0) {
                return true;
            }
            return false;
        }

        public boolean isGeneric() {
            return !isStandard() && !isDaylight();
        }

        private int getType() {
            return type;
        }
    }

    public ZoneStringInfo findSpecificLong(String text, int start) {
        return find(text, start, STANDARD_LONG | DAYLIGHT_LONG);
    }
    
    public ZoneStringInfo findSpecificShort(String text, int start) {
        return find(text, start, STANDARD_SHORT | DAYLIGHT_SHORT);
    }

    public ZoneStringInfo findGenericLong(String text, int start) {
        return find(text, start, GENERIC_LONG | STANDARD_LONG | LOCATION);
    }
    
    public ZoneStringInfo findGenericShort(String text, int start) {
        return find(text, start, GENERIC_SHORT | STANDARD_SHORT | LOCATION);
    }

    public ZoneStringInfo findGenericLocation(String text, int start) {
        return find(text, start, LOCATION);
    }

    // Following APIs are not used by SimpleDateFormat, but public for testing purpose
    public String getLongStandard(String tzid, long date) {
        return getString(tzid, ZSIDX_LONG_STANDARD, date, false /* not used */);
    }

    public String getLongDaylight(String tzid, long date) {
        return getString(tzid, ZSIDX_LONG_DAYLIGHT, date, false /* not used */);
    }

    public String getLongGenericNonLocation(String tzid, long date) {
        return getString(tzid, ZSIDX_LONG_GENERIC, date, false /* not used */);
    }

    public String getLongGenericPartialLocation(String tzid, long date) {
        return getGenericPartialLocationString(tzid, false, date, false /* not used */);
    }

    public String getShortStandard(String tzid, long date, boolean commonlyUsedOnly) {
        return getString(tzid, ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly);
    }

    public String getShortDaylight(String tzid, long date, boolean commonlyUsedOnly) {
        return getString(tzid, ZSIDX_SHORT_DAYLIGHT, date, commonlyUsedOnly);
    }

    public String getShortGenericNonLocation(String tzid, long date, boolean commonlyUsedOnly) {
        return getString(tzid, ZSIDX_SHORT_GENERIC, date, commonlyUsedOnly);
    }

    public String getShortGenericPartialLocation(String tzid, long date, boolean commonlyUsedOnly) {
        return getGenericPartialLocationString(tzid, true, date, commonlyUsedOnly);
    }

    public String getGenericLocation(String tzid) {
        return getString(tzid, ZSIDX_LOCATION, 0L /* not used */, false /* not used */);
    }

    /**
     * Constructs a ZoneStringFormat by locale.  Because an instance of ZoneStringFormat
     * is read-only, only one instance for a locale is sufficient.  Thus, this
     * constructor is protected and only called from getInstance(ULocale) to
     * create one for a locale.
     * @param locale The locale
     */
    protected ZoneStringFormat(ULocale locale) {
        this.locale = locale;
        tzidToStrings = new HashMap<String, ZoneStrings>();
        mzidToStrings = new HashMap<String, ZoneStrings>();
        zoneStringsTrie = new TextTrieMap<ZoneStringInfo>(true);
        NumberingSystem ns = NumberingSystem.getInstance(locale);
        if (ns.isAlgorithmic()) {
            digitString = DEFAULT_DIGIT_STRING; // Using complex ns for GMT formatting doesn't make sense
        } else {
            digitString = ns.getDescription();
        }

        gmtFormat = null;
        String hourFormatString = null;
        try {
            ICUResourceBundle bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_ZONE_BASE_NAME, locale);
            gmtFormat = bundle.getStringWithFallback("zoneStrings/gmtFormat");
            hourFormatString = bundle.getStringWithFallback("zoneStrings/hourFormat");
        } catch (MissingResourceException e) {
        }

        if ( gmtFormat == null) {
            gmtFormat = DEFAULT_GMT_FORMAT;
        }
        if ( hourFormatString == null) {
            hourFormatString = DEFAULT_HOUR_FORMAT;
        }
        
        hourFormats = hourFormatString.split(";", 2);
    }

    // Load only a single zone
    private synchronized void loadZone(String id) {
        if (isFullyLoaded) {
            return;
        }
        String tzid = ZoneMeta.getCanonicalSystemID(id);
        if (tzid == null || tzidToStrings.containsKey(tzid)) {
            return;
        }

        ICUResourceBundle zoneStringsBundle = null;
        try {
            ICUResourceBundle bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_ZONE_BASE_NAME, locale);
            zoneStringsBundle = bundle.getWithFallback("zoneStrings");
        } catch (MissingResourceException e) {
            // If no locale bundles are available, zoneStringsBundle will be null.
            // We still want to go through the rest of zone strings initialization,
            // because generic location format is generated from tzid for the case.
            // The rest of code should work even zoneStrings is null.
        }

        String[] zstrarray = new String[ZSIDX_MAX];
        String[] mzstrarray = new String[ZSIDX_MAX];
        String[][] mzPartialLoc = new String[10][4]; // maximum 10 metazones per zone

        addSingleZone(tzid, zoneStringsBundle,
                getFallbackFormat(locale), getRegionFormat(locale),
                zstrarray, mzstrarray, mzPartialLoc);
    }

    // Loading all zone strings
    private synchronized void loadFull() {
        if (isFullyLoaded) {
            return;
        }
        ICUResourceBundle zoneStringsBundle = null;
        try {
            ICUResourceBundle bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_ZONE_BASE_NAME, locale);
            zoneStringsBundle = bundle.getWithFallback("zoneStrings");
        } catch (MissingResourceException e) {
            // If no locale bundles are available, zoneStringsBundle will be null.
            // We still want to go through the rest of zone strings initialization,
            // because generic location format is generated from tzid for the case.
            // The rest of code should work even zoneStrings is null.
        }

        String[] zoneIDs = TimeZone.getAvailableIDs();

        String[] zstrarray = new String[ZSIDX_MAX];
        String[] mzstrarray = new String[ZSIDX_MAX];
        String[][] mzPartialLoc = new String[10][4]; // maximum 10 metazones per zone

        for (int i = 0; i < zoneIDs.length; i++) {
            // Skip aliases
             String tzid = ZoneMeta.getCanonicalSystemID(zoneIDs[i]);
            if (tzid == null || !zoneIDs[i].equals(tzid)) {
                continue;
            }

            if (tzidToStrings.containsKey(tzid)) {
                continue;
            }

            addSingleZone(tzid, zoneStringsBundle,
                    getFallbackFormat(locale), getRegionFormat(locale),
                    zstrarray, mzstrarray, mzPartialLoc);
        }
        isFullyLoaded = true;
    }

    // This internal initialization code must be called in a synchronized block
    private void addSingleZone(String tzid, ICUResourceBundle zoneStringsBundle,
            MessageFormat fallbackFmt, MessageFormat regionFmt,
            String[] zstrarray, String[] mzstrarray, String[][] mzPartialLoc) {

        if (tzidToStrings.containsKey(tzid)) {
            return;
        }

        String zoneKey = tzid.replace('/', ':');
        zstrarray[ZSIDX_LONG_STANDARD] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_LONG_STANDARD);
        zstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_SHORT_STANDARD);
        zstrarray[ZSIDX_LONG_DAYLIGHT] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_LONG_DAYLIGHT);
        zstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_SHORT_DAYLIGHT);
        zstrarray[ZSIDX_LONG_GENERIC] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_LONG_GENERIC);
        zstrarray[ZSIDX_SHORT_GENERIC] = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_SHORT_GENERIC);

        // Compose location format string
        String countryCode = ZoneMeta.getCanonicalCountry(tzid);
        String country = null;
        String city = null;
        if (countryCode != null) {
            city = getZoneStringFromBundle(zoneStringsBundle, zoneKey, RESKEY_EXEMPLAR_CITY);
            if (city == null) {
                city = tzid.substring(tzid.lastIndexOf('/') + 1).replace('_', ' ');
            }
            country = getLocalizedCountry(countryCode, locale);
            if (ZoneMeta.getSingleCountry(tzid) != null) {
                // If the zone is only one zone in the country, do not add city
                zstrarray[ZSIDX_LOCATION] = regionFmt.format(new Object[] {country});
            } else {
                zstrarray[ZSIDX_LOCATION] = fallbackFmt.format(new Object[] {city, country});
            }
        } else {
            if (tzid.startsWith("Etc/")) {
                // "Etc/xxx" is not associated with a specific location, so localized
                // GMT format is always used as generic location format.
                zstrarray[ZSIDX_LOCATION] = null;
            } else {
                // When a new time zone ID, which is actually associated with a specific
                // location, is added in tzdata, but the current CLDR data does not have
                // the information yet, ICU creates a generic location string based on 
                // the ID.  This implementation supports canonical time zone round trip
                // with format pattern "VVVV".  See #6602 for the details.
                String location = tzid;
                int slashIdx = location.lastIndexOf('/');
                if (slashIdx == -1) {
                    // A time zone ID without slash in the tz database is not
                    // associated with a specific location.  For instances,
                    // MET, CET, EET and WET fall into this catetory.
                    zstrarray[ZSIDX_LOCATION] = null;
                } else {
                    location = tzid.substring(slashIdx + 1);
                    zstrarray[ZSIDX_LOCATION] = regionFmt.format(new Object[] {location});
                }
            }
        }

        boolean commonlyUsed = isCommonlyUsed(zoneStringsBundle, zoneKey);
        
        // Resolve metazones used by this zone
        int mzPartialLocIdx = 0;
        List<OlsonToMetaMappingEntry> metazoneMappings = ZoneMeta.getOlsonToMatazones(tzid);
        if (metazoneMappings != null) {
            Iterator<OlsonToMetaMappingEntry> it = metazoneMappings.iterator();
            while (it.hasNext()) {
                ZoneMeta.OlsonToMetaMappingEntry mzmap = it.next();
                ZoneStrings mzStrings = mzidToStrings.get(mzmap.mzid);
                if (mzStrings == null) {
                    // If the metazone strings are not yet processed, do it now.
                    String mzkey = "meta:" + mzmap.mzid;
                    boolean mzCommonlyUsed = isCommonlyUsed(zoneStringsBundle, mzkey);
                    mzstrarray[ZSIDX_LONG_STANDARD] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_LONG_STANDARD);
                    mzstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_SHORT_STANDARD);
                    mzstrarray[ZSIDX_LONG_DAYLIGHT] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_LONG_DAYLIGHT);
                    mzstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_SHORT_DAYLIGHT);
                    mzstrarray[ZSIDX_LONG_GENERIC] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_LONG_GENERIC);
                    mzstrarray[ZSIDX_SHORT_GENERIC] = getZoneStringFromBundle(zoneStringsBundle, mzkey, RESKEY_SHORT_GENERIC);
                    mzstrarray[ZSIDX_LOCATION] = null;
                    mzStrings = new ZoneStrings(mzstrarray, mzCommonlyUsed, null);
                    mzidToStrings.put(mzmap.mzid, mzStrings);

                    // Add metazone strings to the zone string trie
                    String preferredIdForLocale = ZoneMeta.getZoneIdByMetazone(mzmap.mzid, getRegion());
                    for (int j = 0; j < mzstrarray.length; j++) {
                        if (mzstrarray[j] != null) {
                            int type = getNameType(j);
                            ZoneStringInfo zsinfo = new ZoneStringInfo(preferredIdForLocale, mzstrarray[j], type);
                            zoneStringsTrie.put(mzstrarray[j], zsinfo);
                        }
                    }
                }
                // Compose generic partial location format
                String lg = mzStrings.getString(ZSIDX_LONG_GENERIC);
                String sg = mzStrings.getString(ZSIDX_SHORT_GENERIC);
                if (lg != null || sg != null) {
                    boolean addMzPartialLocationNames = true;
                    for (int j = 0; j < mzPartialLocIdx; j++) {
                        if (mzPartialLoc[j][0].equals(mzmap.mzid)) {
                            // already added
                            addMzPartialLocationNames = false;
                            break;
                        }
                    }
                    if (addMzPartialLocationNames) {
                        String locationPart = null;
                        // Check if the zone is the preferred zone for the territory associated with the zone
                        String preferredID = ZoneMeta.getZoneIdByMetazone(mzmap.mzid, countryCode);
                        if (tzid.equals(preferredID)) {
                            // Use country for the location
                            locationPart = country;
                        } else {
                            // Use city for the location
                            locationPart = city;
                        }
                        mzPartialLoc[mzPartialLocIdx][0] = mzmap.mzid;
                        mzPartialLoc[mzPartialLocIdx][1] = null;
                        mzPartialLoc[mzPartialLocIdx][2] = null;
                        mzPartialLoc[mzPartialLocIdx][3] = null;
                        if (locationPart != null) {
                            if (lg != null) {
                                mzPartialLoc[mzPartialLocIdx][1] = fallbackFmt.format(new Object[] {locationPart, lg});
                            }
                            if (sg != null) {
                                mzPartialLoc[mzPartialLocIdx][2] = fallbackFmt.format(new Object[] {locationPart, sg});
                                boolean shortMzCommonlyUsed = mzStrings.isShortFormatCommonlyUsed();
                                if (shortMzCommonlyUsed) {
                                    mzPartialLoc[mzPartialLocIdx][3] = "1";
                                }
                            }
                        }
                        mzPartialLocIdx++;
                    }
                }
            }
        }
        String[][] genericPartialLocationNames = null;
        if (mzPartialLocIdx != 0) {
            // metazone generic partial location names are collected
            genericPartialLocationNames = new String[mzPartialLocIdx][];
            for (int mzi = 0; mzi < mzPartialLocIdx; mzi++) {
                genericPartialLocationNames[mzi] = mzPartialLoc[mzi].clone();
            }
        }
        // Finally, create ZoneStrings instance and put it into the tzidToStinrgs map
        ZoneStrings zstrings = new ZoneStrings(zstrarray, commonlyUsed, genericPartialLocationNames);
        tzidToStrings.put(tzid, zstrings);

        // Also add all available names to the zone string trie
        if (zstrarray != null) {
            for (int j = 0; j < zstrarray.length; j++) {
                if (zstrarray[j] != null) {
                    int type = getNameType(j);
                    ZoneStringInfo zsinfo = new ZoneStringInfo(tzid, zstrarray[j], type);
                    zoneStringsTrie.put(zstrarray[j], zsinfo);
                }
            }
        }
        if (genericPartialLocationNames != null) {
            for (int j = 0; j < genericPartialLocationNames.length; j++) {
                ZoneStringInfo zsinfo;
                if (genericPartialLocationNames[j][1] != null) {
                    zsinfo = new ZoneStringInfo(tzid, genericPartialLocationNames[j][1], GENERIC_LONG);
                    zoneStringsTrie.put(genericPartialLocationNames[j][1], zsinfo);
                }
                if (genericPartialLocationNames[j][2] != null) {
                    zsinfo = new ZoneStringInfo(tzid, genericPartialLocationNames[j][1], GENERIC_SHORT);
                    zoneStringsTrie.put(genericPartialLocationNames[j][2], zsinfo);
                }
            }
        }
    }

    // Name types, these bit flag are used for zone string lookup
    private static final int LOCATION = 0x0001;
    private static final int GENERIC_LONG = 0x0002;
    private static final int GENERIC_SHORT = 0x0004;
    private static final int STANDARD_LONG = 0x0008;
    private static final int STANDARD_SHORT = 0x0010;
    private static final int DAYLIGHT_LONG = 0x0020;
    private static final int DAYLIGHT_SHORT = 0x0040;
    
    // Name type index, these constants are used for index in ZoneStrings.strings
    private static final int ZSIDX_LOCATION = 0;
    private static final int ZSIDX_LONG_STANDARD = 1;
    private static final int ZSIDX_SHORT_STANDARD = 2;
    private static final int ZSIDX_LONG_DAYLIGHT = 3;
    private static final int ZSIDX_SHORT_DAYLIGHT = 4;
    private static final int ZSIDX_LONG_GENERIC = 5;
    private static final int ZSIDX_SHORT_GENERIC = 6;

    private static final int ZSIDX_MAX = ZSIDX_SHORT_GENERIC + 1;

    // ZoneStringFormat cache
    private static ICUCache<ULocale, ZoneStringFormat> ZSFORMAT_CACHE = new SimpleCache<ULocale, ZoneStringFormat>();

    /*
     * The translation type of the translated zone strings
     */
    private static final String
         RESKEY_SHORT_GENERIC  = "sg",
         RESKEY_SHORT_STANDARD = "ss",
         RESKEY_SHORT_DAYLIGHT = "sd",
         RESKEY_LONG_GENERIC   = "lg",
         RESKEY_LONG_STANDARD  = "ls",
         RESKEY_LONG_DAYLIGHT  = "ld",
         RESKEY_EXEMPLAR_CITY  = "ec",
         RESKEY_COMMONLY_USED  = "cu";

    // Window size used for DST check for a zone in a metazone
    private static final long DST_CHECK_RANGE = 184L*(24*60*60*1000);

    // Map from zone id to ZoneStrings
    private Map<String, ZoneStrings> tzidToStrings;

    // Map from metazone id to ZoneStrings
    private Map<String, ZoneStrings> mzidToStrings;

    // Zone string dictionary, used for look up
    private TextTrieMap<ZoneStringInfo> zoneStringsTrie;

    // Locale used for initializing zone strings
    private ULocale locale;

    // Region used for resolving a zone in a metazone, initialized by locale
    private transient String region;

    // Loading status
    private boolean isFullyLoaded = false;

    // Digit string - used for fast GMT formatting
    private String digitString;
    
    private String gmtFormat;
    
    private String[] hourFormats;
    
    /*
     * Private method to get a zone string except generic partial location types.
     */
    private String getString(String tzid, int typeIdx, long date, boolean commonlyUsedOnly) {
        if (!isFullyLoaded) {
            // Lazy loading
            loadZone(tzid);
        }

        String result = null;
        ZoneStrings zstrings = tzidToStrings.get(tzid);
        if (zstrings == null) {
            // ICU's own array does not have entries for aliases
            String canonicalID = ZoneMeta.getCanonicalSystemID(tzid);
            if (canonicalID != null && !canonicalID.equals(tzid)) {
                // Canonicalize tzid here.  The rest of operations
                // require tzid to be canonicalized.
                tzid = canonicalID;
                zstrings = tzidToStrings.get(tzid);
            }
        }
        if (zstrings != null) {
            switch (typeIdx) {
            case ZSIDX_LONG_STANDARD:
            case ZSIDX_LONG_DAYLIGHT:
            case ZSIDX_LONG_GENERIC:
            case ZSIDX_LOCATION:
                result = zstrings.getString(typeIdx);
                break;
            case ZSIDX_SHORT_STANDARD:
            case ZSIDX_SHORT_DAYLIGHT:
            case ZSIDX_SHORT_GENERIC:
                if (!commonlyUsedOnly || zstrings.isShortFormatCommonlyUsed()) {
                    result = zstrings.getString(typeIdx);
                }
                break;
            }
        }
        if (result == null && mzidToStrings != null && typeIdx != ZSIDX_LOCATION) {
            // Try metazone
            String mzid = ZoneMeta.getMetazoneID(tzid, date);
            if (mzid != null) {
                ZoneStrings mzstrings = mzidToStrings.get(mzid);
                if (mzstrings != null) {
                    switch (typeIdx) {
                    case ZSIDX_LONG_STANDARD:
                    case ZSIDX_LONG_DAYLIGHT:
                    case ZSIDX_LONG_GENERIC:
                        result = mzstrings.getString(typeIdx);
                        break;
                    case ZSIDX_SHORT_STANDARD:
                    case ZSIDX_SHORT_DAYLIGHT:
                    case ZSIDX_SHORT_GENERIC:
                        if (!commonlyUsedOnly || mzstrings.isShortFormatCommonlyUsed()) {
                            result = mzstrings.getString(typeIdx);
                        }
                        break;
                    }
                }
            }
        }
        return result;
    }

    /*
     * 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.
     */
    private String getGenericString(TimeZone tz, long date, boolean isShort, boolean commonlyUsedOnly) {
        String result = null;
        String tzid = tz.getID();

        if (!isFullyLoaded) {
            // Lazy loading
            loadZone(tzid);
        }

        ZoneStrings zstrings = tzidToStrings.get(tzid);
        if (zstrings == null) {
            // ICU's own array does not have entries for aliases
            String canonicalID = ZoneMeta.getCanonicalSystemID(tzid);
            if (canonicalID != null && !canonicalID.equals(tzid)) {
                // Canonicalize tzid here.  The rest of operations
                // require tzid to be canonicalized.
                tzid = canonicalID;
                zstrings = tzidToStrings.get(tzid);
            }
        }
        if (zstrings != null) {
            if (isShort) {
                if (!commonlyUsedOnly || zstrings.isShortFormatCommonlyUsed()) {
                    result = zstrings.getString(ZSIDX_SHORT_GENERIC);
                }
            } else {
                result = zstrings.getString(ZSIDX_LONG_GENERIC);
            }
        }
        if (result == null && mzidToStrings != null) {
            // try metazone
            String mzid = ZoneMeta.getMetazoneID(tzid, date);
            if (mzid != null) {
                boolean useStandard = false;
                if (!inDaylightTime(tz,date)) {
                    useStandard = true;
                    // Check if the zone actually uses daylight saving time around the time
                    if (tz instanceof BasicTimeZone) {
                        BasicTimeZone btz = (BasicTimeZone)tz;
                        TimeZoneTransition before = btz.getPreviousTransition(date, true);
                        if (before != null
                                && (date - before.getTime() < DST_CHECK_RANGE)
                                && before.getFrom().getDSTSavings() != 0) {
                            useStandard = false;
                        } else {
                            TimeZoneTransition after = btz.getNextTransition(date, false);
                            if (after != null
                                    && (after.getTime() - date < DST_CHECK_RANGE)
                                    && after.getTo().getDSTSavings() != 0) {
                                useStandard = false;
                            }
                        }
                    } else {
                        // If not BasicTimeZone... only if the instance is not an ICU's implementation.
                        // We may get a wrong answer in edge case, but it should practically work OK.
                        int[] offsets = new int[2];
                        tz.getOffset(date - DST_CHECK_RANGE, false, offsets);
                        if (offsets[1] != 0) {
                            useStandard = false;
                        } else {
                            tz.getOffset(date + DST_CHECK_RANGE, false, offsets);
                            if (offsets[1] != 0){
                                useStandard = false;
                            }
                        }
                    }
                }
                if (useStandard) {
                    result = getString(tzid, (isShort ? ZSIDX_SHORT_STANDARD : ZSIDX_LONG_STANDARD),
                            date, commonlyUsedOnly);

                    // Note:
                    // In CLDR 1.5.1, a same localization is used for both generic and standard
                    // for some metazones in some locales.  This is actually data bugs and should
                    // be resolved in later versions of CLDR.  For now, we check if the standard
                    // name is different from its generic name below.
                    if (result != null) {
                        String genericNonLocation = getString(tzid, (isShort ? ZSIDX_SHORT_GENERIC : ZSIDX_LONG_GENERIC),
                                date, commonlyUsedOnly);
                        if (genericNonLocation != null && result.equalsIgnoreCase(genericNonLocation)) {
                            result = null;
                        }
                    }
                }
                if (result == null){
                    ZoneStrings mzstrings = mzidToStrings.get(mzid);
                    if (mzstrings != null) {
                        if (isShort) {
                            if (!commonlyUsedOnly || mzstrings.isShortFormatCommonlyUsed()) {
                                result = mzstrings.getString(ZSIDX_SHORT_GENERIC);
                            }
                        } else {
                            result = mzstrings.getString(ZSIDX_LONG_GENERIC);
                        }
                    }
                    if (result != null) {
                        // Check if the offsets at the given time matches the preferred zone's offsets
                        String preferredId = ZoneMeta.getZoneIdByMetazone(mzid, getRegion());
                        if (!tzid.equals(preferredId)) {
                            // Check if the offsets at the given time are identical with the preferred zone
                            int[] offsets = {0,0};
                            tz.getOffset(date,false,offsets);
                            int raw = offsets[0];
                            int sav = offsets[1];
                            TimeZone preferredZone = TimeZone.getTimeZone(preferredId);
                            int[] preferredOffsets = new int[2];
                            // Check offset in preferred time zone with wall time.
                            // With getOffset(time, false, preferredOffsets),
                            // you may get incorrect results because of time overlap at DST->STD
                            // transition.
                            preferredZone.getOffset(date + raw + sav, true, preferredOffsets);
                            if (raw != preferredOffsets[0] || sav != preferredOffsets[1]) {
                                // Use generic partial location string as fallback
                                result = zstrings.getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly);
                            }
                        }
                    }
                }
            }
        }
        if (result == null) {
            // Use location format as the final fallback
            result = getString(tzid, ZSIDX_LOCATION, date, false /* not used */);
        }
        return result;
    }
    
    /*
     * Private method to get a generic partial location string
     */
    private String getGenericPartialLocationString(String tzid, boolean isShort, long date, boolean commonlyUsedOnly) {
        if (!isFullyLoaded) {
            // Lazy loading
            loadZone(tzid);
        }

        String result = null;
        String mzid = ZoneMeta.getMetazoneID(tzid, date);
        if (mzid != null) {
            ZoneStrings zstrings = tzidToStrings.get(tzid);
            if (zstrings != null) {
                result = zstrings.getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly);
            }
        }
        return result;
    }

    /*
     * Gets zoneStrings compatible with DateFormatSymbols for the
     * specified date.  In CLDR 1.5, zone names can be changed
     * time to time.  This method generates flat 2-dimensional
     * String array including zone ids and its localized strings
     * at the moment.  Thus, even you construct a new ZoneStringFormat
     * by the zone strings array returned by this method, you will
     * loose historic name changes.  Also, commonly used flag for
     * short types is not reflected in the result.
     */
    private String[][] getZoneStrings(long date) {
        loadFull();

        Set<String> tzids = tzidToStrings.keySet();
        String[][] zoneStrings = new String[tzids.size()][8];
        int idx = 0;
        for (String tzid : tzids) {
            zoneStrings[idx][0] = tzid;
            zoneStrings[idx][1] = getLongStandard(tzid, date);
            zoneStrings[idx][2] = getShortStandard(tzid, date, false);
            zoneStrings[idx][3] = getLongDaylight(tzid, date);
            zoneStrings[idx][4] = getShortDaylight(tzid, date, false);
            zoneStrings[idx][5] = getGenericLocation(tzid);
            zoneStrings[idx][6] = getLongGenericNonLocation(tzid, date);
            zoneStrings[idx][7] = getShortGenericNonLocation(tzid, date, false);
            idx++;
        }
        return zoneStrings;
    }
    
    /*
     * ZoneStrings is an internal implementation class for
     * holding localized name information for a zone/metazone
     */
    private static class ZoneStrings {
        private String[] strings;
        private String[][] genericPartialLocationStrings;
        private boolean commonlyUsed;
 
        private ZoneStrings(String[] zstrarray, boolean commonlyUsed, String[][] genericPartialLocationStrings) {
            if (zstrarray != null) {
                int lastIdx = -1;
                for (int i = 0; i < zstrarray.length; i++) {
                    if (zstrarray[i] != null) {
                        lastIdx = i;
                    }
                }
                if (lastIdx != -1) {
                    strings = new String[lastIdx + 1];
                    System.arraycopy(zstrarray, 0, strings, 0, lastIdx + 1);
                }
            }
            this.commonlyUsed = commonlyUsed;
            this.genericPartialLocationStrings = genericPartialLocationStrings;
        }

        private String getString(int typeIdx) {
            if (strings != null && typeIdx >= 0 && typeIdx < strings.length) {
                return strings[typeIdx];
            }
            return null;
        }

        private boolean isShortFormatCommonlyUsed() {
            return commonlyUsed;
        }

        private String getGenericPartialLocationString(String mzid, boolean isShort, boolean commonlyUsedOnly) {
            String result = null;
            if (genericPartialLocationStrings != null) {
                for (int i = 0; i < genericPartialLocationStrings.length; i++) {
                    if (genericPartialLocationStrings[i][0].equals(mzid)) {
                        if (isShort) {
                            if (!commonlyUsedOnly || genericPartialLocationStrings[i][3] != null) {
                                result = genericPartialLocationStrings[i][2];
                            }
                        } else {
                            result = genericPartialLocationStrings[i][1];
                        }
                        break;
                    }
                }
            }
            return result;
        }
    }

    /*
     * Returns a localized zone string from bundle.
     */
    private static String getZoneStringFromBundle(ICUResourceBundle bundle, String key, String type) {
        String zstring = null;
        if (bundle != null) {
            try {
                zstring = bundle.getStringWithFallback(key + "/" + type);
            } catch (MissingResourceException ex) {
                // throw away the exception
            }
        }
        return zstring;
    }

    /*
     * Returns if the short strings of the zone/metazone is commonly used.
     */
    private static boolean isCommonlyUsed(ICUResourceBundle bundle, String key) {
        boolean commonlyUsed = false;
        if (bundle != null) {
            try {
                UResourceBundle cuRes = bundle.getWithFallback(key + "/" + RESKEY_COMMONLY_USED);
                int cuValue = cuRes.getInt();
                commonlyUsed = (cuValue != 0);
            } catch (MissingResourceException ex) {
                // throw away the exception
            }
        }
        return commonlyUsed;
    }

    /*
     * Returns a localized country string for the country code.  If no actual
     * localized string is found, countryCode itself is returned.
     */
    private static String getLocalizedCountry(String countryCode, ULocale locale) {
        String countryStr = null;
        if (countryCode != null) {
            ICUResourceBundle rb = 
                (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_REGION_BASE_NAME, locale);
//
// TODO: There is a design bug in UResourceBundle and getLoadingStatus() does not work well.
//
//            if (rb.getLoadingStatus() != ICUResourceBundle.FROM_ROOT && rb.getLoadingStatus() != ICUResourceBundle.FROM_DEFAULT) {
//                country = ULocale.getDisplayCountry("xx_" + country_code, locale);
//            }
// START WORKAROUND
            ULocale rbloc = rb.getULocale();
            if (!rbloc.equals(ULocale.ROOT) && rbloc.getLanguage().equals(locale.getLanguage())) {
                countryStr = ULocale.getDisplayCountry("xx_" + countryCode, locale);
            }
// END WORKAROUND
            if (countryStr == null || countryStr.length() == 0) {
                countryStr = countryCode;
            }
        }
        return countryStr;
    }

    /*
     * Gets an instance of MessageFormat used for formatting zone fallback string
     */
    private static MessageFormat getFallbackFormat(ULocale locale) {
        String fallbackPattern = ZoneMeta.getTZLocalizationInfo(locale, ZoneMeta.FALLBACK_FORMAT);
        if (fallbackPattern == null) {
            fallbackPattern = "{1} ({0})";
        }
        return new MessageFormat(fallbackPattern, locale);
    }

    /*
     * Gets an instance of MessageFormat used for formatting zone region string
     */
    private static MessageFormat getRegionFormat(ULocale locale) {
        String regionPattern = ZoneMeta.getTZLocalizationInfo(locale, ZoneMeta.REGION_FORMAT);
        if (regionPattern == null) {
            regionPattern = "{0}";
        }
        return new MessageFormat(regionPattern, locale);
    }

    /*
     * Index value mapping between DateFormatSymbols's zoneStrings and
     * the string types defined in this class.
     */
    private static final int[] INDEXMAP = {
        -1,             // 0 - zone id
        ZSIDX_LONG_STANDARD,  // 1 - long standard
        ZSIDX_SHORT_STANDARD, // 2 - short standard
        ZSIDX_LONG_DAYLIGHT,  // 3 - long daylight
        ZSIDX_SHORT_DAYLIGHT, // 4 - short daylight
        ZSIDX_LOCATION,       // 5 - generic location
        ZSIDX_LONG_GENERIC,   // 6 - long generic non-location
        ZSIDX_SHORT_GENERIC   // 7 - short generic non-location
    };

    /*
     * Convert from zone string array index for zoneStrings used by DateFormatSymbols#get/setZoneStrings
     * to the type constants defined by this class, such as ZSIDX_LONG_STANDARD.
     */
    private static int getNameTypeIndex(int i) {
        int idx = -1;
        if (i >= 1 && i < INDEXMAP.length) {
            idx = INDEXMAP[i];
        }
        return idx;
    }

    /*
     * Mapping from name type index to name type
     */
    private static final int[] NAMETYPEMAP = {
        LOCATION,       // ZSIDX_LOCATION
        STANDARD_LONG,  // ZSIDX_LONG_STANDARD
        STANDARD_SHORT, // ZSIDX_SHORT_STANDARD
        DAYLIGHT_LONG,  // ZSIDX_LONG_DAYLIGHT
        DAYLIGHT_SHORT, // ZSIDX_SHORT_DAYLIGHT
        GENERIC_LONG,   // ZSIDX_LONG_GENERIC
        GENERIC_SHORT,  // ZSIDX_SHORT_GENERIC
    };

    private static int getNameType(int typeIdx) {
        int type = -1;
        if (typeIdx >= 0 && typeIdx < NAMETYPEMAP.length) {
            type = NAMETYPEMAP[typeIdx];
        }
        return type;
    }

    /*
     * Returns region used for ZoneMeta#getZoneIdByMetazone.
     */
    private String getRegion() {
        if (region == null) {
            if (locale != null) {
                region = locale.getCountry();
                if (region.length() == 0) {
                    ULocale tmp = ULocale.addLikelySubtags(locale);
                    region = tmp.getCountry();
                }
            } else {
                region = "";
            }
        }
        return region;
    }

    // This method does lazy zone string loading
    private ZoneStringInfo find(String text, int start, int types) {
        ZoneStringInfo result = subFind(text, start, types);
        if (isFullyLoaded) {
            return result;
        }
        // When zone string data is partially loaded,
        // this method return the result only when
        // the input text is fully consumed.
        if (result != null) {
            int matchLen = result.getString().length();
            if (text.length() - start == matchLen) {
                return result;
            }
        }
        // Now load all zone strings
        loadFull();
        return subFind(text, start, types);
    }

    /*
     * 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
     * @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.
     */
    private ZoneStringInfo subFind(String text, int start, int types) {
        ZoneStringInfo result = null;
        ZoneStringSearchResultHandler handler = new ZoneStringSearchResultHandler();
        zoneStringsTrie.find(text, start, handler);
        List<ZoneStringInfo> list = handler.getMatchedZoneStrings();
        ZoneStringInfo fallback = null;
        if (list != null && list.size() > 0) {
            Iterator<ZoneStringInfo> it = list.iterator();
            while (it.hasNext()) {
                ZoneStringInfo tmp = it.next();
                if ((types & tmp.getType()) != 0) {
                    if (result == null || result.getString().length() < tmp.getString().length()) {
                        result = tmp;
                    } else if (result.getString().length() == tmp.getString().length()) {
                        // Tie breaker - there are some examples that a
                        // long standard name is identical with a location
                        // name - for example, "Uruguay Time".  In this case,
                        // we interpret it as generic, not specific.
                        if (tmp.isGeneric() && !result.isGeneric()) {
                            result = tmp;
                        }
                    }
                } else if (result == null) {
                    if (fallback == null || fallback.getString().length() < tmp.getString().length()) {
                        fallback = tmp;
                    } else if (fallback.getString().length() == tmp.getString().length()) {
                        if (tmp.isGeneric() && !fallback.isGeneric()) {
                            fallback = tmp;
                        }
                    }
                }
            }
        }
        if (result == null && fallback != null) {
            result = fallback;
        }
        return result;
    }

    

    private static class ZoneStringSearchResultHandler implements TextTrieMap.ResultHandler<ZoneStringInfo> {

        private ArrayList<ZoneStringInfo> resultList;

        public boolean handlePrefixMatch(int matchLength, Iterator<ZoneStringInfo> values) {
            if (resultList == null) {
                resultList = new ArrayList<ZoneStringInfo>();
            }
            while (values.hasNext()) {
                ZoneStringInfo zsitem = values.next();
                if (zsitem == null) {
                    break;
                }
                int i = 0;
                for (; i < resultList.size(); i++) {
                    ZoneStringInfo tmp = resultList.get(i);
                    if (zsitem.getType() == tmp.getType()) {
                        if (matchLength > tmp.getString().length()) {
                            resultList.set(i, zsitem);
                        }
                        break;
                    }
                }
                if (i == resultList.size()) {
                    // not found in the current list
                    resultList.add(zsitem);
                }
            }
            return true;
        }

        List<ZoneStringInfo> getMatchedZoneStrings() {
            if (resultList == null || resultList.size() == 0) {
                return null;
            }
            return resultList;
        }
    }
}
