package com.jaalee.sdk.internal;

import java.math.BigInteger;
/**
 * @author JAALEE, Inc
 * 
 * @Support dev@jaalee.com
 * @Sales: sales@jaalee.com
 * 
 * @see http://www.jaalee.com/
 */

public final class UnsignedInteger extends Number
{
	public static final UnsignedInteger ZERO = fromIntBits(0);
	public static final UnsignedInteger ONE = fromIntBits(1);
	public static final UnsignedInteger MAX_VALUE = fromIntBits(-1);
	private final int value;

	private UnsignedInteger(int value)
	{
		this.value = (value & 0xFFFFFFFF);
	}

	public static UnsignedInteger fromIntBits(int bits)
	{
		return new UnsignedInteger(bits);
	}

	public static UnsignedInteger valueOf(long value)
	{
		Preconditions.checkArgument((value & 0xFFFFFFFF) == value, "value (%s) is outside the range for an unsigned integer value", new Object[] { Long.valueOf(value) });

		return fromIntBits((int)value);
	}

	public static UnsignedInteger valueOf(BigInteger value)
	{
		Preconditions.checkNotNull(value);
		Preconditions.checkArgument((value.signum() >= 0) && (value.bitLength() <= 32), "value (%s) is outside the range for an unsigned integer value", new Object[] { value });

		return fromIntBits(value.intValue());
	}

	public static UnsignedInteger valueOf(String string)
	{
		return valueOf(string, 10);
	}

	public static UnsignedInteger valueOf(String string, int radix)
	{
		return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
	}

	public UnsignedInteger plus(UnsignedInteger val)
	{
		return fromIntBits(this.value + ((UnsignedInteger)Preconditions.checkNotNull(val)).value);
	}

	public UnsignedInteger minus(UnsignedInteger val)
	{
		return fromIntBits(this.value - ((UnsignedInteger)Preconditions.checkNotNull(val)).value);
	}

	public UnsignedInteger times(UnsignedInteger val)
	{
		return fromIntBits(this.value * ((UnsignedInteger)Preconditions.checkNotNull(val)).value);
	}

	public UnsignedInteger dividedBy(UnsignedInteger val)
	{
		return fromIntBits(UnsignedInts.divide(this.value, ((UnsignedInteger)Preconditions.checkNotNull(val)).value));
	}

	public UnsignedInteger mod(UnsignedInteger val)
	{
		return fromIntBits(UnsignedInts.remainder(this.value, ((UnsignedInteger)Preconditions.checkNotNull(val)).value));
	}

	public int intValue()
	{
		return this.value;
	}

	public long longValue()
	{
		return UnsignedInts.toLong(this.value);
	}

	public float floatValue()
	{
		return (float)longValue();
	}

	public double doubleValue()
	{
		return longValue();
	}

	public BigInteger bigIntegerValue()
	{
		return BigInteger.valueOf(longValue());
	}

	public int hashCode()
	{
		return this.value;
	}

	public boolean equals(Object obj)
	{
		if ((obj instanceof UnsignedInteger)) {
			UnsignedInteger other = (UnsignedInteger)obj;
			return this.value == other.value;
		}
		return false;
	}

	public String toString()
	{
		return toString(10);
	}

	public String toString(int radix)
	{
		return UnsignedInts.toString(this.value, radix);
	}
}
