/*
******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and   *
* others. All Rights Reserved.                                               *
******************************************************************************
*/

package com.ibm.icu.impl.duration;

import com.ibm.icu.impl.duration.impl.DataRecord;
import com.ibm.icu.impl.duration.impl.PeriodFormatterData;
import com.ibm.icu.impl.duration.impl.PeriodFormatterDataService;

import java.util.TimeZone;

/**
 * Default implementation of PeriodBuilderFactory.  This creates builders that
 * use approximate durations.
 */
class BasicPeriodBuilderFactory implements PeriodBuilderFactory {
  private PeriodFormatterDataService ds;
  private Settings settings;
  
  private static final short allBits = 0xff;
  
  BasicPeriodBuilderFactory(PeriodFormatterDataService ds) {
    this.ds = ds;
    this.settings = new Settings();
  }

  static long approximateDurationOf(TimeUnit unit) {
    return TimeUnit.approxDurations[unit.ordinal];
  }

  class Settings {
    boolean inUse;
    short uset = allBits;
    TimeUnit maxUnit = TimeUnit.YEAR;
    TimeUnit minUnit = TimeUnit.MILLISECOND;
    int maxLimit;
    int minLimit;
    boolean allowZero = true;
    boolean weeksAloneOnly;
    boolean useMilliseconds = true;

    Settings setUnits(int uset) {
      if (this.uset == uset) {
        return this;
      }
      Settings result = inUse ? copy() : this;
        
      result.uset = (short)uset;

      if ((uset & allBits) == allBits) {
        result.uset = allBits;
        result.maxUnit = TimeUnit.YEAR;
        result.minUnit = TimeUnit.MILLISECOND;
      } else {
        int lastUnit = -1;
        for (int i = 0; i < TimeUnit.units.length; ++i) {
          if (0 != (uset & (1 << i))) {
            if (lastUnit == -1) {
              result.maxUnit = TimeUnit.units[i];
            }
            lastUnit = i;
          }
        }
	if (lastUnit == -1) { 
	    // currently empty, but this might be transient so no fail
	    result.minUnit = result.maxUnit = null;
	} else {
	    result.minUnit = TimeUnit.units[lastUnit];
	}
      }

      return result;
    }

    short effectiveSet() {
      if (useMilliseconds) {
        return uset;
      }
      return (short)(uset & ~(1 << TimeUnit.MILLISECOND.ordinal));
    }

    Settings setMaxLimit(float maxLimit) {
      int val = maxLimit <= 0 ? 0 : (int)(maxLimit*1000);
      if (maxLimit == val) {
        return this;
      }
      Settings result = inUse ? copy() : this;
      result.maxLimit = val;
      return result;
    }

    Settings setMinLimit(float minLimit) {
      int val = minLimit <= 0 ? 0 : (int)(minLimit*1000);
      if (minLimit == val) {
        return this;
      }
      Settings result = inUse ? copy() : this;
      result.minLimit = val;
      return result;
    }

    Settings setAllowZero(boolean allow) {
      if (this.allowZero == allow) {
        return this;
      }
      Settings result = inUse ? copy() : this;
      result.allowZero = allow;
      return result;
    }

    Settings setWeeksAloneOnly(boolean weeksAlone) {
      if (this.weeksAloneOnly == weeksAlone) {
        return this;
      }
      Settings result = inUse ? copy() : this;
      result.weeksAloneOnly = weeksAlone;
      return result;
    }

    Settings setAllowMilliseconds(boolean useMilliseconds) {
      if (this.useMilliseconds == useMilliseconds) {
        return this;
      }
      Settings result = inUse ? copy() : this;
      result.useMilliseconds = useMilliseconds;
      return result;
    }

    Settings setLocale(String localeName) {
      PeriodFormatterData data = ds.get(localeName);
      return this
        .setAllowZero(data.allowZero())
        .setWeeksAloneOnly(data.weeksAloneOnly())
        .setAllowMilliseconds(data.useMilliseconds() != DataRecord.EMilliSupport.NO);  
    }

    Settings setInUse() {
      inUse = true;
      return this;
    }

    Period createLimited(long duration, boolean inPast) {
      long maxUnitDuration = approximateDurationOf(maxUnit);
      if (maxLimit > 0 && duration * 1000 > maxLimit * maxUnitDuration) {
        return Period.moreThan(maxLimit/1000f, maxUnit).inPast(inPast);
      }
      long minUnitDuration = approximateDurationOf(minUnit);
      if (minLimit > 0 && duration * 1000 < minLimit * minUnitDuration) {
        return Period.lessThan(minLimit/1000f, minUnit).inPast(inPast);
      }
      return null;
    }

    public Settings copy() {
	Settings result = new Settings();
	result.inUse = inUse;
	result.uset = uset;
	result.maxUnit = maxUnit;
	result.minUnit = minUnit;
	result.maxLimit = maxLimit;
	result.minLimit = minLimit;
	result.allowZero = allowZero;
	result.weeksAloneOnly = weeksAloneOnly;
	result.useMilliseconds = useMilliseconds;
	return result;
    }
  }

  public PeriodBuilderFactory setAvailableUnitRange(TimeUnit minUnit, 
							 TimeUnit maxUnit) {
    int uset = 0;
    for (int i = maxUnit.ordinal; i <= minUnit.ordinal; ++i) {
	uset |= 1 << i;
    }
    if (uset == 0) {
	throw new IllegalArgumentException("range " + minUnit + " to " + maxUnit + " is empty");
    }
    settings = settings.setUnits(uset);
    return this;
  }

  public PeriodBuilderFactory setUnitIsAvailable(TimeUnit unit, 
						      boolean available) {
    int uset = settings.uset;
    if (available) {
      uset |= 1 << unit.ordinal;
    } else {
      uset &= ~(1 << unit.ordinal);
    }
    settings = settings.setUnits(uset);
    return this;
  }

  public PeriodBuilderFactory setMaxLimit(float maxLimit) {
    settings = settings.setMaxLimit(maxLimit);
    return this;
  }

  public PeriodBuilderFactory setMinLimit(float minLimit) {
    settings = settings.setMinLimit(minLimit);
    return this;
  }

  public PeriodBuilderFactory setAllowZero(boolean allow) {
    settings = settings.setAllowZero(allow);
    return this;
  }

  public PeriodBuilderFactory setWeeksAloneOnly(boolean aloneOnly) {
    settings = settings.setWeeksAloneOnly(aloneOnly);
    return this;
  }

  public PeriodBuilderFactory setAllowMilliseconds(boolean useMilliseconds) {
    settings = settings.setAllowMilliseconds(useMilliseconds);
    return this;
  }

  public PeriodBuilderFactory setLocale(String localeName) {
    settings = settings.setLocale(localeName);
    return this;
  }

  private Settings getSettings() {
    if (settings.effectiveSet() == 0) {
      return null;
    }
    return settings.setInUse();
  }

  /**
   * Return a builder that represents relative time in terms of the single
   * given TimeUnit
   *
   * @param unit the single TimeUnit with which to represent times
   * @return a builder
   */
  public PeriodBuilder getFixedUnitBuilder(TimeUnit unit) {
    return FixedUnitBuilder.get(unit, getSettings());
  }

  /**
   * Return a builder that represents relative time in terms of the
   * largest period less than or equal to the duration.
   *
   * @return a builder
   */
  public PeriodBuilder getSingleUnitBuilder() {
    return SingleUnitBuilder.get(getSettings());
  }

  /**
   * Return a builder that formats the largest one or two periods,
   * Starting with the largest period less than or equal to the duration.
   * It formats two periods if the first period has a count &lt; 2
   * and the next period has a count &gt;= 1.
   *
   * @return a builder
   */
  public PeriodBuilder getOneOrTwoUnitBuilder() {
    return OneOrTwoUnitBuilder.get(getSettings());
  }

  /**
   * Return a builder that formats the given number of periods,
   * starting with the largest period less than or equal to the
   * duration.
   *
   * @return a builder
   */
  public PeriodBuilder getMultiUnitBuilder(int periodCount) {
    return MultiUnitBuilder.get(periodCount, getSettings());
  }
}

abstract class PeriodBuilderImpl implements PeriodBuilder {

  protected BasicPeriodBuilderFactory.Settings settings;
 
  public Period create(long duration) {
    return createWithReferenceDate(duration, System.currentTimeMillis());
  }

  public long approximateDurationOf(TimeUnit unit) {
    return BasicPeriodBuilderFactory.approximateDurationOf(unit);
  }

  public Period createWithReferenceDate(long duration, long referenceDate) {
    boolean inPast = duration < 0;
    if (inPast) {
      duration = -duration;
    }
    Period ts = settings.createLimited(duration, inPast);
    if (ts == null) {
      ts = handleCreate(duration, referenceDate, inPast);
      if (ts == null) {
        ts = Period.lessThan(1, settings.minUnit).inPast(inPast);
      }
    }
    return ts;
  }

  public PeriodBuilder withTimeZone(TimeZone timeZone) {
      // ignore the time zone
      return this;
  }
	
  public PeriodBuilder withLocale(String localeName) {
    BasicPeriodBuilderFactory.Settings newSettings = settings.setLocale(localeName);
    if (newSettings != settings) {
      return withSettings(newSettings);
    }
    return this;
  }

  protected abstract PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settings);

  protected abstract Period handleCreate(long duration, long referenceDate, 
                                         boolean inPast);

  protected PeriodBuilderImpl(BasicPeriodBuilderFactory.Settings settings) {
    this.settings = settings;
  }
}

class FixedUnitBuilder extends PeriodBuilderImpl {
  private TimeUnit unit;
  
  public static FixedUnitBuilder get(TimeUnit unit, BasicPeriodBuilderFactory.Settings settings) {
    if (settings != null && (settings.effectiveSet() & (1 << unit.ordinal)) != 0) {
      return new FixedUnitBuilder(unit, settings);
    }
    return null;
  }

  FixedUnitBuilder(TimeUnit unit, BasicPeriodBuilderFactory.Settings settings) {
    super(settings);
    this.unit = unit;
  }

  protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settings) {
    return get(unit, settings);
  }

  protected Period handleCreate(long duration, long referenceDate, 
                                boolean inPast) {
    if (unit == null) {
      return null;
    }
    long unitDuration = approximateDurationOf(unit);
    return Period.at((float)((double)duration/unitDuration), unit)
        .inPast(inPast);
  }
}

class SingleUnitBuilder extends PeriodBuilderImpl {
  SingleUnitBuilder(BasicPeriodBuilderFactory.Settings settings) {
    super(settings);
  }

  public static SingleUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) {
    if (settings == null) {
      return null;
    }
    return new SingleUnitBuilder(settings);
  }

  protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settings) {
    return SingleUnitBuilder.get(settings);
  }

  protected Period handleCreate(long duration, long referenceDate, 
                                boolean inPast) {
    short uset = settings.effectiveSet();
    for (int i = 0; i < TimeUnit.units.length; ++i) {
      if (0 != (uset & (1 << i))) {
        TimeUnit unit = TimeUnit.units[i];
        long unitDuration = approximateDurationOf(unit);
        if (duration >= unitDuration) {
          return Period.at((float)((double)duration/unitDuration), unit)
              .inPast(inPast);
        }
      }
    }
    return null;
  }
}

class OneOrTwoUnitBuilder extends PeriodBuilderImpl {
  OneOrTwoUnitBuilder(BasicPeriodBuilderFactory.Settings settings) {
    super(settings);
  }

  public static OneOrTwoUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) {
    if (settings == null) {
      return null;
    }
    return new OneOrTwoUnitBuilder(settings);
  }

  protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settings) {
    return OneOrTwoUnitBuilder.get(settings);
  }

  protected Period handleCreate(long duration, long referenceDate, 
                                boolean inPast) {
    Period period = null;
    short uset = settings.effectiveSet();
    for (int i = 0; i < TimeUnit.units.length; ++i) {
      if (0 != (uset & (1 << i))) {
        TimeUnit unit = TimeUnit.units[i];
        long unitDuration = approximateDurationOf(unit);
        if (duration >= unitDuration || period != null) {
          double count = (double)duration/unitDuration;
          if (period == null) {
            if (count >= 2) {
              period = Period.at((float)count, unit);
              break;
            }
            period = Period.at(1, unit).inPast(inPast);
            duration -= unitDuration;
          } else {
            if (count >= 1) {
              period.and((float)count, unit);
            }
            break;
          }
        }
      }
    }
    return period;
  }
}

class MultiUnitBuilder extends PeriodBuilderImpl {
  private int nPeriods;

  MultiUnitBuilder(int nPeriods, BasicPeriodBuilderFactory.Settings settings) {
    super(settings);
    this.nPeriods = nPeriods;
  }

  public static MultiUnitBuilder get(int nPeriods, BasicPeriodBuilderFactory.Settings settings) {
    if (nPeriods > 0 && settings != null) {
      return new MultiUnitBuilder(nPeriods, settings);
    }
    return null;
  }

  protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settings) {
    return MultiUnitBuilder.get(nPeriods, settings);
  }

  protected Period handleCreate(long duration, long referenceDate, 
                                boolean inPast) {
    Period period = null;
    int n = 0;
    short uset = settings.effectiveSet();
    for (int i = 0; i < TimeUnit.units.length; ++i) {
      if (0 != (uset & (1 << i))) {
        TimeUnit unit = TimeUnit.units[i];
        if (n == nPeriods) {
          break;
        }
        long unitDuration = approximateDurationOf(unit);
        if (duration >= unitDuration || n > 0) {
          ++n;
          double count = (double)duration / unitDuration;
          if (n < nPeriods) {
            count = Math.floor(count);
            duration -= (long)(count * unitDuration);
          }
          if (period == null) {
            period = Period.at((float)count, unit).inPast(inPast);
          } else {
            period.and((float)count, unit);
          }
        }
      }
    }
    return period;
  }
}

