/*
******************************************************************************
* 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.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 settingsToUse);

  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 settingsToUse) {
    if (settingsToUse != null && (settingsToUse.effectiveSet() & (1 << unit.ordinal)) != 0) {
      return new FixedUnitBuilder(unit, settingsToUse);
    }
    return null;
  }

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

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

  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 settingsToUse) {
    return SingleUnitBuilder.get(settingsToUse);
  }

  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 settingsToUse) {
    return OneOrTwoUnitBuilder.get(settingsToUse);
  }

  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 settingsToUse) {
    return MultiUnitBuilder.get(nPeriods, settingsToUse);
  }

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

