package me.xdrop.ensurej.checks;

import me.xdrop.ensurej.Predicate;

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

public class CheckString {

    public static Predicate<String> isAllUppercase(final boolean allowNonChar) {
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                for (int i = 0; i < s.length(); i++) {
                    char ch = s.charAt(i);
                    if (Character.isLowerCase(ch) || (!allowNonChar && !Character.isUpperCase(ch))) {
                        return false;
                    }
                }

                return true;

            }
        };
    }

    public static Predicate<String> isAllLowercase(final boolean allowNonChar){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {

                for (int i = 0; i < s.length(); i++) {
                    char ch = s.charAt(i);
                    if ((Character.isUpperCase(ch)) || !allowNonChar && !Character.isLowerCase(ch)) {
                        return false;
                    }
                }
                return true;
            }
        };
    }

    public static Predicate<String> matches(final String pattern){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                Pattern p = Pattern.compile(pattern);
                Matcher matcher = p.matcher(s);
                return matcher.matches();
            }
        };
    }

    public static Predicate<String> hasOnlyLetters(final boolean unicode){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                if (unicode) {
                    for (int i = 0; i < s.length(); i++) {
                        char ch = s.charAt(i);
                        if (!Character.isLetter(ch)) {
                            return false;
                        }
                    }
                    return true;
                } else {
                    return matches("^[a-zA-Z]+$").eval(s);
                }

            }
        };
    }

    public static Predicate<String> hasOnlyDigits(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {

                for (int i = 0; i < s.length(); i++) {
                    char ch = s.charAt(i);
                    if (!Character.isDigit(ch)) {
                        return false;
                    }
                }
                return true;

            }
        };
    }

    public static Predicate<String> isNotEmpty(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return s != null && matches("[^\\s+]").eval(s);
            }
        };
    }

    public static Predicate<String> isEmpty(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return !isNotEmpty().eval(s);
            }
        };
    }

    public static Predicate<String> isNotNull(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return s != null;
            }
        };
    }

    public static Predicate<String> hasWhitespaceStart(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return matches("\\s+.*").eval(s);
            }
        };
    }

    public static Predicate<String> hasWhitespaceEnd(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return matches(".*\\s").eval(s);
            }
        };
    }

    public static Predicate<String> isTrimmed(){
        return new Predicate<String>() {
            @Override
            public boolean eval(String s) {
                return !hasWhitespaceStart().eval(s) && !hasWhitespaceEnd().eval(s);
            }
        };
    }

    public static Predicate<String> lengthBetween(final int lower, final int upper){

        return new Predicate<String>() {
            @Override
            public boolean eval(String in) {
                int length = in.length();
                return length >= lower && length < upper;
            }
        };

    }
}

@@ -27,16 +27,47 @@
 hecks;%0A%0A
+import me.xdrop.ensurej.Chain;%0A
 import m
@@ -4470,11 +4470,423 @@
 ;%0A%0A    %7D
+%0A%0A    public static Predicate%3CString%3E allLetters(final Character c)%7B%0A        return new Predicate%3CString%3E() %7B%0A            @Override%0A            public boolean eval(String in) %7B%0A                for (int i = 0; i %3C in.length(); i++)%7B%0A                    if(in.charAt(i) != c)%7B%0A                        return false;%0A                    %7D%0A                %7D%0A                return true;%0A            %7D%0A        %7D;%0A    %7D
 %0A%7D%0A

Add check for all letters