using Php;

namespace PhpNative {
    private bool trim_char_is_in_set (char ch, string chars) {
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == ch) {
                return true;
            }
        }

        return false;
    }

    private string trim_left_whitespace (string value) {
        int start = 0;
        while (start < value.length && value[start].isspace ()) {
            start++;
        }

        return start >= value.length ? "" : value.substring (start);
    }

    private string trim_right_whitespace (string value) {
        int end = value.length;
        while (end > 0 && value[end - 1].isspace ()) {
            end--;
        }

        return end <= 0 ? "" : value.substring (0, end);
    }

    private string trim_left_chars (string value, string chars) {
        int start = 0;
        while (start < value.length && trim_char_is_in_set (value[start], chars)) {
            start++;
        }

        return start >= value.length ? "" : value.substring (start);
    }

    private string trim_right_chars (string value, string chars) {
        int end = value.length;
        while (end > 0 && trim_char_is_in_set (value[end - 1], chars)) {
            end--;
        }

        return end <= 0 ? "" : value.substring (0, end);
    }

    public string ltrim (string value, string chars = "") {
        if (chars == "") {
            return trim_left_whitespace (value);
        }

        return trim_left_chars (value, chars);
    }

    public string rtrim (string value, string chars = "") {
        if (chars == "") {
            return trim_right_whitespace (value);
        }

        return trim_right_chars (value, chars);
    }

    public string trim (string value, string chars = "") {
        if (chars == "") {
            return trim_right_whitespace (trim_left_whitespace (value));
        }

        return trim_right_chars (trim_left_chars (value, chars), chars);
    }

    public string trim_static (string value, string php_file, int php_line) throws Error {
        return trim (value);
    }

    public string ltrim_static (string value, string php_file, int php_line) throws Error {
        return ltrim (value);
    }

    public string rtrim_static (string value, string php_file, int php_line) throws Error {
        return rtrim (value);
    }

    public string rtrim_chars_static (string value, string chars, string php_file, int php_line) throws Error {
        return rtrim (value, chars);
    }

    public zval trim_zval (zval value, string php_file, int php_line) throws Error {
        return zval.string_value (trim_static (zval_to_string (value), php_file, php_line));
    }

    public zval ltrim_zval (zval value, string php_file, int php_line) throws Error {
        return zval.string_value (ltrim_static (zval_to_string (value), php_file, php_line));
    }

    public zval rtrim_zval (zval value, string php_file, int php_line) throws Error {
        return zval.string_value (rtrim_static (zval_to_string (value), php_file, php_line));
    }

    public zval rtrim_chars_zval (zval value, zval chars, string php_file, int php_line) throws Error {
        return zval.string_value (rtrim_chars_static (zval_to_string (value), zval_to_string (chars), php_file, php_line));
    }
}
