/*
* Licensed Materials - Property of IBM
* © Copyright IBM Corporation 2015. All Rights Reserved.
*/
package com.ibm.mil.readyapps.telco.offers;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.SystemClock;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.ibm.mil.readyapps.telco.R;
import com.ibm.mil.readyapps.telco.baseplan.BasePlanModelImpl;
import com.ibm.mil.readyapps.telco.cycles.CycleModel;
import com.ibm.mil.readyapps.telco.cycles.CycleModelImpl;
import com.ibm.mil.readyapps.telco.mydata.DataRecyclerAdapter;
import com.ibm.mil.readyapps.telco.termsconditions.TermsConditionsActivity;
import com.ibm.mil.readyapps.telco.views.RobotoTextView;
import com.yqritc.recyclerviewmultipleviewtypesadapter.DataBindAdapter;
import com.yqritc.recyclerviewmultipleviewtypesadapter.DataBinder;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.Bind;
import butterknife.OnClick;
import rx.Observable;
import rx.subjects.PublishSubject;
/**
* Binder to append the user data/talk/text accepted offer information
* to the corresponding recyclerView ViewHolder
*/
public class AcceptedOfferBinder extends DataBinder<AcceptedOfferBinder.OfferViewHolder> {
private final CoordinatorLayout snackbar_layout;
private final Context context;
private DataRecyclerAdapter dataRecyclerAdapter;
private final Resources resources;
private long mLastClickTime = 0;
private final int BINDER_OFFSET = 3;
private List<Offer> offers;
private Offer originalOffer;
private final BasePlanModelImpl basePlanModel;
private final OfferModel offerModel;
private final PublishSubject<Offer> removeOfferStream;
private static final CycleModel cycleModel = new CycleModelImpl();
/**
* Constructor to initialize the cycle binder
*
* @param dataBindAdapter the adapter that uses this binder to populate the recyclerView
* @param layout coordinator layout from the main activity
* used for inflating the snackBar
* @param context context from the main activity
* used to access application resources
*/
public AcceptedOfferBinder(DataBindAdapter dataBindAdapter, CoordinatorLayout layout, Context context) {
super(dataBindAdapter);
this.snackbar_layout = layout;
removeOfferStream = PublishSubject.create();
this.context = context;
offerModel = new OfferModelImpl();
resources = context.getResources();
this.basePlanModel = new BasePlanModelImpl();
if (dataBindAdapter instanceof DataRecyclerAdapter)
dataRecyclerAdapter = (DataRecyclerAdapter) dataBindAdapter;
}
/**
* creates a new ViewHolder using the provided xml layout
*
* @param viewGroup the parent ViewGroup that this ViewHolder will inflate
* specifies the xml layout that the binder should use to create the view
* @return the inflated view
*/
@Override
public OfferViewHolder newViewHolder(ViewGroup viewGroup) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.telco_card_layout_view, viewGroup, false);
return new OfferViewHolder(view);
}
/**
* @param offerViewHolder the ViewHolder to use onBind
* has all the associated views in this layout
* @param position the position of this ViewHolder in the binder
*/
@Override
public void bindViewHolder(OfferViewHolder offerViewHolder, int position) {
Offer offer = offers.get(position);
offerViewHolder.iconImageView.setImageResource(offer.getCardIcon());
offerViewHolder.titleTextView.setText(offer.getTitle());
offerViewHolder.bodyTextView.setText(offer.getBody());
offerViewHolder.costTextView.setText(offer.getLocalizedCost());
offerViewHolder.removeOfferBtn.setText(context.getString(R.string.card_remove));
}
@Override
public int getItemCount() {
return offers.size();
}
/**
* Add all accepted offers for data/talk/text to the binder dataset
* @param offers to add
*/
public void addAll(List<Offer> offers) {
this.offers = offers;
notifyBinderDataSetChanged();
}
/**
* @param offer to remove from accepted offers
*/
public void remove(Offer offer) {
offers.remove(offer);
cycleModel.setLimit(offer.getType(), -offer.getAmountAddedToCycle());
notifyDataSetChanged();
}
/**
* @param offer to add to the accepted offers list
*/
public void addNewCard(Offer offer) {
offers.add(offer);
notifyDataSetChanged();
}
/**
* Get position of the accepted app offer
* @param position position of recyclerView that was accessed
* @return position of the accepted offer with respect to the
* accepted offers list not the recyclerView
*/
private int getCardPosition(int position) {
int usageCount = dataRecyclerAdapter.getAppUsageBinder().getItemCount();
int myAppCount = dataRecyclerAdapter.getMyAppBinder().getItemCount();
int BINDER_DATA_OFFSET = 4;
return position - BINDER_DATA_OFFSET - (usageCount + myAppCount);
}
/**
* Get the Publish Subject stream that observes when an accepted offer is removed
*
* @return observable for the offer remove update
*/
public Observable<Offer> getRemoveOfferStream() {
return removeOfferStream;
}
/**
* create a SnackBar after changing base plan
* the user gets ability to undo the plan change
*
* @param addedCost the amount added/removed after plan change
* used to undo the plan change
*/
private void createSnackBar(final int addedCost) {
View.OnClickListener undoAction;
/**
* on click listener for undo of offer removal
*/
undoAction = new View.OnClickListener() {
@Override
public void onClick(View view) {
view.setEnabled(false);
cycleModel.setLimit(originalOffer.getType(), originalOffer.getAmountAddedToCycle());
offerModel.undoRemove(originalOffer);
basePlanModel.updateCost(-addedCost, originalOffer.doesAffectBaseCost());
}
};
//build the SnackBar and display it
Snackbar.make(snackbar_layout, resources.getString(R.string.baseplan_snackbar), Snackbar.LENGTH_LONG)
.setAction(resources.getString(R.string.undo), undoAction)
.setActionTextColor(resources.getColor(R.color.light_indigo))
.show();
}
/**
* Starts a the TermsConditionsActivity and passes along data from the passed offer
* @param selectedOffer The selected offer
* @param offerContext The context of the selected offer
*/
private void goToInfo(Offer selectedOffer, Context offerContext) {
String offerTitle = selectedOffer.getTitle();
String termsCond = selectedOffer.getTermsConditions();
Intent intent = new Intent(offerContext, TermsConditionsActivity.class);
intent.putExtra(TermsConditionsActivity.OFFER_TITLE, offerTitle);
intent.putExtra(TermsConditionsActivity.OFFER_TERMS_CONDITIONS, termsCond);
offerContext.startActivity(intent);
}
/**
* Define the OfferViewHolder
* inject views that need to be updated in the ViewHolder onBind
*/
public class OfferViewHolder extends RecyclerView.ViewHolder{
@Bind(R.id.offer_title) RobotoTextView titleTextView;
@Bind(R.id.offer_body) RobotoTextView bodyTextView;
@Bind(R.id.card_icon) ImageView iconImageView;
@Bind(R.id.costTextView) RobotoTextView costTextView;
@Bind(R.id.accept) RobotoTextView removeOfferBtn;
public OfferViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
/**
* Remove accepted offer cards from data/talk/text
* update the basePlan accordingly
* provide options for undo
*
* @param view view that was clicked
*/
@OnClick(R.id.accept)public void onRemoveClick(View view){
//prevent multiple fast clicks
if (SystemClock.elapsedRealtime() - mLastClickTime < 500){
return;
}
mLastClickTime = SystemClock.elapsedRealtime();
Offer offerToRemove;
if (dataRecyclerAdapter != null) {
offerToRemove = offers.get(getCardPosition(getAdapterPosition()));
} else {
offerToRemove = offers.get(getAdapterPosition() - BINDER_OFFSET);
}
originalOffer = offerToRemove;
createSnackBar(-(int) offerToRemove.getCost());
removeOfferStream.onNext(offerToRemove);
basePlanModel.updateCost(-offerToRemove.getCost(), offerToRemove.doesAffectBaseCost());
}
/**
* When the info icon button is clicked on a card, need to get the offer
* that was selected and call the function goToInfo()
* @param view The view that was clicked
*/
@OnClick(R.id.info_icon_button)public void onInfoClick(View view){
Offer selectedOffer;
if (dataRecyclerAdapter != null) {
selectedOffer = offers.get(getCardPosition(getAdapterPosition()));
} else {
selectedOffer = offers.get(getAdapterPosition() - BINDER_OFFSET);
}
goToInfo(selectedOffer, view.getContext());
}
}
}