//##header
/*
 *******************************************************************************
 * Copyright (C) 2004-2006, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
*/
package com.ibm.icu.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

//#ifndef FOUNDATION
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//#endif

import com.ibm.icu.impl.Utility;
import com.ibm.icu.impl.ZoneMeta;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.SimpleDateFormat;

/**
 * This convenience class provides a mechanism for bundling together different
 * globalization preferences. It includes:
 * <ul>
 * <li>A list of locales/languages in preference order</li>
 * <li>A territory</li>
 * <li>A currency</li>
 * <li>A timezone</li>
 * <li>A calendar</li>
 * <li>A collator (for language-sensitive sorting, searching, and matching).</li>
 * <li>Explicit overrides for date/time formats, etc.</li>
 * </ul>
 * The class will heuristically compute implicit, heuristic values for the above
 * based on available data if explicit values are not supplied. These implicit
 * values can be presented to users for confirmation, or replacement if the
 * values are incorrect.
 * <p>
 * To reset any explicit field so that it will get heuristic values, pass in
 * null. For example, myPreferences.setLocale(null);
 * <p>
 * All of the heuristics can be customized by subclasses, by overriding
 * getTerritory(), guessCollator(), etc.
 * <p>
 * The class also supplies display names for languages, scripts, territories,
 * currencies, timezones, etc. These are computed according to the
 * locale/language preference list. Thus, if the preference is Breton; French;
 * English, then the display name for a language will be returned in Breton if
 * available, otherwise in French if available, otherwise in English.
 * <p>
 * The codes used to reference territory, currency, etc. are as defined elsewhere in ICU,
 * and are taken from CLDR (which reflects RFC 3066bis usage, ISO 4217, and the 
 * TZ Timezone database identifiers).
 * <p>
 * <b>This is at a prototype stage, and has not incorporated all the design
 * changes that we would like yet; further feedback is welcome.</b></p>
 * <p>
 * TODO:<ul>
 * <li>Separate out base class</li>
 * <li>Add BreakIterator</li>
 * <li>Add Holidays</li>
 * <li>Add convenience to get/take Locale as well as ULocale.</li>
 * <li>Add getResourceBundle(String baseName, ClassLoader loader);</li>
 * <li>Add getFallbackLocales();</li>
 * <li>Add Lenient datetime formatting when that is available.</li>
 * <li>Should this be serializable?</li>
 * <li>Other utilities?</li>
 * </ul>
 * Note:
 * <ul>
 * <li>to get the display name for the first day of the week, use the calendar +
 * display names.</li>
 * <li>to get the work days, ask the calendar (when that is available).</li>
 * <li>to get papersize / measurement system/bidi-orientation, ask the locale
 * (when that is available there)</li>
 * <li>to get the field order in a date, and whether a time is 24hour or not,
 * ask the DateFormat (when that is available there)</li>
 * <li>it will support HOST locale when it becomes available (it is a special
 * locale that will ask the services to use the host platform's values).</li>
 * </ul>
 *
 * @internal
 * @deprecated This API is ICU internal only.
 */
public class GlobalizationPreferences implements Freezable {
    /**
     * Number Format types
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int CURRENCY = 0, NUMBER = 1, INTEGER = 2, SCIENTIFIC = 3, 
        PERCENT = 4, NUMBER_LIMIT = 5;

    /**
     * Supplement to DateFormat.FULL, LONG, MEDIUM, SHORT. Indicates
     * that no value for one of date or time is to be used.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int NONE = 4;

    /**
     * For selecting a choice of display names
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int
        LOCALEID = 0, LANGUAGEID = 1, SCRIPTID = 2, TERRITORYID = 3, VARIANTID = 4, 
        KEYWORDID = 5, KEYWORD_VALUEID = 6,
        CURRENCYID = 7, CURRENCY_SYMBOLID = 8, TIMEZONEID = 9, DISPLAYID_LIMIT = 10;
	
    /**
     * Sets the language/locale priority list. If other information is
     * not (yet) available, this is used to to produce a default value
     * for the appropriate territory, currency, timezone, etc.  The
     * user should be given the opportunity to correct those defaults
     * in case they are incorrect.
     * @param locales list of locales in priority order, eg {"be", "fr"} 
     *     for Breton first, then French if that fails.
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setLocales(List locales) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        if (locales.size() == 0) {
            this.locales = locales.get(0);
        } else {
            this.locales = new ArrayList(locales); // clone for safety
        }
        return this;
    }

    /**
     * Get a copy of the language/locale priority list
     * @return a copy of the language/locale priority list.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public List getLocales() {
        List result = new ArrayList(); // clone for safety
        if (locales == null) {
            result = guessLocales();
        } else if (locales instanceof ULocale) {
            result.add(locales);
        } else {
            result.addAll((List)locales);
        }
        return result;
    }

    /**
     * Convenience function for getting the locales in priority order
     * @param index The index (0..n) of the desired item.
     * @return desired item.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public ULocale getLocale(int index) {
        if (locales == null) {
            return (ULocale)guessLocales().get(index);
        } else if (locales instanceof ULocale) {
            if (index != 0) throw new IllegalArgumentException("Out of bounds: " + index);
            return (ULocale)locales;
        } else {
            return (ULocale)((List)locales).get(index);
        }
    }

    /**
     * Convenience routine for setting the language/locale priority
     * list from an array.
     * @see #setLocales(List locales)
     * @param uLocales list of locales in an array
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setLocales(ULocale[] uLocales) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        return setLocales(Arrays.asList(uLocales));
    }
    /**
     * Convenience routine for setting the language/locale priority
     * list from a single locale/language.
     * @see #setLocales(List locales)
     * @param uLocale single locale
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setLocale(ULocale uLocale) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        return setLocales(new ULocale[]{uLocale});
    }

//#ifndef FOUNDATION
    /**
     * Convenience routine for setting the locale priority list from
     * an Accept-Language string.
     * @see #setLocales(List locales)
     * @param acceptLanguageString Accept-Language list, as defined by 
     *     Section 14.4 of the RFC 2616 (HTTP 1.1)
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setLocales(String acceptLanguageString) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        /*
          Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q" "=" qvalue ] )
          x matches x-...
        */
        // reorders in quality order
        // don't care that it is not very efficient right now
        Matcher acceptMatcher = Pattern.compile("\\s*([-_a-zA-Z]+)(;q=([.0-9]+))?\\s*").matcher("");
        Map reorder = new TreeMap();
        String[] pieces = acceptLanguageString.split(",");
		
        for (int i = 0; i < pieces.length; ++i) {
            Double qValue = new Double(1);
            try {
                if (!acceptMatcher.reset(pieces[i]).matches()) {
                    throw new IllegalArgumentException();
                }
                String qValueString = acceptMatcher.group(3);
                if (qValueString != null) qValue = new Double(Double.parseDouble(qValueString));
            } catch (Exception e) {
                throw new IllegalArgumentException("element '" + pieces[i] + 
                    "' is not of the form '<locale>{;q=<number>}");
            }
            List items = (List)reorder.get(qValue);
            if (items == null) reorder.put(qValue, items = new LinkedList());
            items.add(0, acceptMatcher.group(1)); // reverse order, will reverse again
        }
        // now read out in reverse order
        List result = new ArrayList();
        for (Iterator it = reorder.keySet().iterator(); it.hasNext();) {
            Object key = it.next();
            List items = (List)reorder.get(key);
            for (Iterator it2 = items.iterator(); it2.hasNext();) {
                result.add(0, new ULocale((String)it2.next()));
            }
        }
        return setLocales(result);
    }
//#endif

    /**
     * Sets the territory, which is a valid territory according to for
     * RFC 3066 (or successor).  If not otherwise set, default
     * currency and timezone values will be set from this.  The user
     * should be given the opportunity to correct those defaults in
     * case they are incorrect.
     * @param territory code
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setTerritory(String territory) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.territory = territory;
        return this;
    }

    /**
     * Gets the territory setting. If it wasn't explicitly set, it is
     * computed from the general locale setting.
     * @return territory code, explicit or implicit.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public String getTerritory() {
        if (territory == null) return guessTerritory();
        return territory; // immutable, so don't need to clone
    }

    /**
     * Sets the currency code. If this has not been set, uses default for territory.
     * @param currency Valid ISO 4217 currency code.
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setCurrency(Currency currency) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.currency = currency;
        return this;
    }

    /**
     * Get a copy of the currency computed according to the settings. 
     * @return currency code, explicit or implicit.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public Currency getCurrency() {
        if (currency == null) return guessCurrency();
        return currency; // immutable, so don't have to clone
    }

    /**
     * Sets the calendar. If this has not been set, uses default for territory.
     * @param calendar arbitrary calendar
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setCalendar(Calendar calendar) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.calendar = calendar;
        return this;
    }

    /**
     * Get a copy of the calendar according to the settings. 
     * @return calendar explicit or implicit.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public Calendar getCalendar() {
        if (calendar == null) return guessCalendar();
        Calendar temp = (Calendar) calendar.clone(); // clone for safety
        temp.setTimeZone(getTimeZone());
        return temp;
    }

    /**
     * Sets the timezone ID.  If this has not been set, uses default for territory.
     * @param timezone a valid TZID (see UTS#35).
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setTimeZone(TimeZone timezone) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.timezone = timezone;
        return this;
    }

    /**
     * Get the timezone. It was either explicitly set, or is
     * heuristically computed from other settings.
     * @return timezone, either implicitly or explicitly set
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public TimeZone getTimeZone() {
        if (timezone == null) return guessTimeZone();
        return (TimeZone) timezone.clone(); // clone for safety
    }
	
    /**
     * Get a copy of the collator according to the settings. 
     * @return collator explicit or implicit.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public Collator getCollator() {
        if (collator == null) return guessCollator();
        try {
            return (Collator) collator.clone();  // clone for safety
        } catch (CloneNotSupportedException e) {
            throw new InternalError("Error in cloning collator");
        }
    }

    /**
     * Explicitly set the collator for this object.
     * @param collator
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setCollator(Collator collator) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.collator = collator;
        return this;
    }

    /**
     * Set the date locale. 
     * @param dateLocale If not null, overrides the locale priority list for all the date formats.
     * @return this, for chaining
     */
    public GlobalizationPreferences setDateLocale(ULocale dateLocale) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.dateLocale = dateLocale;
        return this;
    }

    /**
     * Gets the date locale, to be used in computing date formats. Overrides the general locale setting.
     * @return date locale. Null if none was set explicitly.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public ULocale getDateLocale() {
        return dateLocale != null ? dateLocale : getLocale(0);
    }
	
    /**
     * Set the number locale. 
     * @param numberLocale If not null, overrides the locale priority list for all the date formats.
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setNumberLocale(ULocale numberLocale) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        this.numberLocale = numberLocale;
        return this;
    }

    /**
     * Get the current number locale setting used for getNumberFormat.
     * @return number locale. Null if none was set explicitly.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public ULocale getNumberLocale() {
        return numberLocale != null ? numberLocale : getLocale(0);
    }
	
    /**
     * Get the display name for an ID: language, script, territory, currency, timezone...
     * Uses the language priority list to do so.
     * @param id language code, script code, ...
     * @param type specifies the type of the ID: LANGUAGE, etc.
     * @return the display name
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public String getDisplayName(String id, int type) {
        String result = id;
        for (Iterator it = getLocales().iterator(); it.hasNext();) {
            ULocale locale = (ULocale) it.next();
            switch (type) {
            case LOCALEID: 
                result = ULocale.getDisplayName(id, locale); 
                break;
            case LANGUAGEID: 
                result = ULocale.getDisplayLanguage(id, locale); 
                break;
            case SCRIPTID: 
                result = ULocale.getDisplayScript("und-" + id, locale); 
                break;
            case TERRITORYID: 
                result = ULocale.getDisplayCountry("und-" + id, locale); 
                break;
            case VARIANTID: 
                // TODO fix variant parsing
                result = ULocale.getDisplayVariant("und-QQ-" + id, locale); 
                break;
            case KEYWORDID: 
                result = ULocale.getDisplayKeyword(id, locale); 
                break;
            case KEYWORD_VALUEID:
                String[] parts = new String[2];
                Utility.split(id,'=',parts);
                result = ULocale.getDisplayKeywordValue("und@"+id, parts[0], locale);
                // TODO fix to tell when successful
                if (result.equals(parts[1])) continue;
                break;
            case CURRENCY_SYMBOLID:
            case CURRENCYID:
                Currency temp = new Currency(id);
                result =temp.getName(locale, type==CURRENCYID 
                                     ? Currency.LONG_NAME 
                                     : Currency.SYMBOL_NAME, new boolean[1]);
                // TODO: have method that doesn't take parameter. Add
                // function to determine whether string is choice
                // format.  
                // TODO: have method that doesn't require us
                // to create a currency
                break;
            case TIMEZONEID:
                SimpleDateFormat dtf = new SimpleDateFormat("vvvv",locale);
                dtf.setTimeZone(TimeZone.getTimeZone(id));
                result = dtf.format(new Date());
                // TODO, have method that doesn't require us to create a timezone
                // fix other hacks
                // hack for couldn't match
                // note, compiling with FOUNDATION omits this check for now
//#ifndef FOUNDATION
                if (badTimeZone.reset(result).matches()) continue;
//#endif
                break;
            default:
                throw new IllegalArgumentException("Unknown type: " + type);
            }
            if (!id.equals(result)) return result;
            // TODO need better way of seeing if we fell back to root!!
            // This will not work at all for lots of stuff
        }
        return result;
    }
//#ifndef FOUNDATION
    // TODO remove need for this
    private static final Matcher badTimeZone = Pattern.compile("[A-Z]{2}|.*\\s\\([A-Z]{2}\\)").matcher("");
//#endif


    /**
     * Set an explicit date format. Overrides both the date locale,
     * and the locale priority list for a particular combination of
     * dateStyle and timeStyle. NONE should be used if for the style,
     * where only the date or time format individually is being set.
     * @param dateStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @param timeStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @param format
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setDateFormat(int dateStyle, int timeStyle, DateFormat format) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        if (dateFormats == null) dateFormats = new Object[NONE+1][NONE+1];
        dateFormats[dateStyle][timeStyle] = (DateFormat) format.clone(); // for safety
        return this;
    }
	
    /**
     * Set an explicit date format. Overrides both the date locale,
     * and the locale priority list for a particular combination of
     * dateStyle and timeStyle. NONE should be used if for the style,
     * where only the date or time format individually is being set.
     * @param dateStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @param timeStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @param formatPattern date pattern, eg "yyyy-MMM-dd"
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setDateFormat(int dateStyle, int timeStyle, String formatPattern) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        if (dateFormats == null) dateFormats = new Object[NONE+1][NONE+1];
        // test the format to make sure it won't throw an error later
        new SimpleDateFormat(formatPattern, getDateLocale());
        dateFormats[dateStyle][timeStyle] = formatPattern; // for safety
        return this;
    }

    /**
     * Gets a date format according to the current settings. If there
     * is an explicit (non-null) date/time format set, a copy of that
     * is returned. Otherwise, if there is a non-null date locale,
     * that is used.  Otherwise, the language priority list is
     * used. NONE should be used for the style, where only the date or
     * time format individually is being gotten.
     * @param dateStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @param timeStyle NONE, or DateFormat.FULL, LONG, MEDIUM, SHORT
     * @return a DateFormat, according to the above description
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public DateFormat getDateFormat(int dateStyle, int timeStyle) {
        try {
            DateFormat result = null;
            if (dateFormats != null) { // and override can either be a string or a pattern
                Object temp = dateFormats[dateStyle][timeStyle];
                if (temp instanceof DateFormat) {
                    result = (DateFormat) temp;
                } else {
                    result = new SimpleDateFormat((String)temp, getDateLocale());
                }	
            }
            if (result != null) {
                result = (DateFormat) result.clone(); // clone for safety
                result.setCalendar(getCalendar());
            } else {
                // In the case of date formats, we don't have to look at more than one
                // locale. May be different for other cases
                // TODO Make this one function.
                if (timeStyle == NONE) {
                    result = DateFormat.getDateInstance(getCalendar(), dateStyle, getDateLocale());
                } else if (dateStyle == NONE) {
                    result = DateFormat.getTimeInstance(getCalendar(), timeStyle, getDateLocale());
                } else {
                    result = DateFormat.getDateTimeInstance(getCalendar(), dateStyle, timeStyle, getDateLocale());
                }
            }
            return result;
        } catch (RuntimeException e) {
            IllegalArgumentException ex = new IllegalArgumentException("Cannot create DateFormat");
//#ifndef FOUNDATION
            ex.initCause(e);
//#endif
            throw ex;
        }
    }
	
    /**
     * Gets a number format according to the current settings.  If
     * there is an explicit (non-null) number format set, a copy of
     * that is returned. Otherwise, if there is a non-null number
     * locale, that is used.  Otherwise, the language priority list is
     * used. NONE should be used for the style, where only the date or
     * time format individually is being gotten.
     * @param style CURRENCY, NUMBER, INTEGER, SCIENTIFIC, PERCENT
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public NumberFormat getNumberFormat(int style) {
        try {
            NumberFormat result = null;
            if (numberFormats != null) {
                Object temp = numberFormats[style];
                if (temp instanceof NumberFormat) {
                    result = (NumberFormat) temp;
                } else {
                    result = new DecimalFormat((String)temp, new DecimalFormatSymbols(getDateLocale()));
                }	
            }
            if (result != null) {
                result = (NumberFormat) result.clone(); // clone for safety (later optimize)
                if (style == CURRENCY) {
                    result.setCurrency(getCurrency());
                }
                return result; 
            }
            // In the case of date formats, we don't have to look at more than one
            // locale. May be different for other cases
            switch (style) {
            case NUMBER: return NumberFormat.getInstance(getNumberLocale());
            case SCIENTIFIC: return NumberFormat.getScientificInstance(getNumberLocale());
            case INTEGER: return NumberFormat.getIntegerInstance(getNumberLocale());
            case PERCENT: return NumberFormat.getPercentInstance(getNumberLocale());
            case CURRENCY: result = NumberFormat.getCurrencyInstance(getNumberLocale());
                result.setCurrency(getCurrency());
                return result;
            }
        } catch (RuntimeException e) {}
        throw new IllegalArgumentException(); // fix later
    }
	
    /**
     * Sets a number format explicitly. Overrides the number locale
     * and the general locale settings.
     * @param style CURRENCY, NUMBER, INTEGER, SCIENTIFIC, PERCENT
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setNumberFormat(int style, DateFormat format) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        if (numberFormats == null) numberFormats = new Object[NUMBER_LIMIT];
        numberFormats[style] = (NumberFormat) format.clone(); // for safety
        return this;
    }
	
    /**
     * Sets a number format explicitly. Overrides the number locale
     * and the general locale settings.
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences setNumberFormat(int style, String formatPattern) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        if (numberFormats == null) numberFormats = new Object[NUMBER_LIMIT];
        // check to make sure it compiles
        new DecimalFormat((String)formatPattern, new DecimalFormatSymbols(getDateLocale()));
        numberFormats[style] = formatPattern; // for safety
        return this;
    }

    /**
     * Restore the object to the initial state.
     * @return this, for chaining
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public GlobalizationPreferences reset() {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify immutable object");
        }
        territory = null;
        calendar = null;
        collator = null;
        timezone = null;
        currency = null;
        dateFormats = null;
        numberFormats = null;
        dateLocale = null;
        numberLocale = null;
        locales = null;
        return this;
    }
	
    /**
     * This function can be overridden by subclasses to use different heuristics.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected String guessTerritory() {
        String result;
        // pass through locales to see if there is a territory.
        for (Iterator it = getLocales().iterator(); it.hasNext();) {
            ULocale locale = (ULocale)it.next();
            result = locale.getCountry();
            if (result.length() != 0) {
                return result;
            }
        }
        // if not, guess from the first language tag, or maybe from
        // intersection of languages, eg nl + fr => BE
        // TODO: fix using real data
        // for now, just use fixed values
        ULocale firstLocale = getLocale(0);
        String language = firstLocale.getLanguage();
        String script = firstLocale.getScript();
        result = null;
        if (script.length() != 0) {
            result = (String) language_territory_hack_map.get(language + "_" + script);
        }
        if (result == null) result = (String) language_territory_hack_map.get(language);
        if (result == null) result = "US"; // need *some* default
        return result;
    }

    /**
     * This function can be overridden by subclasses to use different heuristics
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected Currency guessCurrency() {
        return Currency.getInstance(new ULocale("und-" + getTerritory()));
    }

    /**
     * This function can be overridden by subclasses to use different heuristics
     * <b>It MUST return a 'safe' value,
     * one whose modification will not affect this object.</b>
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected List guessLocales() {
        List result = new ArrayList(0);
        result.add(ULocale.getDefault());
        return result;
    }

    /**
     * This function can be overridden by subclasses to use different heuristics.
     * <b>It MUST return a 'safe' value,
     * one whose modification will not affect this object.</b>
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected Collator guessCollator() {
        return Collator.getInstance(getLocale(0));
    }

    /**
     * This function can be overridden by subclasses to use different heuristics.
     * <b>It MUST return a 'safe' value,
     * one whose modification will not affect this object.</b>
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected TimeZone guessTimeZone() {
        // TODO fix using real data
        // for single-zone countries, pick that zone
        // for others, pick the most populous zone
        // for now, just use fixed value
        // NOTE: in a few cases can do better by looking at language. 
        // Eg haw+US should go to Pacific/Honolulu
        // fr+CA should go to America/Montreal
        String timezoneString = (String) territory_tzid_hack_map.get(getTerritory());
        if (timezoneString == null) {
            String[] attempt = ZoneMeta.getAvailableIDs(getTerritory());
            if (attempt.length == 0) {
                timezoneString = "Etc/GMT"; // gotta do something
            } else {
                int i;
                // this all needs to be fixed to use real data. But for now, do slightly better by skipping cruft
                for (i = 0; i < attempt.length; ++i) {
                    if (attempt[i].indexOf("/") >= 0) break;
                }
                if (i > attempt.length) i = 0;
                timezoneString = attempt[i];
            }
        }
        return TimeZone.getTimeZone(timezoneString);
    }

    /**
     * This function can be overridden by subclasses to use different heuristics.
     * <b>It MUST return a 'safe' value,
     * one whose modification will not affect this object.</b>
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected Calendar guessCalendar() {
        // TODO add better API
        return Calendar.getInstance(new ULocale("und-" + getTerritory()));
    }
	
    // PRIVATES
	
    private Object locales;
    private String territory;
    private Currency currency;
    private TimeZone timezone;
    private Calendar calendar;
    private Collator collator;
	
    private ULocale dateLocale;
    private Object[][] dateFormats;
    private ULocale numberLocale;
    private Object[] numberFormats;
	
    {
        reset();
    }
	
    /** WARNING: All of this data is temporary, until we start importing from CLDR!!!
     * 
     */
    private static final Map language_territory_hack_map = new HashMap();
    private static final String[][] language_territory_hack = {
        {"af", "ZA"},
        {"am", "ET"},
        {"ar", "SA"},
        {"as", "IN"},
        {"ay", "PE"},
        {"az", "AZ"},
        {"bal", "PK"},
        {"be", "BY"},
        {"bg", "BG"},
        {"bn", "IN"},
        {"bs", "BA"},
        {"ca", "ES"},
        {"ch", "MP"},
        {"cpe", "SL"},
        {"cs", "CZ"},
        {"cy", "GB"},
        {"da", "DK"},
        {"de", "DE"},
        {"dv", "MV"},
        {"dz", "BT"},
        {"el", "GR"},
        {"en", "US"},
        {"es", "ES"},
        {"et", "EE"},
        {"eu", "ES"},
        {"fa", "IR"},
        {"fi", "FI"},
        {"fil", "PH"},
        {"fj", "FJ"},
        {"fo", "FO"},
        {"fr", "FR"},
        {"ga", "IE"},
        {"gd", "GB"},
        {"gl", "ES"},
        {"gn", "PY"},
        {"gu", "IN"},
        {"gv", "GB"},
        {"ha", "NG"},
        {"he", "IL"},
        {"hi", "IN"},
        {"ho", "PG"},
        {"hr", "HR"},
        {"ht", "HT"},
        {"hu", "HU"},
        {"hy", "AM"},
        {"id", "ID"},
        {"is", "IS"},
        {"it", "IT"},
        {"ja", "JP"},
        {"ka", "GE"},
        {"kk", "KZ"},
        {"kl", "GL"},
        {"km", "KH"},
        {"kn", "IN"},
        {"ko", "KR"},
        {"kok", "IN"},
        {"ks", "IN"},
        {"ku", "TR"},
        {"ky", "KG"},
        {"la", "VA"},
        {"lb", "LU"},
        {"ln", "CG"},
        {"lo", "LA"},
        {"lt", "LT"},
        {"lv", "LV"},
        {"mai", "IN"},
        {"men", "GN"},
        {"mg", "MG"},
        {"mh", "MH"},
        {"mk", "MK"},
        {"ml", "IN"},
        {"mn", "MN"},
        {"mni", "IN"},
        {"mo", "MD"},
        {"mr", "IN"},
        {"ms", "MY"},
        {"mt", "MT"},
        {"my", "MM"},
        {"na", "NR"},
        {"nb", "NO"},
        {"nd", "ZA"},
        {"ne", "NP"},
        {"niu", "NU"},
        {"nl", "NL"},
        {"nn", "NO"},
        {"no", "NO"},
        {"nr", "ZA"},
        {"nso", "ZA"},
        {"ny", "MW"},
        {"om", "KE"},
        {"or", "IN"},
        {"pa", "IN"},
        {"pau", "PW"},
        {"pl", "PL"},
        {"ps", "PK"},
        {"pt", "BR"},
        {"qu", "PE"},
        {"rn", "BI"},
        {"ro", "RO"},
        {"ru", "RU"},
        {"rw", "RW"},
        {"sd", "IN"},
        {"sg", "CF"},
        {"si", "LK"},
        {"sk", "SK"},
        {"sl", "SI"},
        {"sm", "WS"},
        {"so", "DJ"},
        {"sq", "CS"},
        {"sr", "CS"},
        {"ss", "ZA"},
        {"st", "ZA"},
        {"sv", "SE"},
        {"sw", "KE"},
        {"ta", "IN"},
        {"te", "IN"},
        {"tem", "SL"},
        {"tet", "TL"},
        {"th", "TH"},
        {"ti", "ET"},
        {"tg", "TJ"},
        {"tk", "TM"},
        {"tkl", "TK"},
        {"tvl", "TV"},
        {"tl", "PH"},
        {"tn", "ZA"},
        {"to", "TO"},
        {"tpi", "PG"},
        {"tr", "TR"},
        {"ts", "ZA"},
        {"uk", "UA"},
        {"ur", "IN"},
        {"uz", "UZ"},
        {"ve", "ZA"},
        {"vi", "VN"},
        {"wo", "SN"},
        {"xh", "ZA"},
        {"zh", "CN"},
        {"zh_Hant", "TW"},
        {"zu", "ZA"},
        {"aa", "ET"},
        {"byn", "ER"},
        {"eo", "DE"},
        {"gez", "ET"},
        {"haw", "US"},
        {"iu", "CA"},
        {"kw", "GB"},
        {"sa", "IN"},
        {"sh", "HR"},
        {"sid", "ET"},
        {"syr", "SY"},
        {"tig", "ER"},
        {"tt", "RU"},
        {"wal", "ET"},	};
    static {
        for (int i = 0; i < language_territory_hack.length; ++i) {
            language_territory_hack_map.put(language_territory_hack[i][0],language_territory_hack[i][1]);
        }
    }
	
    static final Map territory_tzid_hack_map = new HashMap();
    static final String[][] territory_tzid_hack = {
        {"AQ", "Antarctica/McMurdo"},
        {"AR", "America/Buenos_Aires"},
        {"AU", "Australia/Sydney"},
        {"BR", "America/Sao_Paulo"},
        {"CA", "America/Toronto"},
        {"CD", "Africa/Kinshasa"},
        {"CL", "America/Santiago"},
        {"CN", "Asia/Shanghai"},
        {"EC", "America/Guayaquil"},
        {"ES", "Europe/Madrid"},
        {"GB", "Europe/London"},
        {"GL", "America/Godthab"},
        {"ID", "Asia/Jakarta"},
        {"ML", "Africa/Bamako"},
        {"MX", "America/Mexico_City"},
        {"MY", "Asia/Kuala_Lumpur"},
        {"NZ", "Pacific/Auckland"},
        {"PT", "Europe/Lisbon"},
        {"RU", "Europe/Moscow"},
        {"UA", "Europe/Kiev"},
        {"US", "America/New_York"},
        {"UZ", "Asia/Tashkent"},
        {"PF", "Pacific/Tahiti"},
        {"FM", "Pacific/Kosrae"},
        {"KI", "Pacific/Tarawa"},
        {"KZ", "Asia/Almaty"},
        {"MH", "Pacific/Majuro"},
        {"MN", "Asia/Ulaanbaatar"},
        {"SJ", "Arctic/Longyearbyen"},
        {"UM", "Pacific/Midway"},	
    };
    static {
        for (int i = 0; i < territory_tzid_hack.length; ++i) {
            territory_tzid_hack_map.put(territory_tzid_hack[i][0],territory_tzid_hack[i][1]);
        }
    }

    private boolean frozen;

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public boolean isFrozen() {
        return frozen;
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public Object freeze() {
        frozen = true;
        return this;
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public Object cloneAsThawed() {
        try {
            GlobalizationPreferences result = (GlobalizationPreferences) clone();
            result.frozen = false;
            return result;
        } catch (CloneNotSupportedException e) {
            // will always work
            return null;
        }
    }
}

