package io.bitsquare.gui.main.offer.createoffer.monetary;
import org.bitcoinj.core.Coin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.math.BigInteger;
import static com.google.common.base.Preconditions.checkArgument;
// Cloned from ExchangeRate. Use Altcoin instead of Fiat.
public class AltcoinExchangeRate implements Serializable {
private static final Logger log = LoggerFactory.getLogger(AltcoinExchangeRate.class);
/**
* An exchange rate is expressed as a ratio of a {@link Coin} and a {@link Altcoin} amount.
*/
public final Coin coin;
public final Altcoin altcoin;
/**
* Construct exchange rate. This amount of coin is worth that amount of altcoin.
*/
public AltcoinExchangeRate(Coin coin, Altcoin altcoin) {
checkArgument(coin.isPositive());
checkArgument(altcoin.isPositive());
checkArgument(altcoin.currencyCode != null, "currency code required");
this.coin = coin;
this.altcoin = altcoin;
}
/**
* Construct exchange rate. One coin is worth this amount of altcoin.
*/
public AltcoinExchangeRate(Altcoin altcoin) {
this(Coin.COIN, altcoin);
}
/**
* Convert a coin amount to a altcoin amount using this exchange rate.
*
* @throws ArithmeticException if the converted altcoin amount is too high or too low.
*/
public Altcoin coinToAltcoin(Coin convertCoin) {
// Use BigInteger because it's much easier to maintain full precision without overflowing.
final BigInteger converted = BigInteger.valueOf(convertCoin.value).multiply(BigInteger.valueOf(altcoin.value))
.divide(BigInteger.valueOf(coin.value));
if (converted.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0
|| converted.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0)
throw new ArithmeticException("Overflow");
return Altcoin.valueOf(altcoin.currencyCode, converted.longValue());
}
/**
* Convert a altcoin amount to a coin amount using this exchange rate.
*
* @throws ArithmeticException if the converted coin amount is too high or too low.
*/
public Coin altcoinToCoin(Altcoin convertAltcoin) {
checkArgument(convertAltcoin.currencyCode.equals(altcoin.currencyCode), "Currency mismatch: %s vs %s",
convertAltcoin.currencyCode, altcoin.currencyCode);
// Use BigInteger because it's much easier to maintain full precision without overflowing.
final BigInteger converted = BigInteger.valueOf(convertAltcoin.value).multiply(BigInteger.valueOf(coin.value))
.divide(BigInteger.valueOf(altcoin.value));
if (converted.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0
|| converted.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0)
throw new ArithmeticException("Overflow");
try {
return Coin.valueOf(converted.longValue());
} catch (IllegalArgumentException x) {
throw new ArithmeticException("Overflow: " + x.getMessage());
}
}
}