package co.smartreceipts.android.model.impl;
import android.os.Parcel;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import co.smartreceipts.android.model.Price;
import co.smartreceipts.android.model.PriceCurrency;
import co.smartreceipts.android.model.factory.ExchangeRateBuilderFactory;
import co.smartreceipts.android.model.gson.ExchangeRate;
import co.smartreceipts.android.model.utils.ModelUtils;
/**
* Defines an immutable implementation of the {@link co.smartreceipts.android.model.Price} interface
* for a collection of other price objects.
* <p/>
* TODO: Eventually normally for a single currency. Very hacky now
*
* @author williambaumann
*/
public final class ImmutableLegacyNetPriceImpl extends AbstractPriceImpl {
private final List<Price> mPrices;
private final Map<PriceCurrency, BigDecimal> mCurrencyToPriceMap;
private final BigDecimal mPossiblyIncorrectTotalPrice;
private final PriceCurrency mCurrency;
private final ExchangeRate mExchangeRate;
public ImmutableLegacyNetPriceImpl(@NonNull List<Price> prices) {
mPrices = Collections.unmodifiableList(prices);
mCurrencyToPriceMap = new HashMap<>();
BigDecimal possiblyIncorrectTotalPrice = new BigDecimal(0);
PriceCurrency currency = null;
for (final Price price : prices) {
possiblyIncorrectTotalPrice = possiblyIncorrectTotalPrice.add(price.getPrice());
final BigDecimal priceToAdd = mCurrencyToPriceMap.containsKey(price.getCurrency()) ? mCurrencyToPriceMap.get(price.getCurrency()).add(price.getPrice()) : price.getPrice();
mCurrencyToPriceMap.put(price.getCurrency(), priceToAdd);
if (currency == null) {
currency = price.getCurrency();
} else if (!currency.equals(price.getCurrency())) {
currency = PriceCurrency.MIXED_CURRENCY; // Mark as fixed if multiple
}
}
mCurrency = currency;
mPossiblyIncorrectTotalPrice = possiblyIncorrectTotalPrice;
final ExchangeRateBuilderFactory builder = new ExchangeRateBuilderFactory();
if (mCurrency != null) {
builder.setBaseCurrency(mCurrency);
}
mExchangeRate = builder.build();
}
private ImmutableLegacyNetPriceImpl(@NonNull Parcel in) {
this(restorePricesFromParcel(in));
}
private static List<Price> restorePricesFromParcel(Parcel in) {
final int size = in.readInt();
final List<Price> prices = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
final Price price = in.readParcelable(Price.class.getClassLoader());
prices.add(price);
}
return prices;
}
@Override
public float getPriceAsFloat() {
return mPossiblyIncorrectTotalPrice.floatValue();
}
@NonNull
@Override
public BigDecimal getPrice() {
return mPossiblyIncorrectTotalPrice;
}
@NonNull
@Override
public String getDecimalFormattedPrice() {
return ModelUtils.getDecimalFormattedValue(mPossiblyIncorrectTotalPrice);
}
@NonNull
@Override
public String getCurrencyFormattedPrice() {
final List<String> currencyStrings = new ArrayList<>();
for (PriceCurrency currency : mCurrencyToPriceMap.keySet()) {
currencyStrings.add(ModelUtils.getCurrencyFormattedValue(mCurrencyToPriceMap.get(currency), currency));
}
return TextUtils.join("; ", currencyStrings);
}
@NonNull
@Override
public String getCurrencyCodeFormattedPrice() {
final List<String> currencyStrings = new ArrayList<>();
for (PriceCurrency currency : mCurrencyToPriceMap.keySet()) {
currencyStrings.add(ModelUtils.getCurrencyCodeFormattedValue(mCurrencyToPriceMap.get(currency), currency));
}
return TextUtils.join("; ", currencyStrings);
}
@NonNull
@Override
public PriceCurrency getCurrency() {
return mCurrency;
}
@NonNull
@Override
public String getCurrencyCode() {
return mCurrency.getCurrencyCode();
}
@NonNull
@Override
public ExchangeRate getExchangeRate() {
return mExchangeRate;
}
@Override
public String toString() {
return getCurrencyFormattedPrice();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mPrices.size());
for (Price price : mPrices) {
dest.writeParcelable(price, 0);
}
}
public static final Creator<ImmutableLegacyNetPriceImpl> CREATOR = new Creator<ImmutableLegacyNetPriceImpl>() {
public ImmutableLegacyNetPriceImpl createFromParcel(Parcel source) {
return new ImmutableLegacyNetPriceImpl(source);
}
public ImmutableLegacyNetPriceImpl[] newArray(int size) {
return new ImmutableLegacyNetPriceImpl[size];
}
};
}