package jp.sourceforge.glad.util;

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

/**
 * 
 * @author GLAD!!
 */
public class StringUtils {

    static final String EMPTY = "";

    static final String[] EMPTY_ARRAY = {};

    StringUtils() {
    }

    public static boolean isEmpty(String s) {
        return (s == null || s.length() == 0);
    }

    public static boolean isNotEmpty(String s) {
        return !isEmpty(s);
    }

    static final Pattern WORD_PATTERN = Pattern.compile(
            "([A-Z]?[^A-Z_\\s\\p{Punct}]+|[A-Z][A-Z0-9]*(?![a-z]))");

    public static String[] splitWords(String s) {
        if (s == null) {
            return null;
        }
        if (s.length() == 0) {
            return EMPTY_ARRAY;
        }
        List<String> words = new ArrayList<String>();
        Matcher m = WORD_PATTERN.matcher(s);
        while (m.find()) {
            words.add(m.group(1));
        }
        return words.toArray(new String[words.size()]);
    }

    public static String join(Object[] array) {
        return join(array, EMPTY);
    }

    public static String join(Object[] array, char separator) {
        if (array == null) {
            return null;
        }
        return join(array, separator, 0, array.length);
    }

    public static String join(
            Object[] array, char separator, int startIndex, int endIndex) {
        if (array == null) {
            return null;
        }
        if (startIndex == endIndex) {
            return EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(array[startIndex]);
        for (int i = startIndex + 1; i < endIndex; ++i) {
            sb.append(separator);
            sb.append(array[i]);
        }
        return sb.toString();
    }

    public static String join(Object[] array, String separator) {
        if (array == null) {
            return null;
        }
        return join(array, separator, 0, array.length);
    }

    public static String join(
            Object[] array, String separator, int startIndex, int endIndex) {
        if (array == null) {
            return null;
        }
        if (startIndex == endIndex) {
            return EMPTY;
        }
        if (separator == null) {
            separator = EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(array[startIndex]);
        for (int i = startIndex + 1; i < endIndex; ++i) {
            sb.append(separator);
            sb.append(array[i]);
        }
        return sb.toString();
    }

    public static String capitalize(String s) {
        if (isEmpty(s) || Character.isUpperCase(s.charAt(0))) {
            return s;
        }
        char[] chars = s.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return String.valueOf(chars);
    }

    public static String uncapitalize(String s) {
        if (isEmpty(s) || Character.isLowerCase(s.charAt(0))) {
            return s;
        }
        char[] chars = s.toCharArray();
        int index = chars.length;
        for (int i = 1; i < index; ++i) {
            if (Character.isLowerCase(chars[i])) {
                index = i - 1;
                break;
            }
        }
        chars[0] = Character.toLowerCase(chars[0]);
        for (int i = 1; i < index; ++i) {
            chars[i] = Character.toLowerCase(chars[i]);
        }
        return String.valueOf(chars);
    }

    public static String toPascalCase(String s) {
        if (isEmpty(s)) {
            return s;
        }
        String[] words = splitWords(s);
        if (words.length == 0) {
            return EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < words.length; ++i) {
            if (words[i].length() > 0) {
                sb.append(Character.toUpperCase(words[i].charAt(0)));
                sb.append(words[i].substring(1).toLowerCase());
            }
        }
        return sb.toString();
    }

    public static String toCamelCase(String s) {
        if (isEmpty(s)) {
            return s;
        }
        String[] words = splitWords(s);
        if (words.length == 0) {
            return EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(words[0].toLowerCase());
        for (int i = 1; i < words.length; ++i) {
            if (words[i].length() > 0) {
                sb.append(Character.toUpperCase(words[i].charAt(0)));
                sb.append(words[i].substring(1).toLowerCase());
            }
        }
        return sb.toString();
    }

}
