//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010 huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.workflow.xpdl.util;

import org.huihoo.workflow.WorkflowComponent;

public final class Duration implements WorkflowComponent
{
	protected int value;
	protected DurationUnit unit;
	
  /** 
   *  Construct a new Duration.  A value of 0 signals an unlimited duration.
   *  The duration unit may be null to specify that the default should be used.
   *  The default is determined at runtime.
   *   
   *  @param value The duration value
   *  @param unit The unit of measurement
   */
  
  public Duration(int value, DurationUnit unit)
  {
    this.value = value;
    this.unit = unit;
  }

  public Duration(String durationString) 
  throws NumberFormatException
  {
    Duration d = Duration.parse(durationString);
  
    this.value = d.getValue();
    this.unit = d.getUnit();
  }

  /** The duration value.

    @return The duration value
  */

  public int getValue()
  {
    return value;
  }

  /** Return this duration's unit.  This method may return null if the
    unit is not specified.
  
    @return The duration unit or null
  */

  public DurationUnit getUnit()
  {
    return unit;
  }

  /** Get the duration's unit.  The specified default duration unit is
    used if this duration has no specified duration unit.
  
    @param defaultUnit The default unit if no unit specified
    @return The duration unit
  */

  public DurationUnit getUnit(DurationUnit defaultUnit)
  {
    if(unit == null)
    {
      return defaultUnit;
    } 
    else 
      {
      return unit;
    }
  }

  /** Get the duration represented as millseconds.  The specified default
    duration unit is used this duration has no specified duration unit.
  
    @param defaultUnit The default unit if no unit specified
    @return The number of milliseconds for this duration
  */

  public long getDurationInMilliseconds(DurationUnit defaultUnit)
  {
    int value = getValue();
    DurationUnit unit = getUnit(defaultUnit);
  
    //log.debug("Duration value: " + value);
    //log.debug("Duration unit: " + unit);
    //log.debug("Unit in MS: " + unit.toMilliseconds());
  
    if(value == 0)
    {
      return value;
    } 
    else 
    {
      long duration = value * unit.toMilliseconds();
      //log.debug("Duration in MS: " + duration);
      return duration;
    }
  }

  public String toString()
  {
    StringBuffer buffer = new StringBuffer();
    buffer.append(value);
    if(unit != null)
    {
      buffer.append(unit);
    }
    return buffer.toString();
  }

  public static Duration parse(String durationString) 
  throws NumberFormatException
  {
    if(durationString == null)
    {
      throw new IllegalArgumentException("Duration string can not be null");
    }
  
    StringBuffer intBuffer = new StringBuffer();
    DurationUnit unit = null;
    for(int i = 0; i < durationString.length(); i++)
    {
      char c = durationString.charAt(i);
      if(Character.isDigit(c))
      {
        intBuffer.append(c);
      } 
      else if(Character.isLetter(c))
      {
        char[] cArray = {c};
        unit = DurationUnit.stringToType(new String(cArray));
      }
    }
  
    if(intBuffer.toString().equals(""))
    {
      return new Duration(0, unit);
    } 
    else 
    {
      return new Duration(Integer.parseInt(intBuffer.toString()), unit);
    }
  }
  
  public String getTagName()
  {
  	return "Limit";
  }
}
