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

import java.util.EnumMap;
import java.util.Locale;

import com.ibm.icu.impl.CalendarData;
import com.ibm.icu.impl.ICUCache;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.SimpleCache;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;


/**
 * Formats simple relative dates. There are two types of relative dates that
 * it handles:
 * <ul>
 *   <li>relative dates with a quantity e.g "in 5 days"</li>
 *   <li>relative dates without a quantity e.g "next Tuesday"</li>
 * </ul>
 * <p>
 * This API is very basic and is intended to be a building block for more
 * fancy APIs. The caller tells it exactly what to display in a locale
 * independent way. While this class automatically provides the correct plural
 * forms, the grammatical form is otherwise as neutral as possible. It is the
 * caller's responsibility to handle cut-off logic such as deciding between
 * displaying "in 7 days" or "in 1 week." This API supports relative dates
 * involving one single unit. This API does not support relative dates
 * involving compound units.
 * e.g "in 5 days and 4 hours" nor does it support parsing.
 * This class is both immutable and thread-safe.
 * <p>
 * Here are some examples of use:
 * <blockquote>
 * <pre>
 * RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 * fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 * fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 * fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"
 * 
 * fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 * fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 * fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 * fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"
 * 
 * fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 * fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 * fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"
 * 
 * fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"
 * </pre>
 * </blockquote>
 * <p>
 * In the future, we may add more forms, such as abbreviated/short forms
 * (3 secs ago), and relative day periods ("yesterday afternoon"), etc.
 * 
 * @draft ICU 53
 * @provisional This API might change or be removed in a future release.
 */
public final class RelativeDateTimeFormatter {
    
    /**
     * The formatting style
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     *
     */
    public static enum Style {
        
        /**
         * Everything spelled out.
         * @draft ICU 54
         * @provisional This API might change or be removed in a future release.
         */
        LONG,
        
        /**
         * Abbreviations used when possible.
         * @draft ICU 54
         * @provisional This API might change or be removed in a future release.
         */
        SHORT,
        
        /**
         * Use single letters when possible.
         * @draft ICU 54
         * @provisional This API might change or be removed in a future release.
         */
        NARROW,
    }
    
    /**
     * Represents the unit for formatting a relative date. e.g "in 5 days"
     * or "in 3 months"
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public static enum RelativeUnit {
        
        /**
         * Seconds
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        SECONDS,
        
        /**
         * Minutes
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        MINUTES,
        
       /**
        * Hours
        * @draft ICU 53
        * @provisional This API might change or be removed in a future release.
        */
        HOURS,
        
        /**
         * Days
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        DAYS,
        
        /**
         * Weeks
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        WEEKS,
        
        /**
         * Months
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        MONTHS,
        
        /**
         * Years
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        YEARS,
    }
    
    /**
     * Represents an absolute unit.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public static enum AbsoluteUnit {
        
       /**
        * Sunday
        * @draft ICU 53
        * @provisional This API might change or be removed in a future release.
        */
        SUNDAY,
        
        /**
         * Monday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        MONDAY,
        
        /**
         * Tuesday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        TUESDAY,
        
        /**
         * Wednesday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        WEDNESDAY,
        
        /**
         * Thursday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        THURSDAY,
        
        /**
         * Friday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        FRIDAY,
        
        /**
         * Saturday
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        SATURDAY,
        
        /**
         * Day
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        DAY,
        
        /**
         * Week
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        WEEK,
        
        /**
         * Month
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        MONTH,
        
        /**
         * Year
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        YEAR,
        
        /**
         * Now
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        NOW,
      }

      /**
       * Represents a direction for an absolute unit e.g "Next Tuesday"
       * or "Last Tuesday"
       * @draft ICU 53
       * @provisional This API might change or be removed in a future release.
       */
      public static enum Direction {
          
          /**
           * Two before. Not fully supported in every locale
           * @draft ICU 53
           * @provisional This API might change or be removed in a future release.
           */
          LAST_2,

          
          /**
           * Last
           * @draft ICU 53
           * @provisional This API might change or be removed in a future release.
           */  
        LAST,
        
        /**
         * This
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        THIS,
        
        /**
         * Next
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        NEXT,
        
        /**
         * Two after. Not fully supported in every locale
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        NEXT_2,
        
        /**
         * Plain, which means the absence of a qualifier
         * @draft ICU 53
         * @provisional This API might change or be removed in a future release.
         */
        PLAIN;
      }
    
    /**
     * Returns a RelativeDateTimeFormatter for the default locale.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance() {
        return getInstance(ULocale.getDefault(), null, Style.LONG, DisplayContext.CAPITALIZATION_NONE);
    }
    
    /**
     * Returns a RelativeDateTimeFormatter for a particular locale.
     * 
     * @param locale the locale.
     * @return An instance of RelativeDateTimeFormatter.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance(ULocale locale) {
        return getInstance(locale, null, Style.LONG, DisplayContext.CAPITALIZATION_NONE);
    }
    
    /**
     * Returns a RelativeDateTimeFormatter for a particular JDK locale.
     * 
     * @param locale the JDK locale.
     * @return An instance of RelativeDateTimeFormatter.
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance(Locale locale) {
        return getInstance(ULocale.forLocale(locale));
    }

    /**
     * Returns a RelativeDateTimeFormatter for a particular locale that uses a particular
     * NumberFormat object.
     * 
     * @param locale the locale
     * @param nf the number format object. It is defensively copied to ensure thread-safety
     * and immutability of this class. 
     * @return An instance of RelativeDateTimeFormatter.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance(ULocale locale, NumberFormat nf) {
        return getInstance(locale, nf, Style.LONG, DisplayContext.CAPITALIZATION_NONE);
    }
 
    /**
     * Returns a RelativeDateTimeFormatter for a particular locale that uses a particular
     * NumberFormat object, style, and capitalization context
     * 
     * @param locale the locale
     * @param nf the number format object. It is defensively copied to ensure thread-safety
     * and immutability of this class. May be null.
     * @param style the style.
     * @param capitalizationContext the capitalization context.
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance(
            ULocale locale,
            NumberFormat nf,
            Style style,
            DisplayContext capitalizationContext) {
        RelativeDateTimeFormatterData data = cache.get(locale);
        if (nf == null) {
            nf = NumberFormat.getInstance(locale);
        } else {
            nf = (NumberFormat) nf.clone();
        }
        return new RelativeDateTimeFormatter(
                data.qualitativeUnitMap,
                data.quantitativeUnitMap,
                new MessageFormat(data.dateTimePattern),
                PluralRules.forLocale(locale),
                nf,
                style,
                capitalizationContext,
                capitalizationContext == DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ?
                    BreakIterator.getSentenceInstance(locale) : null,
                locale);
                
    }
           
    /**
     * Returns a RelativeDateTimeFormatter for a particular JDK locale that uses a particular
     * NumberFormat object.
     * 
     * @param locale the JDK locale
     * @param nf the number format object. It is defensively copied to ensure thread-safety
     * and immutability of this class. 
     * @return An instance of RelativeDateTimeFormatter.
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     */
    public static RelativeDateTimeFormatter getInstance(Locale locale, NumberFormat nf) {
        return getInstance(ULocale.forLocale(locale), nf);
    }

    /**
     * Formats a relative date with a quantity such as "in 5 days" or
     * "3 months ago"
     * @param quantity The numerical amount e.g 5. This value is formatted
     * according to this object's {@link NumberFormat} object.
     * @param direction NEXT means a future relative date; LAST means a past
     * relative date.
     * @param unit the unit e.g day? month? year?
     * @return the formatted string
     * @throws IllegalArgumentException if direction is something other than
     * NEXT or LAST.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public String format(double quantity, Direction direction, RelativeUnit unit) {
        if (direction != Direction.LAST && direction != Direction.NEXT) {
            throw new IllegalArgumentException("direction must be NEXT or LAST");
        }
        String result;
        // This class is thread-safe, yet numberFormat is not. To ensure thread-safety of this
        // class we must guarantee that only one thread at a time uses our numberFormat.
        synchronized (numberFormat) {
            result = getQuantity(
                    unit, direction == Direction.NEXT).format(
                            quantity, numberFormat, pluralRules);
        }
        return adjustForContext(result);
    }
    

    /**
     * Formats a relative date without a quantity.
     * @param direction NEXT, LAST, THIS, etc.
     * @param unit e.g SATURDAY, DAY, MONTH
     * @return the formatted string. If direction has a value that is documented as not being
     *  fully supported in every locale (for example NEXT_2 or LAST_2) then this function may
     *  return null to signal that no formatted string is available.
     * @throws IllegalArgumentException if the direction is incompatible with
     * unit this can occur with NOW which can only take PLAIN.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public String format(Direction direction, AbsoluteUnit unit) {
        if (unit == AbsoluteUnit.NOW && direction != Direction.PLAIN) {
            throw new IllegalArgumentException("NOW can only accept direction PLAIN.");
        }
        String result = this.qualitativeUnitMap.get(style).get(unit).get(direction);
        return result != null ? adjustForContext(result) : null;
    }

    /**
     * Combines a relative date string and a time string in this object's
     * locale. This is done with the same date-time separator used for the
     * default calendar in this locale.
     * @param relativeDateString the relative date e.g 'yesterday'
     * @param timeString the time e.g '3:45'
     * @return the date and time concatenated according to the default
     * calendar in this locale e.g 'yesterday, 3:45'
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public String combineDateAndTime(String relativeDateString, String timeString) {
        return this.combinedDateAndTime.format(
            new Object[]{timeString, relativeDateString}, new StringBuffer(), null).toString();
    }
    
    /**
     * Returns a copy of the NumberFormat this object is using.
     * @return A copy of the NumberFormat.
     * @draft ICU 53
     * @provisional This API might change or be removed in a future release.
     */
    public NumberFormat getNumberFormat() {
        // This class is thread-safe, yet numberFormat is not. To ensure thread-safety of this
        // class we must guarantee that only one thread at a time uses our numberFormat.
        synchronized (numberFormat) {
            return (NumberFormat) numberFormat.clone();
        }
    }
    
    /**
     * Return capitalization context.
     *
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     */
    public DisplayContext getCapitalizationContext() {
        return capitalizationContext;
    }

    /**
     * Return style
     *
     * @draft ICU 54
     * @provisional This API might change or be removed in a future release.
     */
    public Style getFormatStyle() {
        return style;
    }
    
    private String adjustForContext(String originalFormattedString) {
        if (breakIterator == null || originalFormattedString.length() == 0 
                || !UCharacter.isLowerCase(UCharacter.codePointAt(originalFormattedString, 0))) {
            return originalFormattedString;
        }
        synchronized (breakIterator) {
            return UCharacter.toTitleCase(
                    locale,
                    originalFormattedString,
                    breakIterator,
                    UCharacter.TITLECASE_NO_LOWERCASE | UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT);
        }
    }
    
    private static void addQualitativeUnit(
            EnumMap<AbsoluteUnit, EnumMap<Direction, String>> qualitativeUnits,
            AbsoluteUnit unit,
            String current) {
        EnumMap<Direction, String> unitStrings =
                new EnumMap<Direction, String>(Direction.class);
        unitStrings.put(Direction.PLAIN, current);
        qualitativeUnits.put(unit,  unitStrings);       
    }

    private static void addQualitativeUnit(
            EnumMap<AbsoluteUnit, EnumMap<Direction, String>> qualitativeUnits,
            AbsoluteUnit unit, ICUResourceBundle bundle, String plain) {
        EnumMap<Direction, String> unitStrings =
                new EnumMap<Direction, String>(Direction.class);
        unitStrings.put(Direction.LAST, bundle.getStringWithFallback("-1"));
        unitStrings.put(Direction.THIS, bundle.getStringWithFallback("0"));
        unitStrings.put(Direction.NEXT, bundle.getStringWithFallback("1"));
        addOptionalDirection(unitStrings, Direction.LAST_2, bundle, "-2");
        addOptionalDirection(unitStrings, Direction.NEXT_2, bundle, "2");
        unitStrings.put(Direction.PLAIN, plain);
        qualitativeUnits.put(unit,  unitStrings);
    }
 
    private static void addOptionalDirection(
            EnumMap<Direction, String> unitStrings,
            Direction direction,
            ICUResourceBundle bundle,
            String key) {
        String s = bundle.findStringWithFallback(key);
        if (s != null) {
            unitStrings.put(direction, s);
        }
    }

    private RelativeDateTimeFormatter(
            EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap,
            EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap,
            MessageFormat combinedDateAndTime,
            PluralRules pluralRules,
            NumberFormat numberFormat,
            Style style,
            DisplayContext capitalizationContext,
            BreakIterator breakIterator,
            ULocale locale) {
        this.qualitativeUnitMap = qualitativeUnitMap;
        this.quantitativeUnitMap = quantitativeUnitMap;
        this.combinedDateAndTime = combinedDateAndTime;
        this.pluralRules = pluralRules;
        this.numberFormat = numberFormat;
        this.style = style;
        if (capitalizationContext.type() != DisplayContext.Type.CAPITALIZATION) {
            throw new IllegalArgumentException(capitalizationContext.toString());
        }
        this.capitalizationContext = capitalizationContext;
        this.breakIterator = breakIterator;
        this.locale = locale;
    }
    
    private QuantityFormatter getQuantity(RelativeUnit unit, boolean isFuture) {
        QuantityFormatter[] quantities = quantitativeUnitMap.get(style).get(unit);
        return isFuture ? quantities[1] : quantities[0];
    }
    
    private final EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap;
    private final EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap;
    private final MessageFormat combinedDateAndTime;
    private final PluralRules pluralRules;
    private final NumberFormat numberFormat;
    private final Style style;
    private final DisplayContext capitalizationContext;
    private final BreakIterator breakIterator;
    private final ULocale locale;
    
    private static class RelativeDateTimeFormatterData {
        public RelativeDateTimeFormatterData(
                EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap,
                EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap,
                String dateTimePattern) {
            this.qualitativeUnitMap = qualitativeUnitMap;
            this.quantitativeUnitMap = quantitativeUnitMap;
            this.dateTimePattern = dateTimePattern;
        }
        
        public final EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap;
        public final EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap;
        public final String dateTimePattern;  // Example: "{1}, {0}"
    }
    
    private static class Cache {
        private final ICUCache<String, RelativeDateTimeFormatterData> cache =
            new SimpleCache<String, RelativeDateTimeFormatterData>();

        public RelativeDateTimeFormatterData get(ULocale locale) {
            String key = locale.toString();
            RelativeDateTimeFormatterData result = cache.get(key);
            if (result == null) {
                result = new Loader(locale).load();
                cache.put(key, result);
            }
            return result;
        }
    }
    
    private static class Loader {
        private final ULocale ulocale;
        
        public Loader(ULocale ulocale) {
            this.ulocale = ulocale;
        }

        public RelativeDateTimeFormatterData load() {
            EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap = 
                    new EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>>(Style.class);
            
            EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap =
                    new EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>>(Style.class);
            
            for (Style style : Style.values()) {
                qualitativeUnitMap.put(style, new EnumMap<AbsoluteUnit, EnumMap<Direction, String>>(AbsoluteUnit.class));
                quantitativeUnitMap.put(style, new EnumMap<RelativeUnit, QuantityFormatter[]>(RelativeUnit.class));                
            }
                    
            ICUResourceBundle r = (ICUResourceBundle)UResourceBundle.
                    getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, ulocale);
            addTimeUnits(
                    r,
                    "fields/day", "fields/day-short", "fields/day-narrow",
                    RelativeUnit.DAYS,
                    AbsoluteUnit.DAY,
                    quantitativeUnitMap,
                    qualitativeUnitMap);
            addTimeUnits(
                    r,
                    "fields/week", "fields/week-short", "fields/week-narrow",
                    RelativeUnit.WEEKS,
                    AbsoluteUnit.WEEK,
                    quantitativeUnitMap,
                    qualitativeUnitMap);
            addTimeUnits(
                    r,
                    "fields/month", "fields/month-short", "fields/month-narrow",
                    RelativeUnit.MONTHS,
                    AbsoluteUnit.MONTH,
                    quantitativeUnitMap,
                    qualitativeUnitMap);
            addTimeUnits(
                    r,
                    "fields/year", "fields/year-short", "fields/year-narrow",
                    RelativeUnit.YEARS,
                    AbsoluteUnit.YEAR,
                    quantitativeUnitMap,
                    qualitativeUnitMap);
            initRelativeUnits(
                    r,
                    "fields/second", "fields/second-short", "fields/second-narrow",
                    RelativeUnit.SECONDS,
                    quantitativeUnitMap);
            initRelativeUnits(
                    r,
                    "fields/minute", "fields/minute-short", "fields/minute-narrow",
                    RelativeUnit.MINUTES,
                    quantitativeUnitMap);
            initRelativeUnits(
                    r,
                    "fields/hour", "fields/hour-short", "fields/hour-narrow",
                    RelativeUnit.HOURS,
                    quantitativeUnitMap);
            
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.LONG),
                    AbsoluteUnit.NOW,
                    r.getStringWithFallback("fields/second/relative/0"));
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.SHORT),
                    AbsoluteUnit.NOW,
                    r.getStringWithFallback("fields/second-short/relative/0"));
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.NARROW),
                    AbsoluteUnit.NOW,
                    r.getStringWithFallback("fields/second-narrow/relative/0"));
            
            EnumMap<Style, EnumMap<AbsoluteUnit, String>> dayOfWeekMap = 
                    new EnumMap<Style, EnumMap<AbsoluteUnit, String>>(Style.class);
            dayOfWeekMap.put(Style.LONG, readDaysOfWeek(
                    r.getWithFallback("calendar/gregorian/dayNames/stand-alone/wide")));
            dayOfWeekMap.put(Style.SHORT, readDaysOfWeek(
                    r.getWithFallback("calendar/gregorian/dayNames/stand-alone/short")));
            dayOfWeekMap.put(Style.NARROW, readDaysOfWeek(
                    r.getWithFallback("calendar/gregorian/dayNames/stand-alone/narrow")));
            
            addWeekDays(
                    r,
                    "fields/mon/relative",
                    "fields/mon-short/relative",
                    "fields/mon-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.MONDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/tue/relative",
                    "fields/tue-short/relative",
                    "fields/tue-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.TUESDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/wed/relative",
                    "fields/wed-short/relative",
                    "fields/wed-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.WEDNESDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/thu/relative",
                    "fields/thu-short/relative",
                    "fields/thu-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.THURSDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/fri/relative",
                    "fields/fri-short/relative",
                    "fields/fri-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.FRIDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/sat/relative",
                    "fields/sat-short/relative",
                    "fields/sat-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.SATURDAY,
                    qualitativeUnitMap);
            addWeekDays(
                    r,
                    "fields/sun/relative",
                    "fields/sun-short/relative",
                    "fields/sun-narrow/relative",
                    dayOfWeekMap,
                    AbsoluteUnit.SUNDAY,
                    qualitativeUnitMap);   
            CalendarData calData = new CalendarData(
                    ulocale, r.getStringWithFallback("calendar/default"));  
            return new RelativeDateTimeFormatterData(
                    qualitativeUnitMap, quantitativeUnitMap, calData.getDateTimePattern());
        }

        private void addTimeUnits(
                ICUResourceBundle r,
                String path, String pathShort, String pathNarrow,
                RelativeUnit relativeUnit, 
                AbsoluteUnit absoluteUnit,
                EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap,
                EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap) {
           addTimeUnit(
                   r.getWithFallback(path),
                   relativeUnit,
                   absoluteUnit,
                   quantitativeUnitMap.get(Style.LONG),
                   qualitativeUnitMap.get(Style.LONG));
           addTimeUnit(
                   r.getWithFallback(pathShort),
                   relativeUnit,
                   absoluteUnit,
                   quantitativeUnitMap.get(Style.SHORT),
                   qualitativeUnitMap.get(Style.SHORT));
           addTimeUnit(
                   r.getWithFallback(pathNarrow),
                   relativeUnit,
                   absoluteUnit,
                   quantitativeUnitMap.get(Style.NARROW),
                   qualitativeUnitMap.get(Style.NARROW));
            
        }

        private void addTimeUnit(
                ICUResourceBundle timeUnitBundle,
                RelativeUnit relativeUnit,
                AbsoluteUnit absoluteUnit,
                EnumMap<RelativeUnit, QuantityFormatter[]> quantitativeUnitMap,
                EnumMap<AbsoluteUnit, EnumMap<Direction, String>> qualitativeUnitMap) {
            addTimeUnit(timeUnitBundle, relativeUnit, quantitativeUnitMap);
            String unitName = timeUnitBundle.getStringWithFallback("dn");
            // TODO(Travis Keep): This is a hack to get around CLDR bug 6818.
            if (ulocale.getLanguage().equals("en")) {
                unitName = unitName.toLowerCase();
            }
            timeUnitBundle = timeUnitBundle.getWithFallback("relative");
            addQualitativeUnit(
                    qualitativeUnitMap,
                    absoluteUnit,
                    timeUnitBundle,
                    unitName);
        }
        
        private void initRelativeUnits(
                ICUResourceBundle r, 
                String path,
                String pathShort,
                String pathNarrow,
                RelativeUnit relativeUnit,
                EnumMap<Style, EnumMap<RelativeUnit, QuantityFormatter[]>> quantitativeUnitMap) {
            addTimeUnit(
                    r.getWithFallback(path),
                    relativeUnit,
                    quantitativeUnitMap.get(Style.LONG));
            addTimeUnit(
                    r.getWithFallback(pathShort),
                    relativeUnit,
                    quantitativeUnitMap.get(Style.SHORT));
            addTimeUnit(
                    r.getWithFallback(pathNarrow),
                    relativeUnit,
                    quantitativeUnitMap.get(Style.NARROW));
        }

        private static void addTimeUnit(
                ICUResourceBundle timeUnitBundle,
                RelativeUnit relativeUnit,
                EnumMap<RelativeUnit, QuantityFormatter[]> quantitativeUnitMap) {
            QuantityFormatter.Builder future = new QuantityFormatter.Builder();
            QuantityFormatter.Builder past = new QuantityFormatter.Builder();
            timeUnitBundle = timeUnitBundle.getWithFallback("relativeTime");
            addTimeUnit(
                    timeUnitBundle.getWithFallback("future"),
                    future);
            addTimeUnit(
                    timeUnitBundle.getWithFallback("past"),
                    past);
            quantitativeUnitMap.put(
                    relativeUnit, new QuantityFormatter[] { past.build(), future.build() });
        }

        private static void addTimeUnit(
                ICUResourceBundle pastOrFuture, QuantityFormatter.Builder builder) {
            int size = pastOrFuture.getSize();
            for (int i = 0; i < size; i++) {
                UResourceBundle r = pastOrFuture.get(i);
                builder.add(r.getKey(), r.getString());
            }
        }
        
        private void addWeekDays(
                ICUResourceBundle r,
                String path,
                String pathShort,
                String pathNarrow,
                EnumMap<Style, EnumMap<AbsoluteUnit, String>> dayOfWeekMap,
                AbsoluteUnit weekDay,
                EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap) {
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.LONG),
                    weekDay,
                    r.findWithFallback(path),
                    dayOfWeekMap.get(Style.LONG).get(weekDay)); 
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.SHORT),
                    weekDay,
                    r.findWithFallback(pathShort),
                    dayOfWeekMap.get(Style.SHORT).get(weekDay)); 
            addQualitativeUnit(
                    qualitativeUnitMap.get(Style.NARROW),
                    weekDay,
                    r.findWithFallback(pathNarrow),
                    dayOfWeekMap.get(Style.NARROW).get(weekDay)); 
            
        }

        private static EnumMap<AbsoluteUnit, String> readDaysOfWeek(ICUResourceBundle daysOfWeekBundle) {
            EnumMap<AbsoluteUnit, String> dayOfWeekMap = new EnumMap<AbsoluteUnit, String>(AbsoluteUnit.class);
            if (daysOfWeekBundle.getSize() != 7) {
                throw new IllegalStateException(String.format("Expect 7 days in a week, got %d", daysOfWeekBundle.getSize()));
            }
            // Sunday always comes first in CLDR data.
            int idx = 0;
            dayOfWeekMap.put(AbsoluteUnit.SUNDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.MONDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.TUESDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.WEDNESDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.THURSDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.FRIDAY, daysOfWeekBundle.getString(idx++));
            dayOfWeekMap.put(AbsoluteUnit.SATURDAY, daysOfWeekBundle.getString(idx++));
            return dayOfWeekMap;
        }
    }

    private static final Cache cache = new Cache();
}
