// © 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 com.ibm.icu.impl.duration.BasicPeriodFormatterFactory.Customizations;
import com.ibm.icu.impl.duration.impl.DataRecord.ECountVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.EMilliSupport;
import com.ibm.icu.impl.duration.impl.DataRecord.ESeparatorVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.ETimeDirection;
import com.ibm.icu.impl.duration.impl.DataRecord.ETimeLimit;
import com.ibm.icu.impl.duration.impl.PeriodFormatterData;

/**
 * Core implementation class for PeriodFormatter.
 */
class BasicPeriodFormatter implements PeriodFormatter {
  private BasicPeriodFormatterFactory factory;
  private String localeName;
  private PeriodFormatterData data;
  private Customizations customs;

  BasicPeriodFormatter(BasicPeriodFormatterFactory factory,
                       String localeName,
                       PeriodFormatterData data,
                       Customizations customs) {
    this.factory = factory;
    this.localeName = localeName;
    this.data = data;
    this.customs = customs;
  }

  @Override
public String format(Period period) {
    if (!period.isSet()) {
      throw new IllegalArgumentException("period is not set");
    }
    return format(period.timeLimit, period.inFuture, period.counts);
  }

  @Override
  public PeriodFormatter withLocale(String locName) {
    if (!this.localeName.equals(locName)) {
      PeriodFormatterData newData = factory.getData(locName);
      return new BasicPeriodFormatter(factory, locName, newData,
                                      customs);
    }
    return this;
  }

  private String format(int tl, boolean inFuture, int[] counts) {
    int mask = 0;
    for (int i = 0; i < counts.length; ++i) {
      if (counts[i] > 0) {
        mask |= 1 << i;
      }
    }

    // if the data does not allow formatting of zero periods,
    // remove these from consideration.  If the result has no
    // periods set, return null to indicate we could not format
    // the duration.
    if (!data.allowZero()) {
      for (int i = 0, m = 1; i < counts.length; ++i, m <<= 1) {
        if ((mask & m) != 0 && counts[i] == 1) {
          mask &= ~m;
        }
      }
      if (mask == 0) {
        return null;
      }
    }

    // if the data does not allow milliseconds but milliseconds are
    // set, merge them with seconds and force display of seconds to
    // decimal with 3 places.
    boolean forceD3Seconds = false;
    if (data.useMilliseconds() != EMilliSupport.YES &&
        (mask & (1 << TimeUnit.MILLISECOND.ordinal)) != 0) {
      int sx = TimeUnit.SECOND.ordinal;
      int mx = TimeUnit.MILLISECOND.ordinal;
      int sf = 1 << sx;
      int mf = 1 << mx;
      switch (data.useMilliseconds()) {
        case EMilliSupport.WITH_SECONDS: {
          // if there are seconds, merge with seconds, otherwise leave alone
          if ((mask & sf) != 0) {
            counts[sx] += (counts[mx]-1)/1000;
            mask &= ~mf;
            forceD3Seconds = true;
          }
        } break;
        case EMilliSupport.NO: {
          // merge with seconds, reset seconds before use just in case
          if ((mask & sf) == 0) {
            mask |= sf;
            counts[sx] = 1;
          }
          counts[sx] += (counts[mx]-1)/1000;
          mask &= ~mf;
          forceD3Seconds = true;
        } break;
      }
    }

    // get the first and last units that are set.
    int first = 0;
    int last = counts.length - 1;
    while (first < counts.length && (mask & (1 << first)) == 0) ++first;
    while (last > first && (mask & (1 << last)) == 0) --last;

    // determine if there is any non-zero unit
    boolean isZero = true;
    for (int i = first; i <= last; ++i) {
      if (((mask & (1 << i)) != 0) &&  counts[i] > 1) {
        isZero = false;
        break;
      }
    }

    StringBuffer sb = new StringBuffer();

    // if we've been requested to not display a limit, or there are
    // no non-zero units, do not display the limit.
    if (!customs.displayLimit || isZero) {
      tl = ETimeLimit.NOLIMIT;
    }

    // if we've been requested to not display the direction, or there
    // are no non-zero units, do not display the direction.
    int td;
    if (!customs.displayDirection || isZero) {
      td = ETimeDirection.NODIRECTION;
    } else {
      td = inFuture ? ETimeDirection.FUTURE : ETimeDirection.PAST;
    }

    // format the initial portion of the string before the units.
    // record whether we need to use a digit prefix (because the
    // initial portion forces it)
    boolean useDigitPrefix = data.appendPrefix(tl, td, sb);

    // determine some formatting params and initial values
    boolean multiple = first != last;
    boolean wasSkipped = true; // no initial skip marker
    boolean skipped = false;
    boolean countSep = customs.separatorVariant != ESeparatorVariant.NONE;

    // loop for formatting the units
    for (int i = first, j = i; i <= last; i = j) {
      if (skipped) {
        // we didn't format the previous unit
        data.appendSkippedUnit(sb);
        skipped = false;
        wasSkipped = true;
      }

      while (++j < last && (mask & (1 << j)) == 0) {
        skipped = true; // skip
      }

      TimeUnit unit = TimeUnit.units[i];
      int count = counts[i] - 1;

      int cv = customs.countVariant;
      if (i == last) {
        if (forceD3Seconds) {
          cv = ECountVariant.DECIMAL3;
        }
        // else leave unchanged
      } else {
        cv = ECountVariant.INTEGER;
      }
      boolean isLast = i == last;
      boolean mustSkip = data.appendUnit(unit, count, cv, customs.unitVariant,
                                         countSep, useDigitPrefix, multiple, isLast, wasSkipped, sb);
      skipped |= mustSkip;
      wasSkipped = false;

      if (customs.separatorVariant != ESeparatorVariant.NONE && j <= last) {
        boolean afterFirst = i == first;
        boolean beforeLast = j == last;
        boolean fullSep = customs.separatorVariant == ESeparatorVariant.FULL;
        useDigitPrefix = data.appendUnitSeparator(unit, fullSep, afterFirst, beforeLast, sb);
      } else {
        useDigitPrefix = false;
      }
    }
    data.appendSuffix(tl, td, sb);

    return sb.toString();
  }
}
