// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
******************************************************************************
* Copyright (C) 2007-2010, International Business Machines Corporation and   *
* others. All Rights Reserved.                                               *
******************************************************************************
*/

package com.ibm.icu.impl.duration;

import java.util.Locale;

import com.ibm.icu.impl.duration.impl.DataRecord.ECountVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.ESeparatorVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.EUnitVariant;
import com.ibm.icu.impl.duration.impl.PeriodFormatterData;
import com.ibm.icu.impl.duration.impl.PeriodFormatterDataService;

/**
 * An implementation of PeriodFormatterFactory that provides customization of
 * formatting behavior. Instances of this factory are created by
 * BasicPeriodFormatterService.
 *
 * The settings on BasicPeriodFormatterFactory are:
 * <ul>
 *
 * <li><b>setDisplayLimit</b> controls whether phrases like 'more than'
 * or 'less than' will be displayed when the Period has a defined
 * limit.  Default is to display them.</li>
 *
 * <li><b>setDisplayPastFuture</b> controls whether phrases like 'ago'
 * or 'from now' will be displayed to indicate past or future
 * time. Default is to display them.</li>
 *
 * <li><b>setSeparatorVariant</b> controls how separators (between
 * count and period, and multiple periods) will be displayed, when
 * appropriate for the language. Default is to use full
 * separators.</li>
 *
 * <li><b>setUnitVariant</b> controls which of various types of
 * unit names to use.  PLURALIZED indicates that full names will be
 * used.  MEDIUM indicates that medium-length (usually 2-3 character)
 * names will be used.  SHORT indicates that short (usually single
 * character) names will be used.  If there is no localization data
 * available for either the SHORT or MEDIUM names, the other will be
 * used, if neither is available, the PLURALIZED names will be used.
 * Default is PLURALIZED.</li>
 *
 * <li><b>setCountVariant</b> controls how the count for the smallest
 * unit will be formatted: either as an integer, a fraction to the
 * smallest half, or as a decimal with 1, 2, or 3 decimal points.</li>
 * Counts for higher units will be formatted as integers.
 *
 * </ul>
 */
public class BasicPeriodFormatterFactory implements PeriodFormatterFactory {
  private final PeriodFormatterDataService ds;
  private PeriodFormatterData data;
  private Customizations customizations;
  private boolean customizationsInUse;
  private String localeName;

  // package-only constructor
  BasicPeriodFormatterFactory(PeriodFormatterDataService ds) {
    this.ds = ds;
    this.customizations = new Customizations();
    this.localeName = Locale.getDefault().toString();
  }

  /**
   * Return the default rdf factory as a BasicPeriodFormatterFactory.
   *
   * @return a default BasicPeriodFormatterFactory
   */
  public static BasicPeriodFormatterFactory getDefault() {
      return (BasicPeriodFormatterFactory)
        BasicPeriodFormatterService.getInstance().newPeriodFormatterFactory();
  }

  /**
   * Set the locale for this factory.
   */
  @Override
  public PeriodFormatterFactory setLocale(String localeName) {
    data = null;
    this.localeName = localeName;
    return this;
  }

  /**
   * Set whether limits will be displayed.
   *
   * @param display true if limits will be displayed
   * @return this PeriodFormatterFactory
   */
  @Override
  public PeriodFormatterFactory setDisplayLimit(boolean display) {
    updateCustomizations().displayLimit = display;
    return this;
  }

  /**
   * Return true if limits will be displayed.
   *
   * @return true if limits will be displayed
   */
  public boolean getDisplayLimit() {
    return customizations.displayLimit;
  }

  /**
   * Set whether past and future will be displayed.
   *
   * @param display true if past and future will be displayed
   * @return this PeriodFormatterFactory
   */
  @Override
  public PeriodFormatterFactory setDisplayPastFuture(boolean display) {
    updateCustomizations().displayDirection = display;
    return this;
  }

  /**
   * Return true if past and future will be displayed.
   *
   * @return true if past and future will be displayed
   */
  public boolean getDisplayPastFuture() {
    return customizations.displayDirection;
  }

  /**
   * Set how separators will be displayed.
   *
   * @param variant the variant indicating separators will be displayed
   * @return this PeriodFormatterFactory
   */
  @Override
  public PeriodFormatterFactory setSeparatorVariant(int variant) {
    updateCustomizations().separatorVariant = (byte) variant;
    return this;
  }

  /**
   * Return the variant indicating how separators will be displayed.
   *
   * @return the variant
   */
  public int getSeparatorVariant() {
    return customizations.separatorVariant;
  }

  /**
   * Set the variant of the time unit names to use.
   *
   * @param variant the variant to use
   * @return this PeriodFormatterFactory
   */
  @Override
  public PeriodFormatterFactory setUnitVariant(int variant) {
    updateCustomizations().unitVariant = (byte) variant;
    return this;
  }

  /**
   * Return the unit variant.
   *
   * @return the unit variant
   */
  public int getUnitVariant() {
    return customizations.unitVariant;
  }

  /**
   * Set the variant of the count to use.
   *
   * @param variant the variant to use
   * @return this PeriodFormatterFactory
   */
  @Override
  public PeriodFormatterFactory setCountVariant(int variant) {
    updateCustomizations().countVariant = (byte) variant;
    return this;
  }

  /**
   * Return the count variant.
   *
   * @return the count variant
   */
  public int getCountVariant() {
    return customizations.countVariant;
  }

  @Override
  public PeriodFormatter getFormatter() {
    customizationsInUse = true;
    return new BasicPeriodFormatter(this, localeName, getData(),
                                    customizations);
  }

  private Customizations updateCustomizations() {
    if (customizationsInUse) {
      customizations = customizations.copy();
      customizationsInUse = false;
    }
    return customizations;
  }

  // package access only
  PeriodFormatterData getData() {
    if (data == null) {
      data = ds.get(localeName);
    }
    return data;
  }

  // package access for use by BasicPeriodFormatter
  PeriodFormatterData getData(String locName) {
    return ds.get(locName);
  }

  // package access for use by BasicPeriodFormatter
  static class Customizations {
    boolean displayLimit = true;
    boolean displayDirection = true;
    byte separatorVariant = ESeparatorVariant.FULL;
    byte unitVariant = EUnitVariant.PLURALIZED;
    byte countVariant = ECountVariant.INTEGER;

    public Customizations copy() {
        Customizations result = new Customizations();
        result.displayLimit = displayLimit;
        result.displayDirection = displayDirection;
        result.separatorVariant = separatorVariant;
        result.unitVariant = unitVariant;
        result.countVariant = countVariant;
        return result;
    }
  }
}
