/* GENERATED SOURCE. DO NOT MODIFY. */
/*
 *******************************************************************************
 * Copyright (C) 2009-2015, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package android.icu.text;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import android.icu.impl.ICUConfig;
import android.icu.lang.UScript;
import android.icu.text.DisplayContext.Type;
import android.icu.util.IllformedLocaleException;
import android.icu.util.ULocale;

/**
 * Returns display names of ULocales and components of ULocales. For
 * more information on language, script, region, variant, key, and
 * values, see {@link android.icu.util.ULocale}.
 * @hide All android.icu classes are currently hidden
 */
public abstract class LocaleDisplayNames {
    /**
     * Enum used in {@link #getInstance(ULocale, DialectHandling)}.
     */
    public enum DialectHandling {
        /**
         * Use standard names when generating a locale name,
         * e.g. en_GB displays as 'English (United Kingdom)'.
         */
        STANDARD_NAMES,
        /**
         * Use dialect names when generating a locale name,
         * e.g. en_GB displays as 'British English'.
         */
        DIALECT_NAMES
    }

    // factory methods
    /**
     * Convenience overload of {@link #getInstance(ULocale, DialectHandling)} that specifies
     * STANDARD dialect handling.
     * @param locale the display locale
     * @return a LocaleDisplayNames instance
     */
    public static LocaleDisplayNames getInstance(ULocale locale) {
        return getInstance(locale, DialectHandling.STANDARD_NAMES);
    };

    /**
     * Convenience overload of {@link #getInstance(Locale, DisplayContext...)} that specifies
     * {@link DisplayContext#STANDARD_NAMES}.
     * @param locale the display JDK locale
     * @return a LocaleDisplayNames instance
     */
    public static LocaleDisplayNames getInstance(Locale locale) {
        return getInstance(ULocale.forLocale(locale));
    };

    /**
     * Returns an instance of LocaleDisplayNames that returns names formatted for the provided locale,
     * using the provided dialectHandling.
     * @param locale the display locale
     * @param dialectHandling how to select names for locales
     * @return a LocaleDisplayNames instance
     */
    public static LocaleDisplayNames getInstance(ULocale locale, DialectHandling dialectHandling) {
        LocaleDisplayNames result = null;
        if (FACTORY_DIALECTHANDLING != null) {
            try {
                result = (LocaleDisplayNames) FACTORY_DIALECTHANDLING.invoke(null,
                        locale, dialectHandling);
            } catch (InvocationTargetException e) {
                // fall through
            } catch (IllegalAccessException e) {
                // fall through
            }
        }
        if (result == null) {
            result = new LastResortLocaleDisplayNames(locale, dialectHandling);
        }
        return result;
    }

    /**
     * Returns an instance of LocaleDisplayNames that returns names formatted for the provided locale,
     * using the provided DisplayContext settings
     * @param locale the display locale
     * @param contexts one or more context settings (e.g. for dialect
     *              handling, capitalization, etc.
     * @return a LocaleDisplayNames instance
     */
    public static LocaleDisplayNames getInstance(ULocale locale, DisplayContext... contexts) {
        LocaleDisplayNames result = null;
        if (FACTORY_DISPLAYCONTEXT != null) {
            try {
                result = (LocaleDisplayNames) FACTORY_DISPLAYCONTEXT.invoke(null,
                        locale, (Object[])contexts);
            } catch (InvocationTargetException e) {
                // fall through
            } catch (IllegalAccessException e) {
                // fall through
            }
        }
        if (result == null) {
            result = new LastResortLocaleDisplayNames(locale, contexts);
        }
        return result;
    }

    /**
     * Returns an instance of LocaleDisplayNames that returns names formatted for the provided JDK
     * locale, using the provided DisplayContext settings
     * @param locale the display JDK locale
     * @param contexts one or more context settings (e.g. for dialect
     *              handling, capitalization, etc.
     * @return a LocaleDisplayNames instance
     */
    public static LocaleDisplayNames getInstance(Locale locale, DisplayContext... contexts) {
        return getInstance(ULocale.forLocale(locale), contexts);
    }

    // getters for state
    /**
     * Returns the locale used to determine the display names. This is not necessarily the same
     * locale passed to {@link #getInstance}.
     * @return the display locale
     */
    public abstract ULocale getLocale();

    /**
     * Returns the dialect handling used in the display names.
     * @return the dialect handling enum
     */
    public abstract DialectHandling getDialectHandling();

    /**
     * Returns the current value for a specified DisplayContext.Type.
     * @param type the DisplayContext.Type whose value to return
     * @return the current DisplayContext setting for the specified type
     */
    public abstract DisplayContext getContext(DisplayContext.Type type);

    // names for entire locales
    /**
     * Returns the display name of the provided ulocale.
     * @param locale the locale whose display name to return
     * @return the display name of the provided locale
     */
    public abstract String localeDisplayName(ULocale locale);

    /**
     * Returns the display name of the provided locale.
     * @param locale the locale whose display name to return
     * @return the display name of the provided locale
     */
    public abstract String localeDisplayName(Locale locale);

    /**
     * Returns the display name of the provided locale id.
     * @param localeId the id of the locale whose display name to return
     * @return the display name of the provided locale
     */
    public abstract String localeDisplayName(String localeId);

    // names for components of a locale id
    /**
     * Returns the display name of the provided language code.
     * @param lang the language code
     * @return the display name of the provided language code
     */
    public abstract String languageDisplayName(String lang);

    /**
     * Returns the display name of the provided script code.
     * @param script the script code
     * @return the display name of the provided script code
     */
    public abstract String scriptDisplayName(String script);

    /**
     * Returns the display name of the provided script code
     * when used in the context of a full locale name.
     * @param script the script code
     * @return the display name of the provided script code
     * @deprecated This API is ICU internal only.
     * @hide original deprecated method
     * @hide draft / provisional / internal are hidden on Android
     */
    @Deprecated
    public String scriptDisplayNameInContext(String script) {
        return scriptDisplayName(script);
    }

    /**
     * Returns the display name of the provided script code.  See
     * {@link android.icu.lang.UScript} for recognized script codes.
     * @param scriptCode the script code number
     * @return the display name of the provided script code
     */
    public abstract String scriptDisplayName(int scriptCode);

    /**
     * Returns the display name of the provided region code.
     * @param region the region code
     * @return the display name of the provided region code
     */
    public abstract String regionDisplayName(String region);

    /**
     * Returns the display name of the provided variant.
     * @param variant the variant string
     * @return the display name of the provided variant
     */
    public abstract String variantDisplayName(String variant);

    /**
     * Returns the display name of the provided locale key.
     * @param key the locale key name
     * @return the display name of the provided locale key
     */
    public abstract String keyDisplayName(String key);

    /**
     * Returns the display name of the provided value (used with the provided key).
     * @param key the locale key name
     * @param value the locale key's value
     * @return the display name of the provided value
     */
    public abstract String keyValueDisplayName(String key, String value);


    /** 
     * Return a list of information used to construct a UI list of locale names. 
     * @param collator how to collate—should normally be Collator.getInstance(getDisplayLocale()) 
     * @param inSelf if true, compares the nameInSelf, otherwise the nameInDisplayLocale. 
     * Set depending on which field (displayLocale vs self) is to show up in the UI. 
     * If both are to show up in the UI, then it should be the one used for the primary sort order. 
     * @param localeSet a list of locales to present in a UI list. The casing uses the settings in the LocaleDisplayNames instance. 
     * @return an ordered list of UiListItems. 
     * @throws IllformedLocaleException if any of the locales in localeSet are malformed.
     * @hide draft / provisional / internal are hidden on Android
     */ 
    public List<UiListItem> getUiList(Set<ULocale> localeSet, boolean inSelf, Comparator<Object> collator) { 
        return getUiListCompareWholeItems(localeSet, UiListItem.getComparator(collator, inSelf)); 
    } 

    /** 
     * Return a list of information used to construct a UI list of locale names, providing more access to control the sorting.  
     * Normally use getUiList instead. 
     * @param comparator how to sort the UiListItems in the result. 
     * @param localeSet a list of locales to present in a UI list. The casing uses the settings in the LocaleDisplayNames instance. 
     * @return an ordered list of UiListItems. 
     * @throws IllformedLocaleException if any of the locales in localeSet are malformed.
     * @hide draft / provisional / internal are hidden on Android
     */
    public abstract List<UiListItem> getUiListCompareWholeItems(Set<ULocale> localeSet, Comparator<UiListItem> comparator);

    /** 
     * Struct-like class used to return information for constructing a UI list, each corresponding to a locale. 
     * @hide draft / provisional / internal are hidden on Android
     */
    public static class UiListItem { 
        /** 
         * Returns the minimized locale for an input locale, such as sr-Cyrl → sr 
         * @hide draft / provisional / internal are hidden on Android
         */
        public final ULocale minimized; 
        /** 
         * Returns the modified locale for an input locale, such as sr → sr-Cyrl, where there is also an sr-Latn in the list 
         * @hide draft / provisional / internal are hidden on Android
         */
        public final ULocale modified; 
        /** 
         * Returns the name of the modified locale in the display locale, such as "Englisch (VS)" (for 'en-US', where the display locale is 'de'). 
         * @hide draft / provisional / internal are hidden on Android
         */
        public final String nameInDisplayLocale; 
        /** 
         * Returns the name of the modified locale in itself, such as "English (US)" (for 'en-US'). 
         * @hide draft / provisional / internal are hidden on Android
         */
        public final String nameInSelf; 

        /**  
         * Constructor, normally only called internally. 
         * @param minimized locale for an input locale 
         * @param modified modified for an input locale 
         * @param nameInDisplayLocale name of the modified locale in the display locale 
         * @param nameInSelf name of the modified locale in itself 
         * @hide draft / provisional / internal are hidden on Android
         */
        public UiListItem(ULocale minimized, ULocale modified, String nameInDisplayLocale, String nameInSelf) { 
            this.minimized = minimized; 
            this.modified = modified; 
            this.nameInDisplayLocale = nameInDisplayLocale; 
            this.nameInSelf = nameInSelf; 
        } 

        /**
         * {@inheritDoc}
         * 
         * @hide draft / provisional / internal are hidden on Android
         */
        @Override 
        public boolean equals(Object obj) { 
            UiListItem other = (UiListItem)obj; 
            return nameInDisplayLocale.equals(other.nameInDisplayLocale) 
                    && nameInSelf.equals(other.nameInSelf) 
                    && minimized.equals(other.minimized) 
                    && modified.equals(other.modified); 
        } 

        /**
         * {@inheritDoc}
         * 
         * @hide draft / provisional / internal are hidden on Android
         */
        @Override 
        public int hashCode() { 
            return modified.hashCode() ^ nameInDisplayLocale.hashCode(); 
        } 

        /**
         * {@inheritDoc}
         * 
         * @hide draft / provisional / internal are hidden on Android
         */
        @Override 
        public String toString() { 
            return "{" + minimized + ", " + modified + ", " + nameInDisplayLocale + ", " + nameInSelf  + "}"; 
        } 

        /**
         * Return a comparator that compares the locale names for the display locale or the in-self names,
         * depending on an input parameter.
         * @param inSelf if true, compares the nameInSelf, otherwise the nameInDisplayLocale
         * @param comparator (meant for strings, but because Java Collator doesn't have &lt;String>...)
         * @return UiListItem comparator
         * @hide draft / provisional / internal are hidden on Android
         */
        public static Comparator<UiListItem> getComparator(Comparator<Object> comparator, boolean inSelf) {
            return new UiListItemComparator(comparator, inSelf);
        }

        private static class UiListItemComparator implements Comparator<UiListItem> { 
            private final Comparator<Object> collator; 
            private final boolean useSelf; 
            UiListItemComparator(Comparator<Object> collator, boolean useSelf) { 
                this.collator = collator; 
                this.useSelf = useSelf; 
            } 
            public int compare(UiListItem o1, UiListItem o2) { 
                int result = useSelf ? collator.compare(o1.nameInSelf, o2.nameInSelf) 
                        : collator.compare(o1.nameInDisplayLocale, o2.nameInDisplayLocale); 
                return result != 0 ? result : o1.modified.compareTo(o2.modified); // just in case 
            } 
        } 
    } 
    /**
     * Sole constructor.  (For invocation by subclass constructors,
     * typically implicit.)
     * @deprecated This API is ICU internal only.
     * @hide original deprecated method
     * @hide draft / provisional / internal are hidden on Android
     */
    @Deprecated
    protected LocaleDisplayNames() {
    }

    private static final Method FACTORY_DIALECTHANDLING;
    private static final Method FACTORY_DISPLAYCONTEXT;

    static {
        String implClassName = ICUConfig.get("android.icu.text.LocaleDisplayNames.impl", "android.icu.impl.LocaleDisplayNamesImpl");

        Method factoryDialectHandling = null;
        Method factoryDisplayContext = null;

        try {
            Class<?> implClass = Class.forName(implClassName);
            try {
                factoryDialectHandling = implClass.getMethod("getInstance",
                        ULocale.class, DialectHandling.class);
            } catch (NoSuchMethodException e) {
            }
            try {
                factoryDisplayContext = implClass.getMethod("getInstance",
                        ULocale.class, DisplayContext[].class);
            } catch (NoSuchMethodException e) {
            }

        } catch (ClassNotFoundException e) {
            // fallback to last resort impl
        }

        FACTORY_DIALECTHANDLING = factoryDialectHandling;
        FACTORY_DISPLAYCONTEXT = factoryDisplayContext;
    }

    /**
     * Minimum implementation of LocaleDisplayNames
     */
    private static class LastResortLocaleDisplayNames extends LocaleDisplayNames {

        private ULocale locale;
        private DisplayContext[] contexts;

        private LastResortLocaleDisplayNames(ULocale locale, DialectHandling dialectHandling) {
            this.locale = locale;
            DisplayContext context = (dialectHandling == DialectHandling.DIALECT_NAMES) ?
                    DisplayContext.DIALECT_NAMES : DisplayContext.STANDARD_NAMES;
            this.contexts = new DisplayContext[] {context};
        }

        private LastResortLocaleDisplayNames(ULocale locale, DisplayContext... contexts) {
            this.locale = locale;
            this.contexts = new DisplayContext[contexts.length];
            System.arraycopy(contexts, 0, this.contexts, 0, contexts.length);
        }

        @Override
        public ULocale getLocale() {
            return locale;
        }

        @Override
        public DialectHandling getDialectHandling() {
            DialectHandling result = DialectHandling.STANDARD_NAMES;
            for (DisplayContext context : contexts) {
                if (context.type() == DisplayContext.Type.DIALECT_HANDLING) {
                    if (context.value() == DisplayContext.DIALECT_NAMES.ordinal()) {
                        result = DialectHandling.DIALECT_NAMES;
                        break;
                    }
                }
            }
            return result;
        }

        @Override
        public DisplayContext getContext(Type type) {
            DisplayContext result = DisplayContext.STANDARD_NAMES;  // final fallback
            for (DisplayContext context : contexts) {
                if (context.type() == type) {
                    result = context;
                    break;
                }
            }
            return result;
        }

        @Override
        public String localeDisplayName(ULocale locale) {
            return locale.getName();
        }

        @Override
        public String localeDisplayName(Locale locale) {
            return ULocale.forLocale(locale).getName();
        }

        @Override
        public String localeDisplayName(String localeId) {
            return new ULocale(localeId).getName();
        }

        @Override
        public String languageDisplayName(String lang) {
            return lang;
        }

        @Override
        public String scriptDisplayName(String script) {
            return script;
        }

        @Override
        public String scriptDisplayName(int scriptCode) {
            return UScript.getShortName(scriptCode);
        }

        @Override
        public String regionDisplayName(String region) {
            return region;
        }

        @Override
        public String variantDisplayName(String variant) {
            return variant;
        }

        @Override
        public String keyDisplayName(String key) {
            return key;
        }

        @Override
        public String keyValueDisplayName(String key, String value) {
            return value;
        }

        @Override 
        public List<UiListItem> getUiListCompareWholeItems(Set<ULocale> localeSet, Comparator<UiListItem> comparator) { 
            return Collections.emptyList(); 
        } 
    }
}
