/*
 **************************************************************************************
 * Copyright (C) 2009-2013, Google, Inc.; International Business Machines Corporation *
 * and others. All Rights Reserved.                                                   *
 **************************************************************************************
 */
package com.ibm.icu.util;

import java.util.MissingResourceException;

import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Category;

/**
 * A class for accessing miscellaneous data in the locale bundles
 * @author ram
 * @stable ICU 2.8
 */
public final class LocaleData {
    
//    private static final String EXEMPLAR_CHARS      = "ExemplarCharacters";
    private static final String MEASUREMENT_SYSTEM  = "MeasurementSystem";
    private static final String PAPER_SIZE          = "PaperSize";
    private static final String LOCALE_DISPLAY_PATTERN  = "localeDisplayPattern";
    private static final String PATTERN             = "pattern";
    private static final String SEPARATOR           = "separator";
    private boolean noSubstitute;
    private ICUResourceBundle bundle;
    private ICUResourceBundle langBundle;

    /**
     * EXType for {@link #getExemplarSet(int, int)}.
     * @stable ICU 3.4
     */
    public static final int ES_STANDARD = 0;

    /**
     * EXType for {@link #getExemplarSet(int, int)}.
     * @stable ICU 3.4
     */
    public static final int ES_AUXILIARY = 1;

    /**
     * EXType for {@link #getExemplarSet(int, int)}.
     * @stable ICU 4.4
     */
   public static final int ES_INDEX = 2;

   /**
    * EXType for {@link #getExemplarSet(int, int)}.
    * Note: This type is no longer supported.
    * @deprecated ICU 51
    */
    public static final int ES_CURRENCY = 3;

    /**
     * EXType for {@link #getExemplarSet(int, int)}.
     * @stable ICU 49
     */
     public static final int ES_PUNCTUATION = 4;

    /**
     * Count of EXTypes for {@link #getExemplarSet(int, int)}.
     * @stable ICU 3.4
     */
    public static final int ES_COUNT = 5;
    
    /**
     * Delimiter type for {@link #getDelimiter(int)}.
     * @stable ICU 3.4
     */
    public static final int QUOTATION_START = 0;

    /**
     * Delimiter type for {@link #getDelimiter(int)}.
     * @stable ICU 3.4
     */
    public static final int QUOTATION_END = 1;

    /**
     * Delimiter type for {@link #getDelimiter(int)}.
     * @stable ICU 3.4
     */
    public static final int ALT_QUOTATION_START = 2;

    /**
     * Delimiter type for {@link #getDelimiter(int)}.
     * @stable ICU 3.4
     */
    public static final int ALT_QUOTATION_END = 3;

    /**
     * Count of delimiter types for {@link #getDelimiter(int)}.
     * @stable ICU 3.4
     */
    public static final int DELIMITER_COUNT = 4;

    // private constructor to prevent default construction
    ///CLOVER:OFF
    private LocaleData(){}
    ///CLOVER:ON

    /**
     * Returns the set of exemplar characters for a locale.
     *
     * @param locale    Locale for which the exemplar character set
     *                  is to be retrieved.
     * @param options   Bitmask for options to apply to the exemplar pattern.
     *                  Specify zero to retrieve the exemplar set as it is
     *                  defined in the locale data.  Specify
     *                  UnicodeSet.CASE to retrieve a case-folded exemplar
     *                  set.  See {@link UnicodeSet#applyPattern(String,
     *                  int)} for a complete list of valid options.  The
     *                  IGNORE_SPACE bit is always set, regardless of the
     *                  value of 'options'.
     * @return          The set of exemplar characters for the given locale.
     * @stable ICU 3.0
     */
    public static UnicodeSet getExemplarSet(ULocale locale, int options) {
        return LocaleData.getInstance(locale).getExemplarSet(options, ES_STANDARD);
     }
    
    /**
     * Returns the set of exemplar characters for a locale.
     *
     * @param locale    Locale for which the exemplar character set
     *                  is to be retrieved.
     * @param options   Bitmask for options to apply to the exemplar pattern.
     *                  Specify zero to retrieve the exemplar set as it is
     *                  defined in the locale data.  Specify
     *                  UnicodeSet.CASE to retrieve a case-folded exemplar
     *                  set.  See {@link UnicodeSet#applyPattern(String,
     *                  int)} for a complete list of valid options.  The
     *                  IGNORE_SPACE bit is always set, regardless of the
     *                  value of 'options'.
     * @param extype    The type of exemplar character set to retrieve.
     * @return          The set of exemplar characters for the given locale.
     * @stable ICU 3.0
     */
    public static UnicodeSet getExemplarSet(ULocale locale, int options, int extype) {
        return LocaleData.getInstance(locale).getExemplarSet(options, extype);
     }
    
    /**
     * Returns the set of exemplar characters for a locale.
     *
     * @param options   Bitmask for options to apply to the exemplar pattern.
     *                  Specify zero to retrieve the exemplar set as it is
     *                  defined in the locale data.  Specify
     *                  UnicodeSet.CASE to retrieve a case-folded exemplar
     *                  set.  See {@link UnicodeSet#applyPattern(String,
     *                  int)} for a complete list of valid options.  The
     *                  IGNORE_SPACE bit is always set, regardless of the
     *                  value of 'options'.
     * @param extype    The type of exemplar set to be retrieved,
     *                  ES_STANDARD, ES_INDEX, ES_AUXILIARY, or ES_PUNCTUATION
     * @return          The set of exemplar characters for the given locale.
     * @stable ICU 3.4
     */
    public UnicodeSet getExemplarSet(int options, int extype) {
        String [] exemplarSetTypes = { 
            "ExemplarCharacters", "AuxExemplarCharacters",
            "ExemplarCharactersIndex", "ExemplarCharactersCurrency",
            "ExemplarCharactersPunctuation"
        };

        if (extype == ES_CURRENCY) {
            // currency symbol exemplar is no longer available
            return new UnicodeSet();
        }

        try{
            ICUResourceBundle stringBundle = (ICUResourceBundle) bundle.get(exemplarSetTypes[extype]);
    
            if ( noSubstitute && (stringBundle.getLoadingStatus() == ICUResourceBundle.FROM_ROOT) )
               return null;
    
            String unicodeSetPattern = stringBundle.getString();
            if (extype == ES_PUNCTUATION) {
                try {
                    return new UnicodeSet(unicodeSetPattern, UnicodeSet.IGNORE_SPACE | options);
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException("Can't create exemplars for " + exemplarSetTypes[extype] + " in " + bundle.getLocale(), e);
                }
            }
            return new UnicodeSet(unicodeSetPattern, UnicodeSet.IGNORE_SPACE | options);
        }catch(MissingResourceException ex){
            if(extype==LocaleData.ES_AUXILIARY){
                return new UnicodeSet();
            } else if (extype==LocaleData.ES_INDEX){
                return null;
            }
            throw ex;
        }
    }

    /**
     * Gets the LocaleData object associated with the ULocale specified in locale
     *
     * @param locale    Locale with thich the locale data object is associated.
     * @return          A locale data object.
     * @stable ICU 3.4
     */
    public static final LocaleData getInstance(ULocale locale) {
       LocaleData ld = new LocaleData();
       ld.bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale);
       ld.langBundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_LANG_BASE_NAME, locale);
       ld.noSubstitute = false;
       return ld;
    }
    
    /**
     * Gets the LocaleData object associated with the default <code>FORMAT</code> locale
     *
     * @return          A locale data object.
     * @see Category#FORMAT
     * @stable ICU 3.4
     */
    public static final LocaleData getInstance() {
       return LocaleData.getInstance(ULocale.getDefault(Category.FORMAT));
    }

    /**
     * Sets the "no substitute" behavior of this locale data object.
     *
     * @param setting   Value for the no substitute behavior.  If TRUE,
     *                  methods of this locale data object will return
     *                  an error when no data is available for that method,
     *                  given the locale ID supplied to the constructor.
     * @stable ICU 3.4
     */
    public void setNoSubstitute(boolean setting) {
       noSubstitute = setting;
    }

    /**
     * Gets the "no substitute" behavior of this locale data object.
     *
     * @return          Value for the no substitute behavior.  If TRUE,
     *                  methods of this locale data object will return
     *                  an error when no data is available for that method,
     *                  given the locale ID supplied to the constructor.
     * @stable ICU 3.4
     */
    public boolean getNoSubstitute() {
       return noSubstitute;
    }

    private static final String [] DELIMITER_TYPES = {
                                 "quotationStart", 
                                 "quotationEnd", 
                                 "alternateQuotationStart", 
                                 "alternateQuotationEnd"
    };

    /**
     * Retrieves a delimiter string from the locale data.
     *
     * @param type      The type of delimiter string desired.  Currently,
     *                  the valid choices are QUOTATION_START, QUOTATION_END,
     *                  ALT_QUOTATION_START, or ALT_QUOTATION_END.
     * @return          The desired delimiter string.
     * @stable ICU 3.4
     */
    public String getDelimiter(int type) {
        ICUResourceBundle delimitersBundle = (ICUResourceBundle) bundle.get("delimiters");
        // Only some of the quotation marks may be here. So we make sure that we do a multilevel fallback.
        ICUResourceBundle stringBundle = delimitersBundle.getWithFallback(DELIMITER_TYPES[type]);

        if ( noSubstitute && (stringBundle.getLoadingStatus() == ICUResourceBundle.FROM_ROOT) )
           return null;

        return stringBundle.getString();
    }

    /**
     * Utility for getMeasurementSystem and getPaperSize
     */
    private static UResourceBundle measurementTypeBundleForLocale(ULocale locale, String measurementType){
        // Much of this is taken from getCalendarType in impl/CalendarUtil.java
        UResourceBundle measTypeBundle = null;
    	ULocale fullLoc = ULocale.addLikelySubtags(locale);
    	String region = fullLoc.getCountry();
		try {
			UResourceBundle rb = UResourceBundle.getBundleInstance(
									ICUResourceBundle.ICU_BASE_NAME,
									"supplementalData",
									ICUResourceBundle.ICU_DATA_CLASS_LOADER);
			UResourceBundle measurementData = rb.get("measurementData");
			UResourceBundle measDataBundle = null;
			try {
				measDataBundle = measurementData.get(region);
				measTypeBundle = measDataBundle.get(measurementType);
			} catch (MissingResourceException mre) {
				// use "001" as fallback
				measDataBundle = measurementData.get("001");
				measTypeBundle = measDataBundle.get(measurementType);
			}
		} catch (MissingResourceException mre) {
			// fall through
		}
		return measTypeBundle;
    }


    /**
     * Enumeration for representing the measurement systems.
     * @stable ICU 2.8
     */
    public static final class MeasurementSystem{
        /** 
         * Measurement system specified by Le Syst&#x00E8;me International d'Unit&#x00E9;s (SI)
         * otherwise known as Metric system. 
         * @stable ICU 2.8
         */
        public static final MeasurementSystem SI = new MeasurementSystem(0);
 
        /** 
         * Measurement system followed in the United States of America. 
         * @stable ICU 2.8
         */ 
        public static final MeasurementSystem US = new MeasurementSystem(1);
    
        private int systemID;
        private MeasurementSystem(int id){
            systemID = id;
        }

        private boolean equals(int id){
            return systemID == id;
        }
    }
   
    /**
     * Returns the measurement system used in the locale specified by the locale.
     *
     * @param locale      The locale for which the measurement system to be retrieved.
     * @return MeasurementSystem the measurement system used in the locale.
     * @stable ICU 3.0
     */
    public static final MeasurementSystem getMeasurementSystem(ULocale locale){
        UResourceBundle sysBundle = measurementTypeBundleForLocale(locale, MEASUREMENT_SYSTEM);
        
        int system = sysBundle.getInt();
        if(MeasurementSystem.US.equals(system)){
            return MeasurementSystem.US;
        }
        if(MeasurementSystem.SI.equals(system)){
            return MeasurementSystem.SI;
        }
        // return null if the object is null or is not an instance
        // of integer indicating an error
        return null;
    }
    
    /**
     * A class that represents the size of letter head 
     * used in the country
     * @stable ICU 2.8
     */
    public static final class PaperSize{
        private int height;
        private int width;
        
        private PaperSize(int h, int w){
            height = h;
            width = w;
        }
        /** 
         * Retruns the height of the paper
         * @return the height 
         * @stable ICU 2.8
         */
        public int getHeight(){
            return height;
        }
        /**
         * Returns the width of the paper
         * @return the width
         * @stable ICU 2.8
         */
        public int getWidth(){
            return width;
        }
    }
    
    /**
     * Returns the size of paper used in the locale. The paper sizes returned are always in 
     * <em> milli-meters<em>.
     * @param locale The locale for which the measurement system to be retrieved. 
     * @return The paper size used in the locale
     * @stable ICU 3.0
     */
    public static final PaperSize getPaperSize(ULocale locale){
        UResourceBundle obj = measurementTypeBundleForLocale(locale, PAPER_SIZE);
        int[] size = obj.getIntVector();
        return new PaperSize(size[0], size[1]);
    }
    
    /**
     * Returns LocaleDisplayPattern for this locale, e.g., {0}({1})
     * @return locale display pattern as a String.
     * @stable ICU 4.2
     */ 
    public String getLocaleDisplayPattern() {
      ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);
      String localeDisplayPattern = locDispBundle.getStringWithFallback(PATTERN);
      return localeDisplayPattern;
    }
    
    /**
     * Returns LocaleDisplaySeparator for this locale.
     * @return locale display separator as a char.
     * @stable ICU 4.2
     */ 
    public String getLocaleSeparator() {
      String sub0 = "{0}";
      String sub1 = "{1}";
      ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);
      String  localeSeparator = locDispBundle.getStringWithFallback(SEPARATOR);
      int index0 = localeSeparator.indexOf(sub0);
      int index1 = localeSeparator.indexOf(sub1);
      if (index0 >= 0 && index1 >= 0 && index0 <= index1) {
          return localeSeparator.substring(index0 + sub0.length(), index1);
      }
      return localeSeparator;
    }
    
    private static VersionInfo gCLDRVersion = null;
    
    /**
     * Returns the current CLDR version
     * @stable ICU 4.2
     */
    public static VersionInfo getCLDRVersion() {
        // fetching this data should be idempotent.
        if(gCLDRVersion == null) {
            // from ZoneMeta.java
            UResourceBundle supplementalDataBundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
            UResourceBundle cldrVersionBundle = supplementalDataBundle.get("cldrVersion");
            gCLDRVersion = VersionInfo.getInstance(cldrVersionBundle.getString());
        }
        return gCLDRVersion;
    }
}
