#ifndef _TT_TEXTBUF_H_ /************************************************************************************/
#define _TT_TEXTBUF_H_

/****************************************************************************************************************/

#include <sys/types.h>
#include <stdio.h>

#ifdef linux
#include "../libtools/include/osdep.h"
#endif

#ifdef WIN32
#include "../libtools/include/osdep.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************************************************/

struct textbuf;

struct textbuf *tb_alloc(size_t size);
struct textbuf *tb_init(void *buf, size_t size);

typedef void tb_putc_t(int ch, void *data);
struct textbuf *tb_init_callback(struct textbuf *tb, tb_putc_t *func, void *data);

void tb_free(struct textbuf *tb);

void tb_clear(struct textbuf *tb);

int tb_puts(const char *str, struct textbuf *tb);
int tb_putc(int ch, struct textbuf *tb);
int tb_write(const void *ptr, size_t size, struct textbuf *tb);
void tb_printf(struct textbuf *tb, const char *fmt, ...);
void tb_vprintf(struct textbuf *tb, const char *fmt, va_list va);
void tb_printsize(struct textbuf *tb, size64_t bytes);

void tb_begin_list(struct textbuf *tb, const char *prefix);
void tb_end_list(struct textbuf *tb, const char *suffix);
void tb_set_list_separator(struct textbuf *tb, const char *sep);

size_t tb_len(struct textbuf *tb);
size_t tb_len_ansi(struct textbuf *tb);
const char *tb_text(struct textbuf *tb);

/****************************************************************************************************************/

struct tb_wordwrap_info {
  // First line
  size_t width_1;		// Total line width in visible characters
  size_t indent_1;		// Indenting to use
  const char *prefix_1;		// Prefix to put at start of line

  // Further lines
  size_t width_n;		// Total line width in visible characters
  size_t indent_n;		// Indenting to use
  const char *prefix_n;		// Prefix to put at start of line
};

struct textbuf *tb_format(struct textbuf *tb, const struct tb_wordwrap_info *wwi, struct textbuf *out);
struct textbuf *tb_format_string(const char *str, const struct tb_wordwrap_info *wwi, struct textbuf *out);

void tb_puts_wordwrap(struct textbuf *tb, const struct tb_wordwrap_info *wwi, FILE *fd);

/****************************************************************************************************************/
// PRIVATE

#define TEXTBUF_MAXLISTDEPTH 4

struct textbuf {
  size_t bufsize;
  size_t buflen;
  const char *liststates[TEXTBUF_MAXLISTDEPTH];
  const char *listsep;
  tb_putc_t *cb_func;
  void *cb_data;
  int listdepth;
#ifndef __cplusplus
  char buf[0];
#endif
};

/****************************************************************************************************************/

#ifdef __cplusplus
}
#endif

#endif
