package data;

/**
  * A value that is based on an {@link Integer} object.
  *
  * <p>All operations are implemented as you would expect them to be.</p>
  */
public class IntegerValue extends NumberValue {

  /**
    * Create a new IntegerValue.
    *
    * @param nbValue the initial value of the object. Will be converted to an {@link Integer}.
    */
  public IntegerValue (Number nbValue) {
    super (nbValue);
  }

  /**
    * Create a new IntegerValue.
    *
    * @param nValue the initial value of the object.
    */
  public IntegerValue (int nValue) {
    this (new Integer (nValue));
  }

  /**
    * Convert every {@link Number} to an {@link Integer} before setting the actual value.
    *
    * @override Never
    */
  public void setValue (Number nbValue) {
    super.setValue (new Integer (nbValue.intValue()));
  }

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

    super.setValue (new Integer (getValue().intValue() + nbV.intValue()));
  }

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

    super.setValue (new Integer (getValue().intValue() - nbV.intValue()));
  }

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

    super.setValue (new Integer (getValue().intValue() * nbV.intValue()));
  }

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

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

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

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

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

    super.setValue (new Integer ((int) (getValue().intValue() / nbV.intValue())));
  }

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

    return new IntegerValue (new Integer (getValue().intValue() + nbV.intValue()));
  }

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

    return new IntegerValue (new Integer (getValue().intValue() - nbV.intValue()));
  }

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

    return new IntegerValue (new Integer (getValue().intValue() * nbV.intValue()));
  }

  /**
    * @override Never
    */
  public Value multiply (double dl) {
    return new IntegerValue (new Integer ((int) (getValue().intValue() * dl)));
  }

  /**
    * @override Never
    */
  public Value multiply (float fl) {
    return new IntegerValue (new Integer ((int) (getValue().intValue() * fl)));
  }

  /**
    * @override Never
    */
  public Value multiply (long l) {
    return new IntegerValue (new Integer ((int) (getValue().intValue() * l)));
  }

  /**
    * @override Never
    */
  public Value multiply (int n) {
    return new IntegerValue (new Integer (getValue().intValue() * n));
  }

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

    return new IntegerValue (new Integer ((int) (getValue().intValue() / nbV.intValue())));
  }

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

    return (getValue().intValue() - nbO.intValue());
  }

  /**
    * @override Never
    */
  public Object clone() {
    return new IntegerValue (new Integer (getValue().intValue()));
  }
}