package jstellarapi.core;
import java.math.BigDecimal;
import java.math.BigInteger;
import jstellarapi.connection.JSONSerializable;
import org.json.simple.JSONObject;
public class DenominatedIssuedCurrency implements JSONSerializable {
public BigDecimal amount;
public BigInteger microStrAmount;
public StellarAddress issuer;
public String currency;
public static final int MIN_SCALE = -96;
public static final int MAX_SCALE = 80;
public static final BigInteger MICROSTR_PER_STR = BigInteger.valueOf(1_000_000);
public static final DenominatedIssuedCurrency ONE_STR=new DenominatedIssuedCurrency(BigInteger.ONE);
public static final DenominatedIssuedCurrency FEE = new DenominatedIssuedCurrency(BigInteger.TEN);
public DenominatedIssuedCurrency(){ //FIXME get rid of this
}
public DenominatedIssuedCurrency(String amount, StellarAddress issuer, String currencyStr){
this(new BigDecimal(amount).stripTrailingZeros(), issuer, currencyStr);
}
public DenominatedIssuedCurrency(BigDecimal amount, StellarAddress issuer, String currencyStr){
int oldScale=amount.scale();
if(oldScale<MIN_SCALE || oldScale>MAX_SCALE){
int newScale=MAX_SCALE-(amount.precision()-amount.scale());
if(newScale<MIN_SCALE || newScale>MAX_SCALE){
throw new RuntimeException("newScale "+newScale+" is out of range");
}
amount=amount.setScale(newScale);
}
this.amount = amount;
this.issuer = issuer;
this.currency = currencyStr;
if(issuer==null || currencyStr==null){
throw new Error("Issuer or currency canot be null for non-STR currency");
}
}
public DenominatedIssuedCurrency(BigInteger micro_stellarAmount) {
this.microStrAmount=micro_stellarAmount;
}
public DenominatedIssuedCurrency(String amountInMicroSTR) {
microStrAmount=new BigInteger(amountInMicroSTR);
}
public boolean isNative() {
return issuer==null;
}
public boolean isNegative() {
return amount.signum()==-1;
}
@Override
public String toString() {
if(issuer==null || currency==null){
return new BigDecimal(microStrAmount).movePointLeft(6).stripTrailingZeros().toPlainString()+" STR";
}
return amount.stripTrailingZeros().toPlainString()+"/"+currency+"/"+issuer;
}
@Override
public void copyFrom(JSONObject jsonDenomination) {
issuer = new StellarAddress(((String) jsonDenomination.get("issuer")));
String currencyStr = ((String) jsonDenomination.get("currency"));
currency = currencyStr;
String amountStr = (String) jsonDenomination.get("value");
amount=new BigDecimal(amountStr);
}
public void copyFrom(Object jsonObject) {
if(jsonObject instanceof String){
amount=new BigDecimal((String) jsonObject);
}
else{
copyFrom((JSONObject) jsonObject);
}
}
@SuppressWarnings("unchecked")
public Object toJSON(){
if(isNative()){
return microStrAmount.toString();
}
else{
JSONObject jsonThis = new JSONObject();
jsonThis.put("value", amount.toPlainString());
jsonThis.put("issuer", issuer.toString());
jsonThis.put("currency", currency);
return jsonThis;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((amount == null) ? 0 : amount.hashCode());
result = prime * result
+ ((currency == null) ? 0 : currency.hashCode());
result = prime * result
+ ((issuer == null) ? 0 : issuer.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DenominatedIssuedCurrency other = (DenominatedIssuedCurrency) obj;
if (amount == null) {
if (other.amount != null)
return false;
} else if (amount.compareTo(other.amount)!=0)
return false;
if (currency == null) {
if (other.currency != null)
return false;
} else if (!currency.equals(other.currency))
return false;
if (issuer == null) {
if (other.issuer != null)
return false;
} else if (!issuer.equals(other.issuer))
return false;
return true;
}
public long toMicroSTR() {
if(isNative()==false){
throw new RuntimeException("Cannot get micro STR on a non-STR currency");
}
return this.microStrAmount.longValue();
}
}