/* * Licensed Materials - Property of IBM * © Copyright IBM Corporation 2015. All Rights Reserved. */ package com.ibm.mil.readyapps.telco.mydata; import android.content.Context; import com.ibm.mil.readyapps.telco.cycles.Cycle; import com.ibm.mil.readyapps.telco.cycles.CycleModel; import com.ibm.mil.readyapps.telco.cycles.CycleModelImpl; import com.ibm.mil.readyapps.telco.offers.Offer; import com.ibm.mil.readyapps.telco.offers.OfferModel; import com.ibm.mil.readyapps.telco.offers.OfferModelImpl; import com.ibm.mil.readyapps.telco.usage.Usage; import com.ibm.mil.readyapps.telco.usage.UsageModel; import com.ibm.mil.readyapps.telco.usage.UsageModelImpl; import java.text.DecimalFormat; import java.util.List; import java.util.Locale; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.schedulers.Schedulers; /** * Presenter for Data tab responsible for setting up subscriptions to * desired streams and acting on those streams emitting new values. */ public class DataPresenterImpl implements DataPresenter { private final DataView view; private final CycleModel cycleModel; private final UsageModel usageModel; private final OfferModel offerModel; /** * Constructor for initializing necessary class properties. * * @param view the view implemented by DataFragment. */ public DataPresenterImpl(DataView view) { this.view = view; this.cycleModel = new CycleModelImpl(); this.usageModel = new UsageModelImpl(); this.offerModel = new OfferModelImpl(); } /** * Subscribe to Data cycle update stream and * call display cycle on the view each time a * new cycle is emitted from the stream. */ @Override public void getCycle() { cycleModel.getDataCycleUpdates() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Cycle>() { @Override public void call(Cycle cycle) { view.displayCycle(cycle); } }); } /** * Subscribe to app usages stream and display new * usages as they are emitted from stream. * * @param context the context needed to get initial usages */ @Override public void getAppUsages(Context context) { usageModel.getUsages(context) .subscribeOn(Schedulers.io()) .toList() .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Usage>>() { @Override public void call(List<Usage> usages) { view.displayAppUsages(usages); } }); } /** * Subscribe to app offers stream and display new * offers as they are emitted from stream. * * @param context the context needed to get initial offers */ @Override public void getAppOffers(Context context) { offerModel.getAppOffers(context) .subscribeOn(Schedulers.io()) .toList() .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Offer>>() { @Override public void call(List<Offer> offers) { view.displayAppOffers(offers); } }); } /** * Subscribe to accepted offers stream and display new * offers as they are emitted from stream. */ @Override public void getAcceptedOffers() { offerModel.getAcceptedOffers() .subscribeOn(Schedulers.io()) .toList() .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Offer>>() { @Override public void call(List<Offer> offers) { view.displayAcceptedOffers(offers); } }); offerModel.getFutureAcceptedOffers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Offer>() { @Override public void call(Offer offer) { if (offer.isAppOffer()) { addAppOffer(offer); } else { addOffer(offer); } } }); } /** * Update data cycle usage * * @param usage to update by */ private void updateCycleUsage(float usage) { Cycle cycle = cycleModel.getDataCycle(); float newUsed = cycle.getUsed() + usage; DecimalFormat df; if(Locale.getDefault().toString().equals("en_US")){ df = new DecimalFormat("#.##"); } else{ df = new DecimalFormat("#,##"); } newUsed = Float.valueOf(df.format(newUsed)); cycle.setUsed(newUsed); cycleModel.updateDataCycle(cycle); } /** * Subscribe to stream for undoing accepted offers * and remove the offers from the view. */ @Override public void listenForUndoAccept() { offerModel.getUndoOfferAcceptStream() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Offer>() { @Override public void call(Offer offer) { view.removeAcceptedOffer(offer); if (offer.isAppOffer()) { updateUsage(offer); updateAppOffer(offer); if(offer.isUnlimited()) { updateCycleUsage(offer.getUsage()); } } } }); } /** * Subscribe to stream for adding app usage. * * @param appOfferObservable the stream to subscribe to */ @Override public Subscription addAppUsage(Observable<Offer> appOfferObservable) { return appOfferObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Offer>() { @Override public void call(Offer offer) { addUsage(offer); addOffer(offer); offer.setBody(offer.getBody()); if(offer.isUnlimited()){ updateCycleUsage(-offer.getUsage()); } view.removeAppOffer(offer); } }); } /** * Subscribe to stream for updating cycle and update model * and view as new objects emitted. * * @param cycleObservable the stream to subscribe to */ @Override public void updateDataPlan(Observable<Cycle> cycleObservable) { cycleObservable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Cycle>() { @Override public void call(Cycle cycle) { cycleModel.updateDataCycle(cycle); updateDataPlan(cycle); } }); } /** * Subscribe to stream for removing offers and update * model and view as new objects emitted. * * @param removeOfferStream the stream to subscribe to */ @Override public void removeOffer(Observable<Offer> removeOfferStream) { removeOfferStream.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Offer>() { @Override public void call(Offer offer) { offerModel.removeAcceptedOffer(offer); view.removeAcceptedOffer(offer); if (offer.isAppOffer()) { updateUsage(offer); updateAppOffer(offer); if (offer.isUnlimited()) { updateCycleUsage(offer.getUsage()); } } } }); } /** * Add an app offer to the model. * * @param appOffer the offer to add */ @Override public void addAppOffer(Offer appOffer) { offerModel.acceptAppOffer(appOffer); } /** * Update the model and the view when a new offer should be * added to app offer section. * * @param offer the offer to add to app offer section */ private void updateAppOffer(Offer offer) { offerModel.addAppOffer(offer); view.displayAppOffer(offer); } /** * Update app usage section model and view. * * @param offer the offer to update usage section with */ private void updateUsage(Offer offer) { Usage usage = usageModel.setLimitedUsage(offer); view.displayNewUsage(usage); } /** * Subscribe to stream for undoing removal of an offer * and update model and view when it happens. * * @param observable the stream to subscribe to */ @Override public void undoRemoveOffer(Observable<Offer> observable) { observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Offer>() { @Override public void call(Offer offer) { if(offer.isAppOffer()){ offerModel.acceptAppOffer(offer); } else{ view.displayCardOffer(offer); } } }); } /** * Update view with an added offer. * * @param offer the offer to add */ private void addOffer(Offer offer) { view.displayCardOffer(offer); } /** * Update model and view with a new app usage. * * @param offer the app usage offer to update with */ private void addUsage(Offer offer) { Usage newUsage = new Usage(); newUsage = newUsage.offerToUsage(offer); usageModel.setNewUsage(newUsage); view.displayNewUsage(newUsage); } /** * Update the view with new cycle. * * @param cycle the cycle to refresh view with */ private void updateDataPlan(Cycle cycle) { view.updateCycleView(cycle); } }