package data;

/**
  * A NumberValue that is based on a {@link java.lang.Double} object.
  *
  * <p>All operations are implemented as one might expect.</p>
  *
  * @author Steffen Zschaler
  * @version 2.0 19/08/1999
  * @since v2.0
  */
public class DoubleValue extends NumberValue {

  /**
    * Create a new DoubleValue.
    *
    * @param nbValue the initial value of the object. Will be converted to a {@link java.lang.Double}.
    */
  public DoubleValue (Number nbValue) {
    super (nbValue);
  }

  /**
    * Create a new DoubleValue.
    *
    * @param dlValue the initial value of the object.
    */
  public DoubleValue (double dlValue) {
    this (new Double (dlValue));
  }

  /**
    * Convert the given value to a {@link java.lang.Double} before setting the actual value of the object.
    *
    * @override Never
    */
  public void setValue (Number nbValue) {
    super.setValue (new Double (nbValue.doubleValue()));
  }

  /**
    * @override Never
    */
  public void addAccumulating (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    super.setValue (new Double (getValue().doubleValue() + nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public void subtractAccumulating (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    super.setValue (new Double (getValue().doubleValue() - nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public void multiplyAccumulating (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    super.setValue (new Double (getValue().doubleValue() * nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public void multiplyAccumulating (double dl) {
    super.setValue (new Double (getValue().doubleValue() * dl));
  }

  /**
    * @override Never
    */
  public void multiplyAccumulating (float fl) {
    super.setValue (new Double (getValue().doubleValue() * fl));
  }

  /**
    * @override Never
    */
  public void multiplyAccumulating (long l) {
    super.setValue (new Double (getValue().doubleValue() * l));
  }

  /**
    * @override Never
    */
  public void multiplyAccumulating (int n) {
    super.setValue (new Double (getValue().doubleValue() * n));
  }

  /**
    * @override Never
    */
  public void divideAccumulating (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    super.setValue (new Double (getValue().doubleValue() / nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public Value add (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    return new DoubleValue (new Double (getValue().doubleValue() + nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public Value subtract (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    return new DoubleValue (new Double (getValue().doubleValue() - nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public Value multiply (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    return new DoubleValue (new Double (getValue().doubleValue() * nbV.doubleValue()));
  }

  /**
    * @override Never
    */
  public Value multiply (double dl) {
    return new DoubleValue (new Double (getValue().doubleValue() * dl));
  }

  /**
    * @override Never
    */
  public Value multiply (float fl) {
    return new DoubleValue (new Double (getValue().doubleValue() * fl));
  }

  /**
    * @override Never
    */
  public Value multiply (long l) {
    return new DoubleValue (new Double (getValue().doubleValue() * l));
  }

  /**
    * @override Never
    */
  public Value multiply (int n) {
    return new DoubleValue (new Double (getValue().doubleValue() * n));
  }

  /**
    * @override Never
    */
  public Value divide (Value v) {
    Number nbV = ((NumberValue) v).getValue();

    return new DoubleValue (new Double (getValue().doubleValue() / nbV.doubleValue()));
  }

  /**
    * Compare this value to the given one.
    *
    * @override Never
    *
    * @exception ClassCastException if the given object cannot be casted into a {@link NumberValue}.
    */
  public int compareTo (Object o) {
    Number nbO = ((NumberValue) o).getValue();

    double dlDiff = (getValue().doubleValue() - nbO.doubleValue());

    if (dlDiff > 0) {
      return 1;
    }
    else if (dlDiff < 0) {
      return -1;
    }
    else {
      return 0;
    }
  }

  /**
    * @override Never
    */
  public Object clone() {
    return new DoubleValue (new Double (getValue().doubleValue()));
  }

  /**
    * Correctly checks <code>getValue().doubleValue()</code>.
    *
    * @override Never
    */
  public boolean isAddZero() {
    return (getValue().doubleValue() == 0);
  }

  /**
    * Correctly checks <code>getValue().doubleValue()</code>.
    *
    * @override Never
    */
  public boolean isMulOne() {
    return (getValue().doubleValue() == 1);
  }
}