#ifndef SWIFT_STRING_STRING_H
#define SWIFT_STRING_STRING_H

#include <swift/data.h>
#include <swift/stdlib.h>
#include <swift/unicode.h>

#include <swift/string/api.h>

typedef struct swift_str_t swift_str_t;
typedef struct swift_str_iter_t swift_str_iter_t;

struct swift_str_t {
	char *data;
	size_t count, size;
};

struct swift_str_iter_t {
	swift_str_t *str;
	swift_uchar_t code;
	size_t pos, size;
};

#define SWIFT_STR_ITER(...) ((swift_str_iter_t){__VA_ARGS__})

SWIFT_STRING_API bool swift_init_strings(void);
SWIFT_STRING_API void swift_term_strings(void);

SWIFT_STRING_API swift_str_t *swift_new_str_size(size_t size);
SWIFT_STRING_API swift_str_t *swift_new_str(void);
SWIFT_STRING_API swift_str_t *swift_new_cstr(const char *cstr);
SWIFT_STRING_API swift_str_t *swift_new_substr(size_t pos, size_t count,
	swift_str_t *src);
SWIFT_STRING_API swift_str_t *swift_new_vstrf(const char *fmt, va_list args);
SWIFT_STRING_API swift_str_t *swift_new_strf(const char *fmt, ...);
SWIFT_STRING_API void swift_del_str(swift_str_t *str);

SWIFT_STRING_API bool swift_resize_str(swift_str_t *str, size_t size);
SWIFT_STRING_API bool swift_expand_str(swift_str_t *str, size_t count);

SWIFT_STRING_API bool swift_set_str(swift_str_t *str, swift_str_t *src);
SWIFT_STRING_API bool swift_set_cstr(swift_str_t *str, const char *data);
SWIFT_STRING_API bool swift_set_substr(swift_str_t *str, size_t pos,
	size_t count, swift_str_t *src);
SWIFT_STRING_API bool swift_set_from(swift_str_t *str, const char *src_fmt,
	const void *src, size_t src_size);
SWIFT_STRING_API bool swift_set_vstrf(swift_str_t *str, const char *fmt,
	va_list args);
SWIFT_STRING_API bool swift_set_strf(swift_str_t *str, const char *fmt, ...);
SWIFT_STRING_API bool swift_clear_str(swift_str_t *str);

SWIFT_STRING_API bool swift_append_uchar(swift_str_t *str, swift_uchar_t code);
SWIFT_STRING_API bool swift_append_str(swift_str_t *str, swift_str_t *src);
SWIFT_STRING_API bool swift_append_cstr(swift_str_t *str, const char *data);

SWIFT_STRING_API size_t swift_find_str(swift_str_t *str, size_t pos,
	swift_str_t *key);
SWIFT_STRING_API size_t swift_find_cstr(swift_str_t *str, size_t pos,
	const char *key);
SWIFT_STRING_API size_t swift_rfind_str(swift_str_t *str, size_t count,
	swift_str_t *key);
SWIFT_STRING_API size_t swift_rfind_cstr(swift_str_t *str, size_t count,
	const char *key);

SWIFT_STRING_API bool swift_remove_str(swift_str_t *str, size_t pos,
	size_t count);

SWIFT_STRING_API swift_array_t *swift_split_str(
	swift_str_t *str, swift_str_t *sep);
SWIFT_STRING_API swift_array_t *swift_split_cstr(
	swift_str_t *str, const char *sep);
SWIFT_STRING_API void swift_del_str_array(swift_array_t *str_array);

SWIFT_STRING_API swift_uchar_t swift_str_pos_get(swift_str_t *str, size_t pos);
SWIFT_STRING_API swift_str_iter_t swift_str_pos_next(swift_str_t *str,
	size_t pos);
SWIFT_STRING_API swift_str_iter_t swift_str_pos_prev(swift_str_t *str,
	size_t pos);
SWIFT_STRING_API swift_str_iter_t swift_str_first(swift_str_t *str);
SWIFT_STRING_API swift_str_iter_t swift_str_last(swift_str_t *str);
SWIFT_STRING_API bool swift_str_next(swift_str_iter_t *iter);
SWIFT_STRING_API bool swift_str_prev(swift_str_iter_t *iter);

SWIFT_STRING_API bool is_digit(size_t c);
SWIFT_STRING_API int64_t swift_str_to_int(swift_str_t *str);
SWIFT_STRING_API bool swift_str_comp(swift_str_t *str1, swift_str_t *str2);
#endif /* SWIFT_STRING_STRING_H */
