// $Id: TimeUnit.java,v 1.1 2004/09/11 00:04:22 caron Exp $
/*
 * Copyright 1997-2004 Unidata Program Center/University Corporation for
 * Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
 * support@unidata.ucar.edu.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package ucar.nc2.units;

import java.util.StringTokenizer;

/**
 * Handles Units that are time durations, eg in seconds.
 *
 * @author John Caron
 * @version $Revision: 1.1 $ $Date: 2004/09/11 00:04:22 $
 */
public class TimeUnit extends SimpleUnit {
  private double value;
  private String unitString;

  TimeUnit(String text, ucar.units.Unit uu) {
    super( uu);

    StringTokenizer stoker = new StringTokenizer(text);
    int ntoke = stoker.countTokens();
    if (ntoke == 1) {
      this.value = 1.0;
      this.unitString = stoker.nextToken();

    } else if (ntoke == 2){
      this.value = Double.parseDouble(stoker.nextToken());
      this.unitString = stoker.nextToken();
    } else
      throw new IllegalArgumentException("Not TimeUnit = "+text);
  }

  /**
   * Constructor that allows us to track the original time unit string.
   * @param text "value unit" where unit must be compatible with secs.
   * @throws java.lang.Exception if not valid time unit.
   */
  public TimeUnit(String text) throws Exception {
    super();

    StringTokenizer stoker = new StringTokenizer(text);
    String valueS = stoker.nextToken();
    this.value = Double.parseDouble( valueS);
    this.unitString = stoker.nextToken();

    SimpleUnit su = SimpleUnit.factoryWithExceptions( toString());
    if (!(su instanceof TimeUnit))
      throw new java.text.ParseException("not udunit time unit", 0);
    uu = su.getUnit();
  }

  /**
   * Constructor that allows us to track the original time unit string.
   * @param value
   * @param unitString
   * @throws java.lang.Exception if not valid time unit.
   */
  public TimeUnit(double value, String unitString) throws Exception {
    this.value = value;
    this.unitString = unitString;

    SimpleUnit su = SimpleUnit.factoryWithExceptions( toString());
    if (!(su instanceof TimeUnit))
      throw new java.text.ParseException("not udunit time unit", 0);
    uu = su.getUnit();
  }

  /** Get the value in the original units (not necesarily in secs). */
  public double getValue() { return value; }
  /** Get the  original units (not necesarily secs). */
  public String getUnitString() { return unitString; }

  /** String representation in the original units. */
  public String toString() {
    return value + " "+unitString;
  }

  /** Get the time duration in seconds. */
  public double getSeconds() {
    try {
      double secs = uu.convertTo( 1.0, timeUnit);
      return secs;
    } catch (Exception e) {
      e.printStackTrace();
      return 0;
    }
  }

  private SimpleUnit oneUnit = null;

  /**
   * create a new TimeUnit, based on the current units.
   * @param secs : convert this to the units of this TimeUnit.
   * @return a new TimeUnit
   * @throws java.lang.Exception
   */
  public TimeUnit newValue( double secs) throws Exception {
    SimpleUnit secSU = SimpleUnit.factoryWithExceptions(secs + " secs"); // lame

    if (oneUnit == null)
      oneUnit = SimpleUnit.factory("1.0 "+unitString);

    double val = secSU.convertTo(1.0, oneUnit);

    return new TimeUnit( val, unitString);
  }

  /** TimeUnits with same value and unitString are equal */
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof TimeUnit)) return false;
    return o.hashCode() == this.hashCode();
  }

  /** Override hashcode to be consistent with equals. */
  public int hashCode() {
    if (hashCode == 0) {
      int result = 17;
      result = 37*result + unitString.hashCode();
      result = 37*result + (int) (1000.0 * value);
      hashCode = result;
    }
    return hashCode;
  }
  private volatile int hashCode = 0;

}

/**
 * $Log: TimeUnit.java,v $
 * Revision 1.1  2004/09/11 00:04:22  caron
 * *** empty log message ***
 *
 * Revision 1.3  2004/08/16 20:53:52  caron
 * 2.2 alpha (2)
 *
 * Revision 1.2  2004/07/12 23:40:20  caron
 * 2.2 alpha 1.0 checkin
 *
 * Revision 1.1  2004/07/06 19:28:13  caron
 * pre-alpha checkin
 *
 * Revision 1.1  2004/06/07 20:24:55  caron
 * move SimpleUnit to ucar.unit.units, add aliases in UnitDB
 *
 */