package jp.webpay.android.token.ui;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.util.List;
import jp.webpay.android.token.R;
import jp.webpay.android.token.WebPay;
import jp.webpay.android.token.WebPayListener;
import jp.webpay.android.token.model.AccountAvailability;
import jp.webpay.android.token.model.CardType;
import jp.webpay.android.token.model.Token;
/**
* A fragment to create WebPay client-side token.
* Activities that contain this fragment must implement the
* {@link WebPayTokenCompleteListener} interface
* to handle tokens created.
* Use the {@link WebPayTokenFragment#newInstance} factory method to
* create an instance of this fragment.
*
*/
public class WebPayTokenFragment extends Fragment implements WebPayTokenCompleteListener {
private static final String ARG_PUBLISHABLE_KEY = "publishableKey";
private static final String CARD_DIALOG_FRAGMENT_TAG = "card_dialog";
private WebPayTokenCompleteListener mListener;
private String mPublishableKey;
private List<CardType> mCardTypesSupported;
private Button mOpenButton;
private boolean mHaveToken = false;
private @StringRes int mOpenButtonTitle = R.string.token_fragment_open_dialog;
private @StringRes int mCardDialogSendButtonTitle = R.string.card_send;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param publishableKey WebPay publishable key to generate token
* @return A new instance of fragment WebPayTokenFragment.
*/
public static WebPayTokenFragment newInstance(String publishableKey) {
WebPayTokenFragment fragment = new WebPayTokenFragment();
Bundle args = new Bundle();
args.putString(ARG_PUBLISHABLE_KEY, publishableKey);
fragment.setArguments(args);
return fragment;
}
public WebPayTokenFragment() {
// Required empty public constructor
}
/**
* Set button title to open card information dialog.
* Default is {@code jp.webpay.android.R.string.token_fragment_open_dialog}, which is "Pay with card".
* This method works before and after fragment is created, but has no effect if token is generated.
*
* @param openButtonTitle title res id
*/
public void setOpenButtonTitle(@StringRes int openButtonTitle) {
mOpenButtonTitle = openButtonTitle;
if (mOpenButton != null && !mHaveToken) {
mOpenButton.setText(openButtonTitle);
}
}
/**
* Set send button title of card dialog created in this token fragment.
* Default is {@code jp.webpay.android.R.string.card_send}, which is "Pay with card".
* This is delegated to {@link CardDialogFragment#setSendButtonTitle(int)}
* on opening dialog.
* So call after dialog open does not effect current one.
*
* @param cardDialogSendButtonTitle title res id
*/
public void setCardDialogSendButtonTitle(@StringRes int cardDialogSendButtonTitle) {
this.mCardDialogSendButtonTitle = cardDialogSendButtonTitle;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() == null) {
throw new IllegalStateException("WebPayTokenFragment must be initialized using WebPayTokenFragment.newInstance()");
}
mPublishableKey = getArguments().getString(ARG_PUBLISHABLE_KEY);
if (mPublishableKey == null || mPublishableKey.equals("")) {
throw new IllegalArgumentException("WebPayTokenFragment requires publishableKey to present. " +
"You can find the key starts with \"test_public_\" in WebPay settings page.");
}
retrieveAvailability();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_web_pay_token, container, false);
mOpenButton = (Button)view.findViewById(R.id.open_dialog_button);
mOpenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// cardTypesSupported is best-effort. Continue even if null.
CardDialogFragment fragment = CardDialogFragment.newInstance(mPublishableKey, mCardTypesSupported);
fragment.setSendButtonTitle(mCardDialogSendButtonTitle);
fragment.show(getChildFragmentManager(), CARD_DIALOG_FRAGMENT_TAG);
}
});
if (!mHaveToken)
mOpenButton.setText(mOpenButtonTitle);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (WebPayTokenCompleteListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement WebPayTokenCompleteListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// Delegate OnCompleteListener from CardDialogFragment to mListener,
// while setting views to reflect current token status.
@Override
public void onTokenCreated(Token token) {
mListener.onTokenCreated(token);
mHaveToken = true;
mOpenButton.setText(R.string.token_fragment_token_generated);
}
@Override
public void onCancelled(Throwable throwable) {
mListener.onCancelled(throwable);
}
private void retrieveAvailability() {
new WebPay(mPublishableKey).retrieveAvailability(new WebPayListener<AccountAvailability>() {
@Override
public void onCreate(AccountAvailability result) {
mCardTypesSupported = result.cardTypesSupported;
}
@Override
public void onException(Throwable cause) {
// ignore failures
// card types supported is not necessary for creating a token
}
});
}
}