// compile with:
// gcc test_pango.c -Wall -o test_pango `pkg-config --cflags --libs pango`

#include <locale.h>
#include <unistd.h>
#include <pango/pango.h>


void read_test_string(gchar *prompt, GString **buffer) {

  GIOChannel *channel;

  channel = g_io_channel_unix_new(STDIN_FILENO);

  if (isatty(STDIN_FILENO))
    g_print("%s", prompt);

  *buffer = g_string_new("");
  g_io_channel_read_line_string(channel, *buffer, NULL, NULL);
  g_io_channel_shutdown(channel, TRUE, NULL);
  g_string_truncate(*buffer, (**buffer).len-1);

  if (g_utf8_validate((**buffer).str, -1, NULL) == FALSE) {
    g_error("Invalid UTF-8 string.");
  }
}


void get_log_attrs(GString* s, PangoLogAttr **log_attrs, guint *nlog_attrs) {
  
  *nlog_attrs = g_utf8_strlen(s->str, -1) + 1;
  *log_attrs = g_new(PangoLogAttr, *nlog_attrs);

  pango_get_log_attrs(s->str, s->len, -1, pango_language_get_default(), 
		      *log_attrs, *nlog_attrs);
}


enum { 
  WORD_START, 
  WORD_END, 
  WORD_BOUNDARY
};

guint get_field(PangoLogAttr *log_attr, guint field) {
  switch(field) {
  case WORD_START:
    return log_attr->is_word_start;
  case WORD_END:
    return log_attr->is_word_end;
  case WORD_BOUNDARY:
  default:
    return log_attr->is_word_boundary;
  }
}

guint *get_attr(PangoLogAttr *log_attrs, guint nlog_attrs, guint attr) {
  guint *attrv;
  guint i;
  attrv = g_malloc(sizeof(gint) * nlog_attrs);
  for (i = 0; i < nlog_attrs; i++) {
    attrv[i] = get_field(&log_attrs[i], attr);
  }
  return attrv;
}


GString *insert_marks(GString *s, guint *positions, guint npos, gchar mark) {
  guint i;
  gchar *p;
  p = s->str;
  for (i = 0; i < npos; i++) {
    if (positions[i]) {
      g_string_insert_c(s, p-(s->str), mark);
      p++;
    }
    p = g_utf8_next_char(p);
  }
  return s;
}

void print_attr(GString *s, PangoLogAttr *log_attrs, guint nlog_attrs, 
		gint attr, gchar mark) {
  GString *attr_str;
  guint *attrv;

  attrv = get_attr(log_attrs, nlog_attrs, attr);
  attr_str = insert_marks(g_string_new(s->str), attrv, nlog_attrs, mark);
  g_print("%s\n", attr_str->str);
  g_string_free(attr_str, TRUE);
  g_free(attrv);
}


int main(gint argc, char* argv[]) {
  guint nlog_attrs;
  gchar mark_character;
  GString *test_string;
  PangoLogAttr *log_attrs;

  setlocale(LC_ALL, "");

  mark_character = '|';

  read_test_string("Enter a test string (finish with RET): ", &test_string);
  get_log_attrs(test_string, &log_attrs, &nlog_attrs);

  g_print("Language is \"%s\".\n", 
	  pango_language_to_string(pango_language_get_default()));
  g_print("Mark character is \"%c\".\n", mark_character);

  g_print("%-20s", "Word start: ");
  print_attr(test_string, log_attrs, nlog_attrs, WORD_START, mark_character);

  g_print("%-20s", "Word end: ");
  print_attr(test_string, log_attrs, nlog_attrs, WORD_END, mark_character);

  g_print("%-20s", "Word boundary: ");
  print_attr(test_string, log_attrs, nlog_attrs, WORD_BOUNDARY, mark_character);

  g_string_free(test_string, TRUE);
  g_free(log_attrs);
  return 0;
}
