/*
******************************************************************************
* Copyright (C) 2007-2008, 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.*;
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;
  }

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

  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();
  }
}
