package jp.webpay.android.token.ui.field;
import android.content.Context;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jp.webpay.android.token.R;
import jp.webpay.android.token.model.RawCard;
import jp.webpay.android.token.validator.ExpiryValidator;
public class ExpiryField extends MultiColumnCardField {
public static final String SEPARATOR = " / ";
private Integer mValidMonth;
private Integer mValidYear;
public ExpiryField(Context context) {
super(context, SEPARATOR);
initialize();
}
public ExpiryField(Context context, AttributeSet attrs) {
super(context, attrs, SEPARATOR);
initialize();
}
public ExpiryField(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle, SEPARATOR);
initialize();
}
private void initialize() {
setHint(R.string.field_expiry_hint);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
@Override
protected boolean validateCurrentValue() {
String pair[] = parseToPair(getText().toString());
String month = pair[0];
String year = pair[1];
try {
mValidMonth = Integer.valueOf(month);
mValidYear = Integer.valueOf(year);
} catch (NumberFormatException e) {
mValidMonth = null;
mValidYear = null;
return false;
}
if (ExpiryValidator.isValid(mValidMonth, mValidYear)) {
return true;
} else {
mValidMonth = null;
mValidYear = null;
return false;
}
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
String pair[] = parseToPair(getText().toString());
String month = pair[0];
String year = pair[1];
if (month != null && year != null && month.length() == 2 && year.equals("20")) {
setText(month + "/ 2020");
}
super.onFocusChange(v, hasFocus);
}
@Override
public void updateCard(RawCard card) {
card.expMonth(mValidMonth);
card.expYear(mValidYear);
}
@Override
protected String formatVisibleText(String current) {
// "0" -> "0" (for 08)
// "1 -> "1" (for 12)
// "13" -> "1"
// "12" -> "12 / "
// "209 / " -> "02 / "
// "8" -> "08 / " (add 0 to 1-digit month)
// "08 / 2" -> "08 / 2" (as is)
// "08 / 1" -> "08 / 201" (other than 2)
// "08 / 21" -> "08 / 2021"
// "08 / 2014" -> "08 / 2014" (as is)
// "08 / 12014" -> "08 / 2012"
String pair[] = parseToPair(current);
String month = pair[0];
String year = pair[1];
if (month == null)
return "";
if (month.length() > 0 && month.charAt(0) >= '2') {
month = "0" + month;
}
if (month.length() > 2) {
month = month.substring(0, 2);
}
if (year == null) {
if (month.length() == 2) {
if (month.charAt(0) == '1' && month.charAt(1) >= '3') {
return month.substring(0, 1);
} else {
return month + SEPARATOR;
}
} else {
return month;
}
}
if (year.length() > 0 && year.charAt(0) != '2') {
year = "20" + year;
}
if (year.length() == 2 && year.charAt(1) != '0') {
year = "20" + year;
}
if (year.length() > 4) {
year = year.substring(0, 4);
}
return month + SEPARATOR + year;
}
// Return array [month part, year part].
// null if not yet entered.
private String[] parseToPair(String current) {
Pattern pat = Pattern.compile("(\\d+)([^\\d]+(\\d+)?)?");
Matcher matcher = pat.matcher(current);
if (!matcher.matches()) {
return new String[2];
}
if (matcher.group(2) == null) {
// year part is unavailable
return new String[]{matcher.group(1), null};
}
return new String[]{matcher.group(1), matcher.group(3)};
}
/**
* Validity of month value is paired with year.
* Get two values at once.
* @return input expiry month value if valid, null otherwise
*/
public Integer getValidMonth() {
return mValidMonth;
}
/**
* Validity of year value is paired with month.
* Get two values at once.
* @return input expiry year value if valid, null otherwise
*/
public Integer getValidYear() {
return mValidYear;
}
}