import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.*;
import android.util.AttributeSet;
import android.widget.EditText;
/**
* Invittion code
*/
public class InviteCodeEditText extends EditText implements android.text.TextWatcher
{
private static final int INVITE_CODE_TOTAL_INCLUDING_DIVIDER = 19;
private static final int INVITE_CODE_TOTAL = 16;
private static final int INVITE_CODE_MODULO = 5;
private static final int INVITE_CODE_DIVIDER_POSITION = INVITE_CODE_MODULO - 1;
private static final char INVITE_CODE_DIVIDER = '-';
public InviteCodeEditText(Context context)
{
super(context);
init();
}
public InviteCodeEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public InviteCodeEditText(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public InviteCodeEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init()
{
this.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
//NOP
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
//NOP
}
@Override
public void afterTextChanged(Editable editable)
{
if (!isValidInput(editable, INVITE_CODE_TOTAL_INCLUDING_DIVIDER, INVITE_CODE_MODULO, INVITE_CODE_DIVIDER))
{
editable.replace(0, editable.length(), concatString(toScrubbedArray(editable, INVITE_CODE_TOTAL), INVITE_CODE_DIVIDER_POSITION, INVITE_CODE_DIVIDER));
}
}
private boolean isValidInput(Editable editable, int size, int dividerPosition, char divider)
{
boolean isCorrect = editable.length() <= size;
for (int i = 0; i < editable.length(); i++)
{
if (i > 0 && (i + 1) % dividerPosition == 0)
{
isCorrect &= (divider == editable.charAt(i));
}
else
{
isCorrect &= Character.isLetterOrDigit(editable.charAt(i));
}
}
return isCorrect;
}
private String concatString(char[] letterOrDigits, int dividerPosition, char divider)
{
final StringBuilder formattedText = new StringBuilder();
for (int i = 0; i < letterOrDigits.length; i++)
{
if (letterOrDigits[i] != 0)
{
formattedText.append(letterOrDigits[i]);
if ((i > 0) && (i < (letterOrDigits.length - 1)) && (((i + 1) % dividerPosition) == 0)) // not first or last letter and next index is a divider
{
formattedText.append(divider);
}
}
}
return formattedText.toString();
}
/**
* Return an array with editable content scrubbed letters and characters
* @param editable, input data
* @param size of return array
* @return array with only upper case digits and characters
*/
private char[] toScrubbedArray(final Editable editable, final int size)
{
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < editable.length() && index < size; i++)
{
char current = editable.charAt(i);
if (Character.isLetterOrDigit(current))
{
digits[index] = Character.toUpperCase(current);
index++;
}
}
return digits;
}
public boolean isValid()
{
return (length() == INVITE_CODE_TOTAL_INCLUDING_DIVIDER);
}
}