// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'int32.dart';
import 'int64.dart';

/// A fixed-precision integer.
abstract class IntX implements Comparable<IntX> {
  /// Addition operator.
  IntX operator +(Object other);

  /// Subtraction operator.
  IntX operator -(Object other);

  /// Negate operator.
  ///
  /// Note that `-MIN_VALUE` is equal to `MIN_VALUE` due to overflow.
  IntX operator -();

  /// Multiplication operator.
  IntX operator *(Object other);

  /// Euclidean modulo operator.
  ///
  /// Returns the remainder of the euclidean division. The euclidean division
  /// of two integers `a` and `b` yields two integers `q` and `r` such that
  /// `a == b * q + r` and `0 <= r < a.abs()`.
  IntX operator %(Object other);

  /// Truncating division operator.
  IntX operator ~/(Object other);

  /// Returns the remainder of the truncating division of this integer by
  /// [other].
  IntX remainder(Object other);

  /// Bitwise and operator.
  IntX operator &(Object other);

  /// Bitwise or operator.
  IntX operator |(Object other);

  /// Bitwise xor operator.
  IntX operator ^(Object other);

  /// Bitwise negate operator.
  IntX operator ~();

  /// Left bit-shift operator.
  ///
  /// Returns the result of shifting the bits of this integer by [shiftAmount]
  /// bits to the left. Low-order bits are filled with zeros.
  IntX operator <<(int shiftAmount);

  /// Right bit-shift operator.
  ///
  /// Returns the result of shifting the bits of this integer by [shiftAmount]
  /// bits to the right. High-order bits are filled with zero in the case where
  /// this integer is positive, or one in the case where it is negative.
  IntX operator >>(int shiftAmount);

  /// Unsigned right-shift operator.
  ///
  /// Returns the result of shifting the bits of this integer by [shiftAmount]
  /// bits to the right. High-order bits are filled with zeros.
  IntX shiftRightUnsigned(int shiftAmount);

  @override
  int compareTo(Object other);

  /// Returns `true` if and only if [other] is an int or IntX equal in
  /// value to this integer.
  @override
  bool operator ==(Object other);

  /// Relational less than operator.
  bool operator <(Object other);

  /// Relational less than or equal to operator.
  bool operator <=(Object other);

  /// Relational greater than operator.
  bool operator >(Object other);

  /// Relational greater than or equal to operator.
  bool operator >=(Object other);

  /// Returns `true` if and only if this integer is even.
  bool get isEven;

  /// Returns `true` if and only if this integer is the maximum signed value
  /// that can be represented within its bit size.
  bool get isMaxValue;

  /// Returns `true` if and only if this integer is the minimum signed value
  /// that can be represented within its bit size.
  bool get isMinValue;

  /// Returns `true` if and only if this integer is less than zero.
  bool get isNegative;

  /// Returns `true` if and only if this integer is odd.
  bool get isOdd;

  /// Returns `true` if and only if this integer is zero.
  bool get isZero;

  @override
  int get hashCode;

  /// Returns the absolute value of this integer.
  IntX abs();

  /// Clamps this integer to be in the range [lowerLimit] - [upperLimit].
  IntX clamp(Object lowerLimit, Object upperLimit);

  /// Returns the minimum number of bits required to store this integer.
  ///
  /// The number of bits excludes the sign bit, which gives the natural length
  /// for non-negative (unsigned) values.  Negative values are complemented to
  /// return the bit position of the first bit that differs from the sign bit.
  ///
  /// To find the the number of bits needed to store the value as a signed
  /// value, add one, i.e. use `x.bitLength + 1`.
  int get bitLength;

  /// Returns the number of high-order zeros in this integer's bit
  /// representation.
  int numberOfLeadingZeros();

  /// Returns the number of low-order zeros in this integer's bit
  /// representation.
  int numberOfTrailingZeros();

  /// Returns the least significant [width] bits of this integer, extending the
  /// highest retained bit to the sign.  This is the same as truncating the
  /// value to fit in [width] bits using an signed 2-s complement
  /// representation. The returned value has the same bit value in all positions
  /// higher than [width].
  ///
  /// If the input value fits in [width] bits without truncation, the result is
  /// the same as the input.  The minimum width needed to avoid truncation of
  /// `x` is `x.bitLength + 1`, i.e.
  ///
  ///     x == x.toSigned(x.bitLength + 1);
  IntX toSigned(int width);

  /// Returns the least significant [width] bits of this integer as a
  /// non-negative number (i.e. unsigned representation). The returned value has
  /// zeros in all bit positions higher than [width].
  ///
  /// If the input fits in [width] bits without truncation, the result is the
  /// same as the input.  The minimum width needed to avoid truncation of `x` is
  /// given by `x.bitLength`, i.e.
  ///
  ///     x == x.toUnsigned(x.bitLength);
  IntX toUnsigned(int width);

  /// Returns a byte-sequence representation of this integer.
  ///
  /// Returns a list of int, starting with the least significant byte.
  List<int> toBytes();

  /// Returns the double representation of this integer.
  ///
  /// On some platforms, inputs with large absolute values (i.e., > 2^52) may
  /// lose some of their low-order bits.
  double toDouble();

  /// Returns the int representation of this integer.
  ///
  /// On some platforms, inputs with large absolute values (i.e., > 2^52) may
  /// lose some of their low-order bits.
  int toInt();

  /// Returns an Int32 representation of this integer.
  ///
  /// Narrower values are sign-extended and wider values have their high bits
  /// truncated.
  Int32 toInt32();

  /// Returns an Int64 representation of this integer.
  Int64 toInt64();

  /// Returns a string representing the value of this integer in decimal
  /// notation; example: `'13'`.
  @override
  String toString();

  /// Returns a string representing the value of this integer in hexadecimal
  /// notation.
  ///
  /// Example: `Int64(0xf01d).toHexString()` returns `'F01D'`.
  ///
  /// The string may interprets the number as *unsigned*, and has no leading
  /// minus, even if the value [isNegative].
  ///
  /// Example: `Int64(-1).toHexString()` returns `'FFFFFFFFFFFFFFFF'`.
  String toHexString();

  /// Returns a string representing the value of this integer in the given
  /// radix.
  ///
  /// [radix] must be an integer in the range 2 .. 16, inclusive.
  String toRadixString(int radix);
}
