package com.gingersoft.gsa.cloud.common.utils.inputFilter;

import android.content.Context;
import android.text.InputFilter;
import android.util.Log;

import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 宇航.
 * User: admin
 * Date: 2020/11/25
 * Time: 17:30
 * Use:
 */
public class InputFilterUtils {
    /**
     * 只能輸入中英文和數字
     */
    public static final Pattern ChAndEnAndNum = Pattern.compile("[-a-zA-Z0-9\u4E00-\u9FA5]+");
    /**
     * 只能輸入英文和數字
     */
    public static final Pattern EnAndNum = Pattern.compile("[-a-zA-Z0-9]+");

    /**
     * emoji过滤器
     */
    public static final Pattern emoji = Pattern.compile(
            "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
            Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);

    public static InputFilter getChAndEnAndNumInputFilter(Context mContext) {
        return InputFilterUtils.getTypeFilter(mContext, "請輸入中英文和數字", InputFilterUtils.ChAndEnAndNum);
    }

    public static InputFilter getLengthFilter(Context mContext, int maxLength) {
        return InputFilterUtils.getMaxLengthFilter(mContext, "最多輸入" + maxLength + "個字", maxLength);
    }

    /**
     * source 新输入的字符串
     * start  新输入的字符串起始下标，一般为0
     * end    新输入的字符串终点下标，一般为source长度-1
     * dest   输入之前文本框内容
     * dstart 原内容起始坐标，一般为0
     * dend   原内容终点坐标，一般为dest长度-1
     *
     * @param p
     * @return
     */
    public static InputFilter getTypeFilter(Context context, String tipString, Pattern p) {
        return (source, start, end, dest, dstart, dend) -> {
            Matcher m = p.matcher(source.toString());
            if (!m.matches()) {
                if (TextUtil.isNotEmptyOrNullOrUndefined(source.toString()) &&
                        TextUtil.isNotEmptyOrNullOrUndefined(tipString)) {
                    ToastUtils.show(context, tipString);
                }
                return "";
            }
            return null;
        };
    }

    public static InputFilter getMaxLengthFilter(Context context, String tipString, int maxLength) {
        return (source, start, end, dest, dstart, dend) -> {
            int keep = maxLength - (dest.length() - (dend - dstart));
            if (keep <= 0) {
                if (TextUtil.isNotEmptyOrNullOrUndefined(source.toString()) && TextUtil.isNotEmptyOrNullOrUndefined(tipString)) {
                    ToastUtils.show(context, tipString);
                }
                return "";
            } else if (keep >= end - start) {
                return null; // keep original
            } else {
                keep += start;
                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                    --keep;
                    if (keep == start) {
                        if (TextUtil.isNotEmptyOrNullOrUndefined(tipString)) {
                            ToastUtils.show(context, tipString);
                        }
                        return "";
                    }
                }
                return source.subSequence(start, keep);
            }
        };
    }

    public static InputFilter getMaxLengthFilterDisChAndEn(int maxLength) {
        return (source, start, end, dest, dstart, dend) -> {
            if (dest != null) {
                int beforeLength = dest.length();
                int sourceLength = source.length();
                int keep = maxLength - beforeLength;
                if (keep <= 0) {
                    return "";
                } else if (keep >= sourceLength) {
                    return null; // keep original
                } else {
                    keep += start;
                    if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                        --keep;
                        if (keep == sourceLength) {
                            return "";
                        }
                    }
                    return source.subSequence(start, keep);
                }
            }
            return null;
        };
    }
}

