package to.sparks.mtgox.model; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; import java.math.RoundingMode; import java.util.Objects; /** * A class to encapsulate all the weird mtgox money conversions. See... * https://en.bitcoin.it/wiki/MtGox/API * * @author SparksG */ public abstract class MtGoxUnitOfCredit implements Comparable<BigDecimal> { private CurrencyInfo currencyInfo; private BigDecimal numUnits; private final MathContext mc = new MathContext(0, RoundingMode.HALF_EVEN); public MtGoxUnitOfCredit(BigDecimal numUnits, CurrencyInfo currencyInfo) { this.numUnits = numUnits.setScale(currencyInfo.getDecimals(), RoundingMode.HALF_EVEN); this.currencyInfo = currencyInfo; } public MtGoxUnitOfCredit(long int_value, CurrencyInfo currencyInfo) { this.numUnits = new BigDecimal(BigInteger.valueOf(int_value), currencyInfo.getDecimals(), mc); this.currencyInfo = currencyInfo; } public MtGoxUnitOfCredit(double units, CurrencyInfo currencyInfo) { this.numUnits = new BigDecimal(units, mc).setScale(currencyInfo.getDecimals(), RoundingMode.HALF_EVEN); this.currencyInfo = currencyInfo; } @Override public int compareTo(BigDecimal competitor) { return numUnits.compareTo(competitor); } public int compareTo(MtGoxUnitOfCredit competitor) { if (isCurrenciesEquivalent(competitor)) { return compareTo(competitor.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public CurrencyInfo getCurrencyInfo() { return currencyInfo; } public void setCurrencyInfo(CurrencyInfo currencyInfo) { this.currencyInfo = currencyInfo; } public BigDecimal getNumUnits() { return numUnits; } public long longValueExact() { return numUnits.longValueExact(); } public long longValue() { return numUnits.longValue(); } public BigDecimal add(BigDecimal target) { return numUnits.add(target); } public BigDecimal subtract(BigDecimal target) { return numUnits.subtract(target); } public BigDecimal add(MtGoxUnitOfCredit target) { if (isCurrenciesEquivalent(target)) { return add(target.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public BigDecimal subtract(MtGoxUnitOfCredit target) { if (isCurrenciesEquivalent(target)) { return subtract(target.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public BigDecimal multiply(BigDecimal target) { return numUnits.multiply(target); } public BigDecimal multiply(MtGoxUnitOfCredit target) { if (isCurrenciesEquivalent(target)) { return multiply(target.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public BigDecimal divide(BigDecimal target) { return numUnits.divide(target, RoundingMode.DOWN); } public BigDecimal divide(MtGoxUnitOfCredit target) { if (isCurrenciesEquivalent(target)) { return divide(target.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public double doubleValue() { return numUnits.doubleValue(); } public BigInteger unscaledValue() { return numUnits.unscaledValue(); } public String toPlainString() { return numUnits.toPlainString(); } public boolean equals(MtGoxUnitOfCredit target) { if (isCurrenciesEquivalent(target)) { return equals(target.getNumUnits()); } else { throw new UnsupportedOperationException("Currency must be the same."); } } public boolean equals(BigDecimal target) { return numUnits.compareTo(target) == 0; } private boolean isCurrenciesEquivalent(MtGoxUnitOfCredit o) { return (currencyInfo == null && o.getCurrencyInfo() == null) || (currencyInfo != null && currencyInfo.equals(o.getCurrencyInfo())); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj instanceof MtGoxUnitOfCredit) { final MtGoxUnitOfCredit o = (MtGoxUnitOfCredit) obj; if (isCurrenciesEquivalent(o)) { return equals(o.getNumUnits()); } } else if (obj instanceof BigDecimal) { return equals((BigDecimal) obj); } return false; } @Override public int hashCode() { int hash = 13; hash = 79 * hash + Objects.hashCode(this.currencyInfo); hash = 79 * hash + Objects.hashCode(this.numUnits); return hash; } }