using System;
using System.Runtime.InteropServices;
using System.Text;

using size_t = System.UInt32;
using int32_t = System.Int32;
using uint16_t = System.UInt16;

/* Type: ALLEGRO_USTR
 */
using ALLEGRO_USTR = sharpallegro5.AllegroApi._al_tagbstring;

/* Type: ALLEGRO_USTR_INFO
 */
using ALLEGRO_USTR_INFO = sharpallegro5.AllegroApi._al_tagbstring;

namespace sharpallegro5
{
    /* utf8.h */
    public partial class AllegroApi
    {
        [StructLayout(LayoutKind.Sequential)]
        public class _al_tagbstring
        {
            public int mlen;
            public int slen;
            public string data;
        }

        /* Creating strings */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_new(string s);
        //ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_new_from_buffer(string s, size_t size);
        //ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_newf(string fmt, __arglist);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_ustr_free(IntPtr us);
        //const char *al_cstr(const ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.AnsiBStr)]
        public static extern string al_cstr(IntPtr us);
        //void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_ustr_to_buffer(IntPtr us, StringBuilder buffer, int size);
        //char *al_cstr_dup(const ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        [return: MarshalAs(UnmanagedType.AnsiBStr)]
        public static extern string al_cstr_dup(IntPtr us);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_dup(IntPtr us);
        //ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos, int end_pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_dup_substr(IntPtr us, int start_pos, int end_pos);

        /* Predefined string */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_empty_string();

        /* Reference strings */
        //ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ref_cstr(IntPtr info, string s);
        //ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ref_buffer(IntPtr info, string s, size_t size);
        //ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us, int start_pos, int end_pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ref_ustr(IntPtr info, IntPtr us, int start_pos, int end_pos);

        /* Sizes and offsets */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_size(IntPtr us);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_length(IntPtr us);
        //int al_ustr_offset(const ALLEGRO_USTR *us, int index)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_offset(IntPtr us, int index);
        //bool al_ustr_next(const ALLEGRO_USTR *us, int *pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_next(IntPtr us, ref int pos);
        //bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_prev(IntPtr us, ref int pos);

        /* Get codepoints */
        //int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int32_t al_ustr_get(IntPtr us, int pos);
        //int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int32_t al_ustr_get_next(IntPtr us, ref int pos);
        //int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int32_t al_ustr_prev_get(IntPtr us, ref int pos);

        /* Insert */
        //bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_insert(IntPtr us1, int pos, IntPtr us2);
        //bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_insert_cstr(IntPtr us, int pos, string us2);
        //size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_insert_chr(IntPtr us, int pos, int32_t c);

        /* Append */
        //bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_append(IntPtr us1, IntPtr us2);
        //bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_append_cstr(IntPtr us, string s);
        //size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_append_chr(IntPtr us, int32_t c);
        //bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_appendf(IntPtr us, string fmt, __arglist);
        //bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_vappendf(IntPtr us, string fmt, __arglist);

        /* Remove */
        //bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_remove_chr(IntPtr us, int pos);
        //bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_remove_range(IntPtr us, int start_pos, int end_pos);
        //bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_truncate(IntPtr us, int start_pos);
        //bool al_ustr_ltrim_ws(ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_ltrim_ws(IntPtr us);
        //bool al_ustr_rtrim_ws(ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_rtrim_ws(IntPtr us);
        //bool al_ustr_trim_ws(ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_trim_ws(IntPtr us);

        /* Assign */
        //bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_assign(IntPtr us1, IntPtr us2);
        //bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int start_pos, int end_pos)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_assign_substr(IntPtr us1, IntPtr us2, int start_pos, int end_pos);
        //bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_assign_cstr(IntPtr us1, string s);

        /* Replace */
        //size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_set_chr(IntPtr us, int pos, int32_t c);
        //bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_replace_range(IntPtr us1, int start_pos1, int end_pos1, IntPtr us2);

        /* Searching */
        //int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_find_chr(IntPtr us, int start_pos, int32_t c);
        //int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_rfind_chr(IntPtr us, int start_pos, int32_t c);
        //public static extern int, al_ustr_find_set, (const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *accept);
        //int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos, const char *accept)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_find_set_cstr(IntPtr us, int start_pos, string accept);
        //public static extern int, al_ustr_find_cset, (const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *reject);
        //int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos, const char *reject)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_find_cset_cstr(IntPtr us, int start_pos, string reject);
        //public static extern int, al_ustr_find_str, (const ALLEGRO_USTR *haystack, int start_pos, const ALLEGRO_USTR *needle);
        //int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos, const char *needle)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_find_cstr(IntPtr haystack, int start_pos, string needle);
        //public static extern int, al_ustr_rfind_str, (const ALLEGRO_USTR *haystack, int start_pos, const ALLEGRO_USTR *needle);
        //int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos, const char *needle)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_rfind_cstr(IntPtr haystack, int start_pos, string needle);
        //bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_find_replace(IntPtr us, int start_pos, IntPtr find, IntPtr replace);
        //bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos, const char *find, const char *replace)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_find_replace_cstr(IntPtr us, int start_pos, string find, string replace);

        /* Compare */
        //bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_equal(IntPtr us1, IntPtr us2);
        //int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_compare(IntPtr u, IntPtr v);
        //int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_ustr_ncompare(IntPtr us1, IntPtr us2, int n);
        //public static extern bool, al_ustr_has_prefix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v);
        //bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_has_prefix_cstr(IntPtr u, string s);
        //public static extern bool, al_ustr_has_suffix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v);
        //bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_ustr_has_suffix_cstr(IntPtr us1, string s);

        /* Low level UTF-8 functions */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_utf8_width(int32_t c);
        //size_t al_utf8_encode(char s[], int32_t c)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_utf8_encode(StringBuilder s, int32_t c);

        /* UTF-16 */
        //ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_ustr_new_from_utf16(uint16_t[] s);
        //size_t al_ustr_size_utf16(const ALLEGRO_USTR *us)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_size_utf16(IntPtr us);
        //size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s, size_t n)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern size_t al_ustr_encode_utf16(IntPtr us, uint16_t[] s, size_t n);
        //public static extern size_t, al_utf16_width, (int c);
        //public static extern size_t, al_utf16_encode, (uint16_t s[], int32_t c);
    }
}
