<commit_before>package com.stripe.android.view;

import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;

import com.stripe.android.model.Card;
import com.stripe.android.util.StripeTextUtils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * An {@link EditText} that handles spacing out the digits of a credit card.
 */
public class CardNumberEditText extends EditText {

    private static final int MAX_LENGTH_COMMON = 19;
    // Note that AmEx and Diners Club have the same length
    // because Diners Club has one more space, but one less digit.
    private static final int MAX_LENGTH_AMEX_DINERS = 17;

    private static final Integer[] SPACES_ARRAY_COMMON = {4, 9, 14};
    private static final Set<Integer> SPACE_SET_COMMON =
            new HashSet<>(Arrays.asList(SPACES_ARRAY_COMMON));

    private static final Integer[] SPACES_ARRAY_AMEX = {4, 11};
    private static final Set<Integer> SPACE_SET_AMEX =
            new HashSet<>(Arrays.asList(SPACES_ARRAY_AMEX));

    @VisibleForTesting @Card.CardBrand String mCardBrand = Card.UNKNOWN;
    private int mLengthMax = 19;

    public CardNumberEditText(Context context) {
        super(context);
        listenForTextChanges();
    }

    public CardNumberEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        listenForTextChanges();
    }

    public CardNumberEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        listenForTextChanges();
    }

    @VisibleForTesting
    int updateSelectionIndex(int oldPosition, int oldLength, int newLength) {
        int increment, newPosition;
        Set<Integer> spaceSet = Card.AMERICAN_EXPRESS.equals(mCardBrand)
                ? SPACE_SET_AMEX
                : SPACE_SET_COMMON;

        boolean growing = newLength > oldLength;

        if (growing) {
            increment = spaceSet.contains(oldPosition) ? 2 : 1;
            newPosition = oldPosition + increment;
            return newPosition <= newLength ? newPosition : newLength;
        } else {
            increment = spaceSet.contains(oldPosition - 2) ? 2 : 1;
            newPosition = oldPosition - increment;
            return newPosition > 0 ? newPosition : 0;
        }
    }

    private void listenForTextChanges() {
        addTextChangedListener(new TextWatcher() {
            boolean ignoreChanges = false;
            int beforeStringLength = 0;
            int beforeSelectionIndex = 0;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (!ignoreChanges) {<commit_msg>adding javadoc to a package function<commit_after>package com.stripe.android.view;

import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;

import com.stripe.android.model.Card;
import com.stripe.android.util.StripeTextUtils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * An {@link EditText} that handles spacing out the digits of a credit card.
 */
public class CardNumberEditText extends EditText {

    private static final int MAX_LENGTH_COMMON = 19;
    // Note that AmEx and Diners Club have the same length
    // because Diners Club has one more space, but one less digit.
    private static final int MAX_LENGTH_AMEX_DINERS = 17;

    private static final Integer[] SPACES_ARRAY_COMMON = {4, 9, 14};
    private static final Set<Integer> SPACE_SET_COMMON =
            new HashSet<>(Arrays.asList(SPACES_ARRAY_COMMON));

    private static final Integer[] SPACES_ARRAY_AMEX = {4, 11};
    private static final Set<Integer> SPACE_SET_AMEX =
            new HashSet<>(Arrays.asList(SPACES_ARRAY_AMEX));

    @VisibleForTesting @Card.CardBrand String mCardBrand = Card.UNKNOWN;
    private int mLengthMax = 19;

    public CardNumberEditText(Context context) {
        super(context);
        listenForTextChanges();
    }

    public CardNumberEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        listenForTextChanges();
    }

    public CardNumberEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        listenForTextChanges();
    }

    /**
     * Updates the selection index based on the current (pre-edit) index, and
     * the size change of the number being input.
     *
     * @param oldPosition the original position of the cursor
     * @param oldLength the pre-edit length of the string
     * @param newLength the post-edit length of the string
     * @return an index within the string at which to put the cursor
     */
    @VisibleForTesting
    int updateSelectionIndex(int oldPosition, int oldLength, int newLength) {
        int increment, newPosition;
        Set<Integer> spaceSet = Card.AMERICAN_EXPRESS.equals(mCardBrand)
                ? SPACE_SET_AMEX
                : SPACE_SET_COMMON;

        boolean growing = newLength > oldLength;

        if (growing) {
            increment = spaceSet.contains(oldPosition) ? 2 : 1;
            newPosition = oldPosition + increment;
            return newPosition <= newLength ? newPosition : newLength;
        } else {
            increment = spaceSet.contains(oldPosition - 2) ? 2 : 1;
            newPosition = oldPosition - increment;
            return newPosition > 0 ? newPosition : 0;
        }
    }

    private void listenForTextChanges() {
        addTextChangedListener(new TextWatcher() {
            boolean ignoreChanges = false;
            int beforeStringLength = 0;
            int beforeSelectionIndex = 0;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (!ignoreChanges) {
{'fraction_non_alphanumeric': 0.0792385291246339, 'fraction_numerical': 0.007159127888057273, 'mean_word_length': 2.920280612244898, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '139626', 'n_tokens_mistral': 1735, 'n_tokens_neox': 1672, 'n_words': 488}