// Path: backbone/src/main/java/org/researchstack/backbone/ui/step/body/BodyAnswer.java
// public class BodyAnswer {
//     public static final BodyAnswer VALID = new BodyAnswer(true, 0);
//     public static final BodyAnswer INVALID = new BodyAnswer(false,
//             R.string.rsb_invalid_answer_default);
// 
//     private boolean isValid;
//     private int reason;
//     private String[] params;
// 
//     public BodyAnswer(boolean isValid, @StringRes int reason, String... params) {
//         this.isValid = isValid;
//         this.reason = reason;
//         this.params = params;
//     }
// 
//     public boolean isValid() {
//         return isValid;
//     }
// 
//     @StringRes
//     public int getReason() {
//         return reason;
//     }
// 
//     public String[] getParams() {
//         return params;
//     }
// 
//     public String getString(Context context) {
//         if (getParams().length == 0) {
//             return context.getString(getReason());
//         } else {
//             return context.getString(getReason(), getParams());
//         }
//     }
// }
// 
// Path: backbone/src/main/java/org/researchstack/backbone/utils/TextUtils.java
// public class TextUtils {
//     public static final Pattern EMAIL_ADDRESS = Pattern.compile(
//             "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
//                     "\\@" +
//                     "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
//                     "(" +
//                     "\\." +
//                     "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
//                     ")+");
// 
//     private TextUtils() {
//     }
// 
//     /**
//      * Returns true if the string is null or 0-length.
//      *
//      * @param str the string to be examined
//      * @return true if str is null or zero length
//      */
//     public static boolean isEmpty(CharSequence str) {
//         if (str == null || str.length() == 0) {
//             return true;
//         } else {
//             return false;
//         }
//     }
// 
//     /**
//      * Returns true if the char sequence is a valid email address
//      *
//      * @param text the email address to be validated
//      * @return a boolean indicating whether the email is valid
//      */
//     public static boolean isValidEmail(CharSequence text) {
//         return !isEmpty(text) && EMAIL_ADDRESS.matcher(text).matches();
//     }
// 
// 
//     public static class AlphabeticFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isLetter(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// 
//     public static class NumericFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isDigit(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// 
//     public static class AlphanumericFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isLetterOrDigit(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// }


import org.researchstack.backbone.R;
import org.researchstack.backbone.ui.step.body.BodyAnswer;
import org.researchstack.backbone.utils.TextUtils;
package org.researchstack.backbone.answerformat;


/**
 * This class defines the attributes for a decimal answer format that participants enter using a
 * numeric keyboard.
 * <p>
 * If you specify maximum or minimum values and the user enters a value outside the specified range,
 * the DecimalQuestionBody does not allow navigation until the participant provides a value that is
 * within the valid range.
 */
public class DecimalAnswerFormat extends AnswerFormat {
    private float minValue;
    private float maxValue;

    /**
     * Creates an answer format with the specified min and max values
     *
     * @param minValue the minimum allowed value
     * @param maxValue the maximum allowed value, or 0f for unlimited
     */
    public DecimalAnswerFormat(float minValue, float maxValue) {
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    @Override
    public QuestionType getQuestionType() {
        return Type.Decimal;
    }

    /**
     * Returns the min value
     *
     * @return returns the min value
     */
    public float getMinValue() {
        return minValue;
    }

    /**
     * Returns the max value, or 0f for no maximum
     *
     * @return returns the max value, or 0f for no maximum
     */
    public float getMaxValue() {
        return maxValue;
    }

    public BodyAnswer validateAnswer(String inputString) {
        // If no answer is recorded
// Path: backbone/src/main/java/org/researchstack/backbone/ui/step/body/BodyAnswer.java
// public class BodyAnswer {
//     public static final BodyAnswer VALID = new BodyAnswer(true, 0);
//     public static final BodyAnswer INVALID = new BodyAnswer(false,
//             R.string.rsb_invalid_answer_default);
// 
//     private boolean isValid;
//     private int reason;
//     private String[] params;
// 
//     public BodyAnswer(boolean isValid, @StringRes int reason, String... params) {
//         this.isValid = isValid;
//         this.reason = reason;
//         this.params = params;
//     }
// 
//     public boolean isValid() {
//         return isValid;
//     }
// 
//     @StringRes
//     public int getReason() {
//         return reason;
//     }
// 
//     public String[] getParams() {
//         return params;
//     }
// 
//     public String getString(Context context) {
//         if (getParams().length == 0) {
//             return context.getString(getReason());
//         } else {
//             return context.getString(getReason(), getParams());
//         }
//     }
// }
// 
// Path: backbone/src/main/java/org/researchstack/backbone/utils/TextUtils.java
// public class TextUtils {
//     public static final Pattern EMAIL_ADDRESS = Pattern.compile(
//             "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
//                     "\\@" +
//                     "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
//                     "(" +
//                     "\\." +
//                     "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
//                     ")+");
// 
//     private TextUtils() {
//     }
// 
//     /**
//      * Returns true if the string is null or 0-length.
//      *
//      * @param str the string to be examined
//      * @return true if str is null or zero length
//      */
//     public static boolean isEmpty(CharSequence str) {
//         if (str == null || str.length() == 0) {
//             return true;
//         } else {
//             return false;
//         }
//     }
// 
//     /**
//      * Returns true if the char sequence is a valid email address
//      *
//      * @param text the email address to be validated
//      * @return a boolean indicating whether the email is valid
//      */
//     public static boolean isValidEmail(CharSequence text) {
//         return !isEmpty(text) && EMAIL_ADDRESS.matcher(text).matches();
//     }
// 
// 
//     public static class AlphabeticFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isLetter(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// 
//     public static class NumericFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isDigit(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// 
//     public static class AlphanumericFilter implements InputFilter {
//         @Override
//         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
//             for (int i = start; i < end; i++) {
//                 if (!Character.isLetterOrDigit(source.charAt(i))) {
//                     return "";
//                 }
//             }
//             return null;
//         }
//     }
// }


// Path: backbone/src/main/java/org/researchstack/backbone/answerformat/DecimalAnswerFormat.java
import org.researchstack.backbone.R;
import org.researchstack.backbone.ui.step.body.BodyAnswer;
import org.researchstack.backbone.utils.TextUtils;

package org.researchstack.backbone.answerformat;


/**
 * This class defines the attributes for a decimal answer format that participants enter using a
 * numeric keyboard.
 * <p>
 * If you specify maximum or minimum values and the user enters a value outside the specified range,
 * the DecimalQuestionBody does not allow navigation until the participant provides a value that is
 * within the valid range.
 */
public class DecimalAnswerFormat extends AnswerFormat {
    private float minValue;
    private float maxValue;

    /**
     * Creates an answer format with the specified min and max values
     *
     * @param minValue the minimum allowed value
     * @param maxValue the maximum allowed value, or 0f for unlimited
     */
    public DecimalAnswerFormat(float minValue, float maxValue) {
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    @Override
    public QuestionType getQuestionType() {
        return Type.Decimal;
    }

    /**
     * Returns the min value
     *
     * @return returns the min value
     */
    public float getMinValue() {
        return minValue;
    }

    /**
     * Returns the max value, or 0f for no maximum
     *
     * @return returns the max value, or 0f for no maximum
     */
    public float getMaxValue() {
        return maxValue;
    }

    public BodyAnswer validateAnswer(String inputString) {
        // If no answer is recorded
        if (inputString == null || TextUtils.isEmpty(inputString)) {