/* GStreamer TTML subtitle parser
 * Copyright (C) <2015> British Broadcasting Corporation
 *   Authors:
 *     Chris Bass <dash@rd.bbc.co.uk>
 *     Peter Taylour <dash@rd.bbc.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/*
 * Parses subtitle files encoded using the EBU-TT-D profile of TTML, as defined
 * in https://tech.ebu.ch/files/live/sites/tech/files/shared/tech/tech3380.pdf
 * and http://www.w3.org/TR/ttaf1-dfxp/, respectively.
 */

#include <glib.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include "ttmlparse.h"
#include "subtitle.h"
#include "subtitlemeta.h"

#define DEFAULT_CELLRES_X 32
#define DEFAULT_CELLRES_Y 15
#define MAX_FONT_FAMILY_NAME_LENGTH 128
#define NSECONDS_IN_DAY 24 * 3600 * GST_SECOND

#define TTML_CHAR_NULL 0x00
#define TTML_CHAR_SPACE 0x20
#define TTML_CHAR_TAB 0x09
#define TTML_CHAR_LF 0x0A
#define TTML_CHAR_CR 0x0D

GST_DEBUG_CATEGORY_EXTERN (ttmlparse_debug);
#define GST_CAT_DEFAULT ttmlparse_debug

static gchar *ttml_get_xml_property (const xmlNode * node, const char *name);
static gpointer ttml_copy_tree_element (gconstpointer src, gpointer data);

typedef struct _TtmlStyleSet TtmlStyleSet;
typedef struct _TtmlElement TtmlElement;
typedef struct _TtmlScene TtmlScene;

typedef enum
{
  TTML_ELEMENT_TYPE_STYLE,
  TTML_ELEMENT_TYPE_REGION,
  TTML_ELEMENT_TYPE_BODY,
  TTML_ELEMENT_TYPE_DIV,
  TTML_ELEMENT_TYPE_P,
  TTML_ELEMENT_TYPE_SPAN,
  TTML_ELEMENT_TYPE_ANON_SPAN,
  TTML_ELEMENT_TYPE_BR
} TtmlElementType;

typedef enum
{
  TTML_WHITESPACE_MODE_NONE,
  TTML_WHITESPACE_MODE_DEFAULT,
  TTML_WHITESPACE_MODE_PRESERVE,
} TtmlWhitespaceMode;

struct _TtmlElement
{
  TtmlElementType type;
  gchar *id;
  TtmlWhitespaceMode whitespace_mode;
  gchar **styles;
  gchar *region;
  GstClockTime begin;
  GstClockTime end;
  TtmlStyleSet *style_set;
  gchar *text;
};

/* Represents a static scene consisting of one or more trees of elements that
 * should be visible over a specific period of time. */
struct _TtmlScene
{
  GstClockTime begin;
  GstClockTime end;
  GList *trees;
  GstBuffer *buf;
};

struct _TtmlStyleSet
{
  GHashTable *table;
};


static TtmlStyleSet *
ttml_style_set_new (void)
{
  TtmlStyleSet *ret = g_slice_new0 (TtmlStyleSet);
  ret->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  return ret;
}


static void
ttml_style_set_delete (TtmlStyleSet * style_set)
{
  if (style_set) {
    g_hash_table_unref (style_set->table);
    g_slice_free (TtmlStyleSet, style_set);
  }
}


/* If attribute with name @attr_name already exists in @style_set, its value
 * will be replaced by @attr_value. */
static gboolean
ttml_style_set_add_attr (TtmlStyleSet * style_set, const gchar * attr_name,
    const gchar * attr_value)
{
  return g_hash_table_insert (style_set->table, g_strdup (attr_name),
      g_strdup (attr_value));
}


static gboolean
ttml_style_set_contains_attr (TtmlStyleSet * style_set, const gchar * attr_name)
{
  return g_hash_table_contains (style_set->table, attr_name);
}


static const gchar *
ttml_style_set_get_attr (TtmlStyleSet * style_set, const gchar * attr_name)
{
  return g_hash_table_lookup (style_set->table, attr_name);
}


static guint8
ttml_hex_pair_to_byte (const gchar * hex_pair)
{
  gint hi_digit, lo_digit;

  hi_digit = g_ascii_xdigit_value (*hex_pair);
  lo_digit = g_ascii_xdigit_value (*(hex_pair + 1));
  return (hi_digit << 4) + lo_digit;
}


/* Color strings in EBU-TT-D can have the form "#RRBBGG" or "#RRBBGGAA". */
static GstSubtitleColor
ttml_parse_colorstring (const gchar * color)
{
  guint length;
  const gchar *c = NULL;
  GstSubtitleColor ret = { 0, 0, 0, 0 };

  if (!color)
    return ret;

  length = strlen (color);
  if (((length == 7) || (length == 9)) && *color == '#') {
    c = color + 1;

    ret.r = ttml_hex_pair_to_byte (c);
    ret.g = ttml_hex_pair_to_byte (c + 2);
    ret.b = ttml_hex_pair_to_byte (c + 4);

    if (length == 7)
      ret.a = G_MAXUINT8;
    else
      ret.a = ttml_hex_pair_to_byte (c + 6);

    GST_CAT_LOG (ttmlparse_debug, "Returning color - r:%u  b:%u  g:%u  a:%u",
        ret.r, ret.b, ret.g, ret.a);
  } else {
    GST_CAT_ERROR (ttmlparse_debug, "Invalid color string: %s", color);
  }

  return ret;
}


static void
ttml_style_set_print (TtmlStyleSet * style_set)
{
  GHashTableIter iter;
  gpointer attr_name, attr_value;

  if (!style_set) {
    GST_CAT_LOG (ttmlparse_debug, "\t\t[NULL]");
    return;
  }

  g_hash_table_iter_init (&iter, style_set->table);
  while (g_hash_table_iter_next (&iter, &attr_name, &attr_value)) {
    GST_CAT_LOG (ttmlparse_debug, "\t\t%s: %s", (const gchar *) attr_name,
        (const gchar *) attr_value);
  }
}


static TtmlStyleSet *
ttml_parse_style_set (const xmlNode * node)
{
  TtmlStyleSet *s;
  gchar *value = NULL;
  xmlAttrPtr attr;

  value = ttml_get_xml_property (node, "id");
  if (!value) {
    GST_CAT_ERROR (ttmlparse_debug, "styles must have an ID.");
    return NULL;
  }
  g_free (value);

  s = ttml_style_set_new ();

  for (attr = node->properties; attr != NULL; attr = attr->next) {
    if (attr->ns && ((g_strcmp0 ((const gchar *) attr->ns->prefix, "tts") == 0)
            || (g_strcmp0 ((const gchar *) attr->ns->prefix, "ebutts") == 0))) {
      ttml_style_set_add_attr (s, (const gchar *) attr->name,
          (const gchar *) attr->children->content);
    }
  }

  return s;
}


static void
ttml_delete_element (TtmlElement * element)
{
  g_free ((gpointer) element->id);
  if (element->styles)
    g_strfreev (element->styles);
  g_free ((gpointer) element->region);
  ttml_style_set_delete (element->style_set);
  g_free ((gpointer) element->text);
  g_slice_free (TtmlElement, element);
}


static gchar *
ttml_get_xml_property (const xmlNode * node, const char *name)
{
  xmlChar *xml_string = NULL;
  gchar *gst_string = NULL;

  g_return_val_if_fail (strlen (name) < 128, NULL);

  xml_string = xmlGetProp (node, (xmlChar *) name);
  if (!xml_string)
    return NULL;
  gst_string = g_strdup ((gchar *) xml_string);
  xmlFree (xml_string);
  return gst_string;
}


/* EBU-TT-D timecodes have format hours:minutes:seconds[.fraction] */
static GstClockTime
ttml_parse_timecode (const gchar * timestring)
{
  gchar **strings;
  guint64 hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
  GstClockTime time = GST_CLOCK_TIME_NONE;

  GST_CAT_LOG (ttmlparse_debug, "time string: %s", timestring);

  strings = g_strsplit (timestring, ":", 3);
  if (g_strv_length (strings) != 3U) {
    GST_CAT_ERROR (ttmlparse_debug, "badly formatted time string: %s",
        timestring);
    return time;
  }

  hours = g_ascii_strtoull (strings[0], NULL, 10U);
  minutes = g_ascii_strtoull (strings[1], NULL, 10U);
  if (g_strstr_len (strings[2], -1, ".")) {
    guint n_digits;
    gchar **substrings = g_strsplit (strings[2], ".", 2);
    seconds = g_ascii_strtoull (substrings[0], NULL, 10U);
    n_digits = strlen (substrings[1]);
    milliseconds = g_ascii_strtoull (substrings[1], NULL, 10U);
    milliseconds =
        (guint64) (milliseconds * pow (10.0, (3 - (double) n_digits)));
    g_strfreev (substrings);
  } else {
    seconds = g_ascii_strtoull (strings[2], NULL, 10U);
  }

  if (minutes > 59 || seconds > 60) {
    GST_CAT_ERROR (ttmlparse_debug, "invalid time string "
        "(minutes or seconds out-of-bounds): %s\n", timestring);
  }

  g_strfreev (strings);
  GST_CAT_LOG (ttmlparse_debug,
      "hours: %" G_GUINT64_FORMAT "  minutes: %" G_GUINT64_FORMAT
      "  seconds: %" G_GUINT64_FORMAT "  milliseconds: %" G_GUINT64_FORMAT "",
      hours, minutes, seconds, milliseconds);

  time = hours * GST_SECOND * 3600
      + minutes * GST_SECOND * 60
      + seconds * GST_SECOND + milliseconds * GST_MSECOND;

  return time;
}


static TtmlElement *
ttml_parse_element (const xmlNode * node)
{
  TtmlElement *element;
  TtmlElementType type;
  gchar *value;

  GST_CAT_DEBUG (ttmlparse_debug, "Element name: %s",
      (const char *) node->name);
  if ((g_strcmp0 ((const char *) node->name, "style") == 0)) {
    type = TTML_ELEMENT_TYPE_STYLE;
  } else if ((g_strcmp0 ((const char *) node->name, "region") == 0)) {
    type = TTML_ELEMENT_TYPE_REGION;
  } else if ((g_strcmp0 ((const char *) node->name, "body") == 0)) {
    type = TTML_ELEMENT_TYPE_BODY;
  } else if ((g_strcmp0 ((const char *) node->name, "div") == 0)) {
    type = TTML_ELEMENT_TYPE_DIV;
  } else if ((g_strcmp0 ((const char *) node->name, "p") == 0)) {
    type = TTML_ELEMENT_TYPE_P;
  } else if ((g_strcmp0 ((const char *) node->name, "span") == 0)) {
    type = TTML_ELEMENT_TYPE_SPAN;
  } else if ((g_strcmp0 ((const char *) node->name, "text") == 0)) {
    type = TTML_ELEMENT_TYPE_ANON_SPAN;
  } else if ((g_strcmp0 ((const char *) node->name, "br") == 0)) {
    type = TTML_ELEMENT_TYPE_BR;
  } else {
    return NULL;
  }

  element = g_slice_new0 (TtmlElement);
  element->type = type;

  if ((value = ttml_get_xml_property (node, "id"))) {
    element->id = g_strdup (value);
    g_free (value);
  }

  if ((value = ttml_get_xml_property (node, "style"))) {
    element->styles = g_strsplit (value, " ", 0);
    GST_CAT_DEBUG (ttmlparse_debug, "%u style(s) referenced in element.",
        g_strv_length (element->styles));
    g_free (value);
  }

  if (element->type == TTML_ELEMENT_TYPE_STYLE
      || element->type == TTML_ELEMENT_TYPE_REGION) {
    TtmlStyleSet *ss;
    ss = ttml_parse_style_set (node);
    if (ss)
      element->style_set = ss;
    else
      GST_CAT_WARNING (ttmlparse_debug,
          "Style or Region contains no styling attributes.");
  }

  if ((value = ttml_get_xml_property (node, "region"))) {
    element->region = g_strdup (value);
    g_free (value);
  }

  if ((value = ttml_get_xml_property (node, "begin"))) {
    element->begin = ttml_parse_timecode (value);
    g_free (value);
  } else {
    element->begin = GST_CLOCK_TIME_NONE;
  }

  if ((value = ttml_get_xml_property (node, "end"))) {
    element->end = ttml_parse_timecode (value);
    g_free (value);
  } else {
    element->end = GST_CLOCK_TIME_NONE;
  }

  if (node->content) {
    GST_CAT_LOG (ttmlparse_debug, "Node content: %s", node->content);
    element->text = g_strdup ((const gchar *) node->content);
  }

  if (element->type == TTML_ELEMENT_TYPE_BR)
    element->text = g_strdup ("\n");

  if ((value = ttml_get_xml_property (node, "space"))) {
    if (g_strcmp0 (value, "preserve") == 0)
      element->whitespace_mode = TTML_WHITESPACE_MODE_PRESERVE;
    else if (g_strcmp0 (value, "default") == 0)
      element->whitespace_mode = TTML_WHITESPACE_MODE_DEFAULT;
    g_free (value);
  }

  return element;
}


static GNode *
ttml_parse_body (const xmlNode * node)
{
  GNode *ret;
  TtmlElement *element;

  GST_CAT_LOG (ttmlparse_debug, "parsing node %s", node->name);
  element = ttml_parse_element (node);
  if (element)
    ret = g_node_new (element);
  else
    return NULL;

  for (node = node->children; node != NULL; node = node->next) {
    GNode *descendants = NULL;
    if ((descendants = ttml_parse_body (node)))
      g_node_append (ret, descendants);
  }

  return ret;
}


/* Update the fields of a GstSubtitleStyleSet, @style_set, according to the
 * values defined in a TtmlStyleSet, @tss, and a given cell resolution. */
static void
ttml_update_style_set (GstSubtitleStyleSet * style_set, TtmlStyleSet * tss,
    guint cellres_x, guint cellres_y)
{
  const gchar *attr;

  if ((attr = ttml_style_set_get_attr (tss, "textDirection"))) {
    if (g_strcmp0 (attr, "rtl") == 0)
      style_set->text_direction = GST_SUBTITLE_TEXT_DIRECTION_RTL;
    else
      style_set->text_direction = GST_SUBTITLE_TEXT_DIRECTION_LTR;
  }

  if ((attr = ttml_style_set_get_attr (tss, "fontFamily"))) {
    if (strlen (attr) <= MAX_FONT_FAMILY_NAME_LENGTH) {
      g_free (style_set->font_family);
      style_set->font_family = g_strdup (attr);
    } else {
      GST_CAT_WARNING (ttmlparse_debug,
          "Ignoring font family name as it's overly long.");
    }
  }

  if ((attr = ttml_style_set_get_attr (tss, "fontSize"))) {
    style_set->font_size = g_ascii_strtod (attr, NULL) / 100.0;
  }
  style_set->font_size *= (1.0 / cellres_y);

  if ((attr = ttml_style_set_get_attr (tss, "lineHeight"))) {
    if (g_strcmp0 (attr, "normal") == 0)
      style_set->line_height = -1;
    else
      style_set->line_height = g_ascii_strtod (attr, NULL) / 100.0;
  }

  if ((attr = ttml_style_set_get_attr (tss, "textAlign"))) {
    if (g_strcmp0 (attr, "left") == 0)
      style_set->text_align = GST_SUBTITLE_TEXT_ALIGN_LEFT;
    else if (g_strcmp0 (attr, "center") == 0)
      style_set->text_align = GST_SUBTITLE_TEXT_ALIGN_CENTER;
    else if (g_strcmp0 (attr, "right") == 0)
      style_set->text_align = GST_SUBTITLE_TEXT_ALIGN_RIGHT;
    else if (g_strcmp0 (attr, "end") == 0)
      style_set->text_align = GST_SUBTITLE_TEXT_ALIGN_END;
    else
      style_set->text_align = GST_SUBTITLE_TEXT_ALIGN_START;
  }

  if ((attr = ttml_style_set_get_attr (tss, "color"))) {
    style_set->color = ttml_parse_colorstring (attr);
  }

  if ((attr = ttml_style_set_get_attr (tss, "backgroundColor"))) {
    style_set->background_color = ttml_parse_colorstring (attr);
  }

  if ((attr = ttml_style_set_get_attr (tss, "fontStyle"))) {
    if (g_strcmp0 (attr, "italic") == 0)
      style_set->font_style = GST_SUBTITLE_FONT_STYLE_ITALIC;
    else
      style_set->font_style = GST_SUBTITLE_FONT_STYLE_NORMAL;
  }

  if ((attr = ttml_style_set_get_attr (tss, "fontWeight"))) {
    if (g_strcmp0 (attr, "bold") == 0)
      style_set->font_weight = GST_SUBTITLE_FONT_WEIGHT_BOLD;
    else
      style_set->font_weight = GST_SUBTITLE_FONT_WEIGHT_NORMAL;
  }

  if ((attr = ttml_style_set_get_attr (tss, "textDecoration"))) {
    if (g_strcmp0 (attr, "underline") == 0)
      style_set->text_decoration = GST_SUBTITLE_TEXT_DECORATION_UNDERLINE;
    else
      style_set->text_decoration = GST_SUBTITLE_TEXT_DECORATION_NONE;
  }

  if ((attr = ttml_style_set_get_attr (tss, "unicodeBidi"))) {
    if (g_strcmp0 (attr, "embed") == 0)
      style_set->unicode_bidi = GST_SUBTITLE_UNICODE_BIDI_EMBED;
    else if (g_strcmp0 (attr, "bidiOverride") == 0)
      style_set->unicode_bidi = GST_SUBTITLE_UNICODE_BIDI_OVERRIDE;
    else
      style_set->unicode_bidi = GST_SUBTITLE_UNICODE_BIDI_NORMAL;
  }

  if ((attr = ttml_style_set_get_attr (tss, "wrapOption"))) {
    if (g_strcmp0 (attr, "noWrap") == 0)
      style_set->wrap_option = GST_SUBTITLE_WRAPPING_OFF;
    else
      style_set->wrap_option = GST_SUBTITLE_WRAPPING_ON;
  }

  if ((attr = ttml_style_set_get_attr (tss, "multiRowAlign"))) {
    if (g_strcmp0 (attr, "start") == 0)
      style_set->multi_row_align = GST_SUBTITLE_MULTI_ROW_ALIGN_START;
    else if (g_strcmp0 (attr, "center") == 0)
      style_set->multi_row_align = GST_SUBTITLE_MULTI_ROW_ALIGN_CENTER;
    else if (g_strcmp0 (attr, "end") == 0)
      style_set->multi_row_align = GST_SUBTITLE_MULTI_ROW_ALIGN_END;
    else
      style_set->multi_row_align = GST_SUBTITLE_MULTI_ROW_ALIGN_AUTO;
  }

  if ((attr = ttml_style_set_get_attr (tss, "linePadding"))) {
    style_set->line_padding = g_ascii_strtod (attr, NULL);
    style_set->line_padding *= (1.0 / cellres_x);
  }

  if ((attr = ttml_style_set_get_attr (tss, "origin"))) {
    gchar *c;
    style_set->origin_x = g_ascii_strtod (attr, &c) / 100.0;
    while (!g_ascii_isdigit (*c) && *c != '+' && *c != '-')
      ++c;
    style_set->origin_y = g_ascii_strtod (c, NULL) / 100.0;
  }

  if ((attr = ttml_style_set_get_attr (tss, "extent"))) {
    gchar *c;
    style_set->extent_w = g_ascii_strtod (attr, &c) / 100.0;
    if ((style_set->origin_x + style_set->extent_w) > 1.0) {
      style_set->extent_w = 1.0 - style_set->origin_x;
    }
    while (!g_ascii_isdigit (*c) && *c != '+' && *c != '-')
      ++c;
    style_set->extent_h = g_ascii_strtod (c, NULL) / 100.0;
    if ((style_set->origin_y + style_set->extent_h) > 1.0) {
      style_set->extent_h = 1.0 - style_set->origin_y;
    }
  }

  if ((attr = ttml_style_set_get_attr (tss, "displayAlign"))) {
    if (g_strcmp0 (attr, "center") == 0)
      style_set->display_align = GST_SUBTITLE_DISPLAY_ALIGN_CENTER;
    else if (g_strcmp0 (attr, "after") == 0)
      style_set->display_align = GST_SUBTITLE_DISPLAY_ALIGN_AFTER;
    else
      style_set->display_align = GST_SUBTITLE_DISPLAY_ALIGN_BEFORE;
  }

  if ((attr = ttml_style_set_get_attr (tss, "padding"))) {
    gchar **decimals;
    guint n_decimals;
    guint i;

    decimals = g_strsplit (attr, "%", 0);
    n_decimals = g_strv_length (decimals) - 1;
    for (i = 0; i < n_decimals; ++i)
      g_strstrip (decimals[i]);

    switch (n_decimals) {
      case 1:
        style_set->padding_start = style_set->padding_end =
            style_set->padding_before = style_set->padding_after =
            g_ascii_strtod (decimals[0], NULL) / 100.0;
        break;

      case 2:
        style_set->padding_before = style_set->padding_after =
            g_ascii_strtod (decimals[0], NULL) / 100.0;
        style_set->padding_start = style_set->padding_end =
            g_ascii_strtod (decimals[1], NULL) / 100.0;
        break;

      case 3:
        style_set->padding_before = g_ascii_strtod (decimals[0], NULL) / 100.0;
        style_set->padding_start = style_set->padding_end =
            g_ascii_strtod (decimals[1], NULL) / 100.0;
        style_set->padding_after = g_ascii_strtod (decimals[2], NULL) / 100.0;
        break;

      case 4:
        style_set->padding_before = g_ascii_strtod (decimals[0], NULL) / 100.0;
        style_set->padding_end = g_ascii_strtod (decimals[1], NULL) / 100.0;
        style_set->padding_after = g_ascii_strtod (decimals[2], NULL) / 100.0;
        style_set->padding_start = g_ascii_strtod (decimals[3], NULL) / 100.0;
        break;
    }
    g_strfreev (decimals);

    /* Padding values in TTML files are relative to the region width & height;
     * make them relative to the overall display width & height like all other
     * dimensions. */
    style_set->padding_before *= style_set->extent_h;
    style_set->padding_after *= style_set->extent_h;
    style_set->padding_end *= style_set->extent_w;
    style_set->padding_start *= style_set->extent_w;
  }

  if ((attr = ttml_style_set_get_attr (tss, "writingMode"))) {
    if (g_str_has_prefix (attr, "rl"))
      style_set->writing_mode = GST_SUBTITLE_WRITING_MODE_RLTB;
    else if ((g_strcmp0 (attr, "tbrl") == 0)
        || (g_strcmp0 (attr, "tb") == 0))
      style_set->writing_mode = GST_SUBTITLE_WRITING_MODE_TBRL;
    else if (g_strcmp0 (attr, "tblr") == 0)
      style_set->writing_mode = GST_SUBTITLE_WRITING_MODE_TBLR;
    else
      style_set->writing_mode = GST_SUBTITLE_WRITING_MODE_LRTB;
  }

  if ((attr = ttml_style_set_get_attr (tss, "showBackground"))) {
    if (g_strcmp0 (attr, "whenActive") == 0)
      style_set->show_background = GST_SUBTITLE_BACKGROUND_MODE_WHEN_ACTIVE;
    else
      style_set->show_background = GST_SUBTITLE_BACKGROUND_MODE_ALWAYS;
  }

  if ((attr = ttml_style_set_get_attr (tss, "overflow"))) {
    if (g_strcmp0 (attr, "visible") == 0)
      style_set->overflow = GST_SUBTITLE_OVERFLOW_MODE_VISIBLE;
    else
      style_set->overflow = GST_SUBTITLE_OVERFLOW_MODE_HIDDEN;
  }
}


static TtmlStyleSet *
ttml_style_set_copy (TtmlStyleSet * style_set)
{
  GHashTableIter iter;
  gpointer attr_name, attr_value;
  TtmlStyleSet *ret = ttml_style_set_new ();

  g_hash_table_iter_init (&iter, style_set->table);
  while (g_hash_table_iter_next (&iter, &attr_name, &attr_value)) {
    ttml_style_set_add_attr (ret, (const gchar *) attr_name,
        (const gchar *) attr_value);
  }

  return ret;
}


/* set2 overrides set1. Unlike style inheritance, merging will result in all
 * values from set1 being merged into set2. */
static TtmlStyleSet *
ttml_style_set_merge (TtmlStyleSet * set1, TtmlStyleSet * set2)
{
  TtmlStyleSet *ret = NULL;

  if (set1) {
    ret = ttml_style_set_copy (set1);

    if (set2) {
      GHashTableIter iter;
      gpointer attr_name, attr_value;

      g_hash_table_iter_init (&iter, set2->table);
      while (g_hash_table_iter_next (&iter, &attr_name, &attr_value)) {
        ttml_style_set_add_attr (ret, (const gchar *) attr_name,
            (const gchar *) attr_value);
      }
    }
  } else if (set2) {
    ret = ttml_style_set_copy (set2);
  }

  return ret;
}


static gchar *
ttml_get_relative_font_size (const gchar * parent_size,
    const gchar * child_size)
{
  guint psize = (guint) g_ascii_strtoull (parent_size, NULL, 10U);
  guint csize = (guint) g_ascii_strtoull (child_size, NULL, 10U);
  csize = (csize * psize) / 100U;
  return g_strdup_printf ("%u%%", csize);
}


static TtmlStyleSet *
ttml_style_set_inherit (TtmlStyleSet * parent, TtmlStyleSet * child)
{
  TtmlStyleSet *ret = NULL;
  GHashTableIter iter;
  gpointer attr_name, attr_value;

  if (child) {
    ret = ttml_style_set_copy (child);
  } else {
    ret = ttml_style_set_new ();
  }

  if (!parent)
    return ret;

  g_hash_table_iter_init (&iter, parent->table);
  while (g_hash_table_iter_next (&iter, &attr_name, &attr_value)) {
    /* In TTML, if an element which has a defined fontSize is the child of an
     * element that also has a defined fontSize, the child's font size is
     * relative to that of its parent. If its parent doesn't have a defined
     * fontSize, then the child's fontSize is relative to the document's cell
     * size. Therefore, if the former is true, we calculate the value of
     * fontSize based on the parent's fontSize; otherwise, we simply keep
     * the value defined in the child's style set. */
    if (g_strcmp0 ((const gchar *) attr_name, "fontSize") == 0
        && ttml_style_set_contains_attr (ret, "fontSize")) {
      const gchar *original_child_font_size =
          ttml_style_set_get_attr (ret, "fontSize");
      gchar *scaled_child_font_size =
          ttml_get_relative_font_size ((const gchar *) attr_value,
          original_child_font_size);
      GST_CAT_LOG (ttmlparse_debug, "Calculated font size: %s",
          scaled_child_font_size);
      ttml_style_set_add_attr (ret, (const gchar *) attr_name,
          scaled_child_font_size);
      g_free (scaled_child_font_size);
    }

    /* Not all styling attributes are inherited in TTML. */
    if (g_strcmp0 ((const gchar *) attr_name, "backgroundColor") != 0
        && g_strcmp0 ((const gchar *) attr_name, "origin") != 0
        && g_strcmp0 ((const gchar *) attr_name, "extent") != 0
        && g_strcmp0 ((const gchar *) attr_name, "displayAlign") != 0
        && g_strcmp0 ((const gchar *) attr_name, "overflow") != 0
        && g_strcmp0 ((const gchar *) attr_name, "padding") != 0
        && g_strcmp0 ((const gchar *) attr_name, "writingMode") != 0
        && g_strcmp0 ((const gchar *) attr_name, "showBackground") != 0
        && g_strcmp0 ((const gchar *) attr_name, "unicodeBidi") != 0) {
      if (!ttml_style_set_contains_attr (ret, (const gchar *) attr_name)) {
        ttml_style_set_add_attr (ret, (const gchar *) attr_name,
            (const gchar *) attr_value);
      }
    }
  }

  return ret;
}


/*
 * Returns TRUE iff @element1 and @element2 reference the same set of styles.
 * If neither @element1 nor @element2 reference any styles, they are considered
 * to have matching styling and, hence, TRUE is returned.
 */
static gboolean
ttml_element_styles_match (TtmlElement * element1, TtmlElement * element2)
{
  const gchar *const *strv;
  gint i;

  if (!element1 || !element2 || (!element1->styles && element2->styles) ||
      (element1->styles && !element2->styles))
    return FALSE;

  if (!element1->styles && !element2->styles)
    return TRUE;

  strv = (const gchar * const *) element2->styles;

  if (g_strv_length (element1->styles) != g_strv_length (element2->styles))
    return FALSE;

  for (i = 0; i < g_strv_length (element1->styles); ++i) {
    if (!g_strv_contains (strv, element1->styles[i]))
      return FALSE;
  }

  return TRUE;
}


static gchar *
ttml_get_element_type_string (TtmlElement * element)
{
  switch (element->type) {
    case TTML_ELEMENT_TYPE_STYLE:
      return g_strdup ("<style>");
      break;
    case TTML_ELEMENT_TYPE_REGION:
      return g_strdup ("<region>");
      break;
    case TTML_ELEMENT_TYPE_BODY:
      return g_strdup ("<body>");
      break;
    case TTML_ELEMENT_TYPE_DIV:
      return g_strdup ("<div>");
      break;
    case TTML_ELEMENT_TYPE_P:
      return g_strdup ("<p>");
      break;
    case TTML_ELEMENT_TYPE_SPAN:
      return g_strdup ("<span>");
      break;
    case TTML_ELEMENT_TYPE_ANON_SPAN:
      return g_strdup ("<anon-span>");
      break;
    case TTML_ELEMENT_TYPE_BR:
      return g_strdup ("<br>");
      break;
    default:
      return g_strdup ("Unknown");
      break;
  }
}


/* Merge styles referenced by an element. */
static gboolean
ttml_resolve_styles (GNode * node, gpointer data)
{
  TtmlStyleSet *tmp = NULL;
  TtmlElement *element, *style;
  GHashTable *styles_table;
  gchar *type_string;
  guint i;

  styles_table = (GHashTable *) data;
  element = node->data;

  type_string = ttml_get_element_type_string (element);
  GST_CAT_LOG (ttmlparse_debug, "Element type: %s", type_string);
  g_free (type_string);

  if (!element->styles)
    return FALSE;

  for (i = 0; i < g_strv_length (element->styles); ++i) {
    tmp = element->style_set;
    style = g_hash_table_lookup (styles_table, element->styles[i]);
    if (style) {
      GST_CAT_LOG (ttmlparse_debug, "Merging style %s...", element->styles[i]);
      element->style_set = ttml_style_set_merge (element->style_set,
          style->style_set);
      ttml_style_set_delete (tmp);
    } else {
      GST_CAT_WARNING (ttmlparse_debug,
          "Element references an unknown style (%s)", element->styles[i]);
    }
  }

  GST_CAT_LOG (ttmlparse_debug, "Style set after merging:");
  ttml_style_set_print (element->style_set);

  return FALSE;
}


static void
ttml_resolve_referenced_styles (GList * trees, GHashTable * styles_table)
{
  GList *tree;

  for (tree = g_list_first (trees); tree; tree = tree->next) {
    GNode *root = (GNode *) tree->data;
    g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, ttml_resolve_styles,
        styles_table);
  }
}


/* Inherit styling attributes from parent. */
static gboolean
ttml_inherit_styles (GNode * node, gpointer data)
{
  TtmlStyleSet *tmp = NULL;
  TtmlElement *element, *parent;
  gchar *type_string;

  element = node->data;

  type_string = ttml_get_element_type_string (element);
  GST_CAT_LOG (ttmlparse_debug, "Element type: %s", type_string);
  g_free (type_string);

  if (node->parent) {
    parent = node->parent->data;
    if (parent->style_set) {
      tmp = element->style_set;
      if (element->type == TTML_ELEMENT_TYPE_ANON_SPAN ||
          element->type == TTML_ELEMENT_TYPE_BR) {
        element->style_set = ttml_style_set_merge (parent->style_set,
            element->style_set);
        element->styles = g_strdupv (parent->styles);
      } else {
        element->style_set = ttml_style_set_inherit (parent->style_set,
            element->style_set);
      }
      ttml_style_set_delete (tmp);
    }
  }

  GST_CAT_LOG (ttmlparse_debug, "Style set after inheriting:");
  ttml_style_set_print (element->style_set);

  return FALSE;
}


static void
ttml_inherit_element_styles (GList * trees)
{
  GList *tree;

  for (tree = g_list_first (trees); tree; tree = tree->next) {
    GNode *root = (GNode *) tree->data;
    g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, ttml_inherit_styles,
        NULL);
  }
}


/* If whitespace_mode isn't explicitly set for this element, inherit from its
 * parent. If this element is the root of the tree, set whitespace_mode to
 * that of the overall document. */
static gboolean
ttml_inherit_element_whitespace_mode (GNode * node, gpointer data)
{
  TtmlWhitespaceMode *doc_mode = (TtmlWhitespaceMode *) data;
  TtmlElement *element = node->data;
  TtmlElement *parent;

  if (element->whitespace_mode != TTML_WHITESPACE_MODE_NONE)
    return FALSE;

  if (G_NODE_IS_ROOT (node)) {
    element->whitespace_mode = *doc_mode;
    return FALSE;
  }

  parent = node->parent->data;
  element->whitespace_mode = parent->whitespace_mode;
  return FALSE;
}


static void
ttml_inherit_whitespace_mode (GNode * tree, TtmlWhitespaceMode doc_mode)
{
  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
      ttml_inherit_element_whitespace_mode, &doc_mode);
}


static gboolean
ttml_free_node_data (GNode * node, gpointer data)
{
  TtmlElement *element = node->data;
  ttml_delete_element (element);
  return FALSE;
}


static void
ttml_delete_tree (GNode * tree)
{
  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1, ttml_free_node_data,
      NULL);
  g_node_destroy (tree);
}


typedef struct
{
  GstClockTime begin;
  GstClockTime end;
} ClipWindow;

static gboolean
ttml_clip_element_period (GNode * node, gpointer data)
{
  TtmlElement *element = node->data;
  ClipWindow *window = data;

  if (!GST_CLOCK_TIME_IS_VALID (element->begin)) {
    return FALSE;
  }

  if (element->begin > window->end || element->end < window->begin) {
    ttml_delete_tree (node);
    node = NULL;
    return FALSE;
  }

  element->begin = MAX (element->begin, window->begin);
  element->end = MIN (element->end, window->end);
  return FALSE;
}


static void
ttml_apply_time_window (GNode * tree, GstClockTime window_begin,
    GstClockTime window_end)
{
  ClipWindow window;
  window.begin = window_begin;
  window.end = window_end;

  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
      ttml_clip_element_period, &window);
}


static gboolean
ttml_resolve_element_timings (GNode * node, gpointer data)
{
  TtmlElement *element, *leaf;

  leaf = element = node->data;

  if (GST_CLOCK_TIME_IS_VALID (leaf->begin)
      && GST_CLOCK_TIME_IS_VALID (leaf->end)) {
    GST_CAT_LOG (ttmlparse_debug, "Leaf node already has timing.");
    return FALSE;
  }

  /* Inherit timings from ancestor. */
  while (node->parent && !GST_CLOCK_TIME_IS_VALID (element->begin)) {
    node = node->parent;
    element = node->data;
  }

  if (!GST_CLOCK_TIME_IS_VALID (element->begin)) {
    GST_CAT_WARNING (ttmlparse_debug,
        "No timing found for element; setting to Root Temporal Extent.");
    leaf->begin = 0;
    leaf->end = NSECONDS_IN_DAY;
  } else {
    leaf->begin = element->begin;
    leaf->end = element->end;
    GST_CAT_LOG (ttmlparse_debug, "Leaf begin: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (leaf->begin));
    GST_CAT_LOG (ttmlparse_debug, "Leaf end: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (leaf->end));
  }

  return FALSE;
}


static void
ttml_resolve_timings (GNode * tree)
{
  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_LEAVES, -1,
      ttml_resolve_element_timings, NULL);
}


static gboolean
ttml_resolve_leaf_region (GNode * node, gpointer data)
{
  TtmlElement *element, *leaf;
  leaf = element = node->data;

  while (node->parent && !element->region) {
    node = node->parent;
    element = node->data;
  }

  if (element->region) {
    leaf->region = g_strdup (element->region);
    GST_CAT_LOG (ttmlparse_debug, "Leaf region: %s", leaf->region);
  } else {
    GST_CAT_WARNING (ttmlparse_debug, "No region found above leaf element.");
  }

  return FALSE;
}


static void
ttml_resolve_regions (GNode * tree)
{
  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_LEAVES, -1,
      ttml_resolve_leaf_region, NULL);
}


typedef struct
{
  GstClockTime start_time;
  GstClockTime next_transition_time;
} TrState;


static gboolean
ttml_update_transition_time (GNode * node, gpointer data)
{
  TtmlElement *element = node->data;
  TrState *state = (TrState *) data;

  if ((element->begin < state->next_transition_time)
      && (!GST_CLOCK_TIME_IS_VALID (state->start_time)
          || (element->begin > state->start_time))) {
    state->next_transition_time = element->begin;
    GST_CAT_LOG (ttmlparse_debug,
        "Updating next transition time to element begin time (%"
        GST_TIME_FORMAT ")", GST_TIME_ARGS (state->next_transition_time));
    return FALSE;
  }

  if ((element->end < state->next_transition_time)
      && (element->end > state->start_time)) {
    state->next_transition_time = element->end;
    GST_CAT_LOG (ttmlparse_debug,
        "Updating next transition time to element end time (%"
        GST_TIME_FORMAT ")", GST_TIME_ARGS (state->next_transition_time));
  }

  return FALSE;
}


/* Return details about the next transition after @time. */
static GstClockTime
ttml_find_next_transition (GList * trees, GstClockTime time)
{
  TrState state;
  state.start_time = time;
  state.next_transition_time = GST_CLOCK_TIME_NONE;

  for (trees = g_list_first (trees); trees; trees = trees->next) {
    GNode *tree = (GNode *) trees->data;
    g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
        ttml_update_transition_time, &state);
  }

  GST_CAT_LOG (ttmlparse_debug, "Next transition is at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (state.next_transition_time));

  return state.next_transition_time;
}


/* Remove nodes from tree that are not visible at @time. */
static GNode *
ttml_remove_nodes_by_time (GNode * node, GstClockTime time)
{
  GNode *child, *next_child;
  TtmlElement *element;
  element = node->data;

  child = node->children;
  next_child = child ? child->next : NULL;
  while (child) {
    ttml_remove_nodes_by_time (child, time);
    child = next_child;
    next_child = child ? child->next : NULL;
  }

  if (!node->children && ((element->begin > time) || (element->end <= time))) {
    ttml_delete_tree (node);
    node = NULL;
  }

  return node;
}


/* Return a list of trees containing the elements and their ancestors that are
 * visible at @time. */
static GList *
ttml_get_active_trees (GList * element_trees, GstClockTime time)
{
  GList *tree;
  GList *ret = NULL;

  for (tree = g_list_first (element_trees); tree; tree = tree->next) {
    GNode *root = g_node_copy_deep ((GNode *) tree->data,
        ttml_copy_tree_element, NULL);
    GST_CAT_LOG (ttmlparse_debug, "There are %u nodes in tree.",
        g_node_n_nodes (root, G_TRAVERSE_ALL));
    root = ttml_remove_nodes_by_time (root, time);
    if (root) {
      GST_CAT_LOG (ttmlparse_debug,
          "After filtering there are %u nodes in tree.", g_node_n_nodes (root,
              G_TRAVERSE_ALL));

      ret = g_list_append (ret, root);
    } else {
      GST_CAT_LOG (ttmlparse_debug,
          "All elements have been filtered from tree.");
    }
  }

  GST_CAT_DEBUG (ttmlparse_debug, "There are %u trees in returned list.",
      g_list_length (ret));
  return ret;
}


static GList *
ttml_create_scenes (GList * region_trees)
{
  TtmlScene *cur_scene = NULL;
  GList *output_scenes = NULL;
  GList *active_trees = NULL;
  GstClockTime timestamp = GST_CLOCK_TIME_NONE;

  while ((timestamp = ttml_find_next_transition (region_trees, timestamp))
      != GST_CLOCK_TIME_NONE) {
    GST_CAT_LOG (ttmlparse_debug,
        "Next transition found at time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (timestamp));
    if (cur_scene) {
      cur_scene->end = timestamp;
      output_scenes = g_list_append (output_scenes, cur_scene);
    }

    active_trees = ttml_get_active_trees (region_trees, timestamp);
    GST_CAT_LOG (ttmlparse_debug, "There will be %u active regions after "
        "transition", g_list_length (active_trees));

    if (active_trees) {
      cur_scene = g_slice_new0 (TtmlScene);
      cur_scene->begin = timestamp;
      cur_scene->trees = active_trees;
    } else {
      cur_scene = NULL;
    }
  }

  return output_scenes;
}


/* Handle element whitespace in accordance with section 7.2.3 of the TTML
 * specification. Specifically, this function implements the
 * white-space-collapse="true" and linefeed-treatment="treat-as-space"
 * behaviours. Note that stripping of whitespace at the start and end of line
 * areas (suppress-at-line-break="auto" and
 * white-space-treatment="ignore-if-surrounding-linefeed" behaviours) can only
 * be done by the renderer once the text from multiple elements has been laid
 * out in line areas. */
static gboolean
ttml_handle_element_whitespace (GNode * node, gpointer data)
{
  TtmlElement *element = node->data;
  guint space_count = 0;
  guint textlen;
  gchar *c;

  if (!element->text || (element->type == TTML_ELEMENT_TYPE_BR) ||
      (element->whitespace_mode == TTML_WHITESPACE_MODE_PRESERVE)) {
    return FALSE;
  }

  textlen = strlen (element->text);
  for (c = element->text; TRUE; c = g_utf8_next_char (c)) {

    gchar buf[6] = { 0 };
    gunichar u = g_utf8_get_char (c);
    gint nbytes = g_unichar_to_utf8 (u, buf);

    /* Repace each newline or tab with a space. */
    if (nbytes == 1 && (buf[0] == TTML_CHAR_LF || buf[0] == TTML_CHAR_TAB)) {
      *c = ' ';
      buf[0] = TTML_CHAR_SPACE;
    }

    /* Collapse runs of whitespace. */
    if (nbytes == 1 && (buf[0] == TTML_CHAR_SPACE || buf[0] == TTML_CHAR_CR)) {
      ++space_count;
    } else {
      if (space_count > 1) {
        gchar *new_head = c - space_count + 1;
        g_strlcpy (new_head, c, textlen);
        c = new_head;
      }
      space_count = 0;
      if (nbytes == 1 && buf[0] == TTML_CHAR_NULL)
        break;
    }
  }

  return FALSE;
}


static void
ttml_handle_whitespace (GNode * tree)
{
  g_node_traverse (tree, G_PRE_ORDER, G_TRAVERSE_LEAVES, -1,
      ttml_handle_element_whitespace, NULL);
}


static GNode *
ttml_filter_content_nodes (GNode * node)
{
  GNode *child, *next_child;
  TtmlElement *element = node->data;
  TtmlElement *parent = node->parent ? node->parent->data : NULL;

  child = node->children;
  next_child = child ? child->next : NULL;
  while (child) {
    ttml_filter_content_nodes (child);
    child = next_child;
    next_child = child ? child->next : NULL;
  }

  /* Only text content in <p>s and <span>s is significant. */
  if (element->type == TTML_ELEMENT_TYPE_ANON_SPAN
      && parent->type != TTML_ELEMENT_TYPE_P
      && parent->type != TTML_ELEMENT_TYPE_SPAN) {
    ttml_delete_element (element);
    g_node_destroy (node);
    node = NULL;
  }

  return node;
}


/* Store in @table child elements of @node with name @element_name. A child
 * element with the same ID as an existing entry in @table will overwrite the
 * existing entry. */
static void
ttml_store_unique_children (xmlNodePtr node, const gchar * element_name,
    GHashTable * table)
{
  xmlNodePtr ptr;

  for (ptr = node->children; ptr; ptr = ptr->next) {
    if (xmlStrcmp (ptr->name, (const xmlChar *) element_name) == 0) {
      TtmlElement *element = ttml_parse_element (ptr);
      gboolean new_key;

      if (element) {
        new_key = g_hash_table_insert (table, g_strdup (element->id), element);
        if (!new_key)
          GST_CAT_WARNING (ttmlparse_debug,
              "Document contains two %s elements with the same ID (\"%s\").",
              element_name, element->id);
      }
    }
  }
}


/* Parse style and region elements from @head and store in their respective
 * hash tables for future reference. */
static void
ttml_parse_head (xmlNodePtr head, GHashTable * styles_table,
    GHashTable * regions_table)
{
  xmlNodePtr node;

  for (node = head->children; node; node = node->next) {
    if (xmlStrcmp (node->name, (const xmlChar *) "styling") == 0)
      ttml_store_unique_children (node, "style", styles_table);
    if (xmlStrcmp (node->name, (const xmlChar *) "layout") == 0)
      ttml_store_unique_children (node, "region", regions_table);
  }
}


/* Remove nodes that do not belong to @region, or are not an ancestor of a node
 * belonging to @region. */
static GNode *
ttml_remove_nodes_by_region (GNode * node, const gchar * region)
{
  GNode *child, *next_child;
  TtmlElement *element;
  element = node->data;

  child = node->children;
  next_child = child ? child->next : NULL;
  while (child) {
    ttml_remove_nodes_by_region (child, region);
    child = next_child;
    next_child = child ? child->next : NULL;
  }

  if ((element->type == TTML_ELEMENT_TYPE_ANON_SPAN
          || element->type != TTML_ELEMENT_TYPE_BR)
      && element->region && (g_strcmp0 (element->region, region) != 0)) {
    ttml_delete_element (element);
    g_node_destroy (node);
    return NULL;
  }
  if (element->type != TTML_ELEMENT_TYPE_ANON_SPAN
      && element->type != TTML_ELEMENT_TYPE_BR && !node->children) {
    ttml_delete_element (element);
    g_node_destroy (node);
    return NULL;
  }

  return node;
}


static TtmlElement *
ttml_copy_element (const TtmlElement * element)
{
  TtmlElement *ret = g_slice_new0 (TtmlElement);

  ret->type = element->type;
  if (element->id)
    ret->id = g_strdup (element->id);
  ret->whitespace_mode = element->whitespace_mode;
  if (element->styles)
    ret->styles = g_strdupv (element->styles);
  if (element->region)
    ret->region = g_strdup (element->region);
  ret->begin = element->begin;
  ret->end = element->end;
  if (element->style_set)
    ret->style_set = ttml_style_set_copy (element->style_set);
  if (element->text)
    ret->text = g_strdup (element->text);

  return ret;
}


static gpointer
ttml_copy_tree_element (gconstpointer src, gpointer data)
{
  return ttml_copy_element ((TtmlElement *) src);
}


/* Split the body tree into a set of trees, each containing only the elements
 * belonging to a single region. Returns a list of trees, one per region, each
 * with the corresponding region element at its root. */
static GList *
ttml_split_body_by_region (GNode * body, GHashTable * regions)
{
  GHashTableIter iter;
  gpointer key, value;
  GList *ret = NULL;

  g_hash_table_iter_init (&iter, regions);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    gchar *region_name = (gchar *) key;
    TtmlElement *region = (TtmlElement *) value;
    GNode *region_node = g_node_new (ttml_copy_element (region));
    GNode *body_copy = g_node_copy_deep (body, ttml_copy_tree_element, NULL);

    GST_CAT_DEBUG (ttmlparse_debug, "Creating tree for region %s", region_name);
    GST_CAT_LOG (ttmlparse_debug, "Copy of body has %u nodes.",
        g_node_n_nodes (body_copy, G_TRAVERSE_ALL));

    body_copy = ttml_remove_nodes_by_region (body_copy, region_name);
    if (body_copy) {
      GST_CAT_LOG (ttmlparse_debug, "Copy of body now has %u nodes.",
          g_node_n_nodes (body_copy, G_TRAVERSE_ALL));

      /* Reparent tree to region node. */
      g_node_prepend (region_node, body_copy);
    }
    GST_CAT_LOG (ttmlparse_debug, "Final tree has %u nodes.",
        g_node_n_nodes (region_node, G_TRAVERSE_ALL));
    ret = g_list_append (ret, region_node);
  }

  GST_CAT_DEBUG (ttmlparse_debug, "Returning %u trees.", g_list_length (ret));
  return ret;
}


static gint
ttml_add_text_to_buffer (GstBuffer * buf, const gchar * text)
{
  GstMemory *mem;
  GstMapInfo map;
  guint ret;

  if (gst_buffer_n_memory (buf) == gst_buffer_get_max_memory ())
    return -1;

  mem = gst_allocator_alloc (NULL, strlen (text) + 1, NULL);
  if (!gst_memory_map (mem, &map, GST_MAP_WRITE))
    GST_CAT_ERROR (ttmlparse_debug, "Failed to map memory.");

  g_strlcpy ((gchar *) map.data, text, map.size);
  GST_CAT_DEBUG (ttmlparse_debug, "Inserted following text into buffer: \"%s\"",
      (gchar *) map.data);
  gst_memory_unmap (mem, &map);

  ret = gst_buffer_n_memory (buf);
  gst_buffer_insert_memory (buf, -1, mem);
  return ret;
}


/* Create a GstSubtitleElement from @element, add it to @block, and insert its
 * associated text in @buf. */
static gboolean
ttml_add_element (GstSubtitleBlock * block, TtmlElement * element,
    GstBuffer * buf, guint cellres_x, guint cellres_y)
{
  GstSubtitleStyleSet *element_style = NULL;
  guint buffer_index;
  GstSubtitleElement *sub_element = NULL;

  buffer_index = ttml_add_text_to_buffer (buf, element->text);
  if (buffer_index == -1) {
    GST_CAT_WARNING (ttmlparse_debug,
        "Reached maximum element count for buffer - discarding element.");
    return FALSE;
  }

  GST_CAT_DEBUG (ttmlparse_debug, "Inserted text at index %u in GstBuffer.",
      buffer_index);

  element_style = gst_subtitle_style_set_new ();
  ttml_update_style_set (element_style, element->style_set,
      cellres_x, cellres_y);
  sub_element = gst_subtitle_element_new (element_style, buffer_index,
      (element->whitespace_mode != TTML_WHITESPACE_MODE_PRESERVE));

  gst_subtitle_block_add_element (block, sub_element);
  GST_CAT_DEBUG (ttmlparse_debug,
      "Added element to block; there are now %u elements in the block.",
      gst_subtitle_block_get_element_count (block));
  return TRUE;
}


/* Return TRUE if @color is totally transparent. */
static gboolean
ttml_color_is_transparent (const GstSubtitleColor * color)
{
  if (!color)
    return FALSE;
  else
    return (color->a == 0);
}


/* Blend @color2 over @color1 and return the resulting color. This is currently
 * a dummy implementation that simply returns color2 as long as it's
 * not fully transparent. */
/* TODO: Implement actual blending of colors. */
static GstSubtitleColor
ttml_blend_colors (GstSubtitleColor color1, GstSubtitleColor color2)
{
  if (ttml_color_is_transparent (&color2))
    return color1;
  else
    return color2;
}


static void
ttml_warn_of_mispositioned_element (TtmlElement * element)
{
  gchar *type = ttml_get_element_type_string (element);
  GST_CAT_WARNING (ttmlparse_debug, "Ignoring illegally positioned %s element.",
      type);
  g_free (type);
}


/* Create the subtitle region and its child blocks and elements for @tree,
 * inserting element text in @buf. Ownership of created region is transferred
 * to caller. */
static GstSubtitleRegion *
ttml_create_subtitle_region (GNode * tree, GstBuffer * buf, guint cellres_x,
    guint cellres_y)
{
  GstSubtitleRegion *region = NULL;
  GstSubtitleStyleSet *region_style;
  GstSubtitleColor block_color;
  TtmlElement *element;
  GNode *node;

  element = tree->data;         /* Region element */
  region_style = gst_subtitle_style_set_new ();
  ttml_update_style_set (region_style, element->style_set, cellres_x,
      cellres_y);
  region = gst_subtitle_region_new (region_style);

  node = tree->children;
  if (!node)
    return region;

  element = node->data;         /* Body element */
  block_color =
      ttml_parse_colorstring (ttml_style_set_get_attr (element->style_set,
          "backgroundColor"));

  for (node = node->children; node; node = node->next) {
    GNode *p_node;
    GstSubtitleColor div_color;

    element = node->data;
    if (element->type != TTML_ELEMENT_TYPE_DIV) {
      ttml_warn_of_mispositioned_element (element);
      continue;
    }
    div_color =
        ttml_parse_colorstring (ttml_style_set_get_attr (element->style_set,
            "backgroundColor"));
    block_color = ttml_blend_colors (block_color, div_color);

    for (p_node = node->children; p_node; p_node = p_node->next) {
      GstSubtitleBlock *block = NULL;
      GstSubtitleStyleSet *block_style;
      GNode *content_node;
      GstSubtitleColor p_color;

      element = p_node->data;
      if (element->type != TTML_ELEMENT_TYPE_P) {
        ttml_warn_of_mispositioned_element (element);
        continue;
      }
      p_color =
          ttml_parse_colorstring (ttml_style_set_get_attr (element->style_set,
              "backgroundColor"));
      block_color = ttml_blend_colors (block_color, p_color);

      block_style = gst_subtitle_style_set_new ();
      ttml_update_style_set (block_style, element->style_set, cellres_x,
          cellres_y);
      block_style->background_color = block_color;
      block = gst_subtitle_block_new (block_style);

      for (content_node = p_node->children; content_node;
          content_node = content_node->next) {
        GNode *anon_node;
        element = content_node->data;

        if (element->type == TTML_ELEMENT_TYPE_BR
            || element->type == TTML_ELEMENT_TYPE_ANON_SPAN) {
          if (!ttml_add_element (block, element, buf, cellres_x, cellres_y))
            GST_CAT_WARNING (ttmlparse_debug,
                "Failed to add element to buffer.");
        } else if (element->type == TTML_ELEMENT_TYPE_SPAN) {
          /* Loop through anon-span children of this span. */
          for (anon_node = content_node->children; anon_node;
              anon_node = anon_node->next) {
            element = anon_node->data;

            if (element->type == TTML_ELEMENT_TYPE_BR
                || element->type == TTML_ELEMENT_TYPE_ANON_SPAN) {
              if (!ttml_add_element (block, element, buf, cellres_x, cellres_y))
                GST_CAT_WARNING (ttmlparse_debug,
                    "Failed to add element to buffer.");
            } else {
              ttml_warn_of_mispositioned_element (element);
            }
          }
        } else {
          ttml_warn_of_mispositioned_element (element);
        }
      }

      if (gst_subtitle_block_get_element_count (block) > 0) {
        gst_subtitle_region_add_block (region, block);
        GST_CAT_DEBUG (ttmlparse_debug,
            "Added block to region; there are now %u blocks in the region.",
            gst_subtitle_region_get_block_count (region));
      } else {
        gst_subtitle_block_unref (block);
      }
    }
  }

  return region;
}


/* For each scene, create data objects to describe the layout and styling of
 * that scene and attach it as metadata to the GstBuffer that will be used to
 * carry that scene's text. */
static void
ttml_attach_scene_metadata (GList * scenes, guint cellres_x, guint cellres_y)
{
  GList *scene_entry;

  for (scene_entry = g_list_first (scenes); scene_entry;
      scene_entry = scene_entry->next) {
    TtmlScene *scene = scene_entry->data;
    GList *region_tree;
    GPtrArray *regions = g_ptr_array_new_with_free_func (
        (GDestroyNotify) gst_subtitle_region_unref);

    scene->buf = gst_buffer_new ();
    GST_BUFFER_PTS (scene->buf) = scene->begin;
    GST_BUFFER_DURATION (scene->buf) = (scene->end - scene->begin);

    for (region_tree = g_list_first (scene->trees); region_tree;
        region_tree = region_tree->next) {
      GNode *tree = (GNode *) region_tree->data;
      GstSubtitleRegion *region;

      region = ttml_create_subtitle_region (tree, scene->buf, cellres_x,
          cellres_y);
      if (region)
        g_ptr_array_add (regions, region);
    }

    gst_buffer_add_subtitle_meta (scene->buf, regions);
  }
}


static GList *
create_buffer_list (GList * scenes)
{
  GList *ret = NULL;

  while (scenes) {
    TtmlScene *scene = scenes->data;
    ret = g_list_prepend (ret, gst_buffer_ref (scene->buf));
    scenes = scenes->next;
  }
  return g_list_reverse (ret);
}


static void
ttml_delete_scene (TtmlScene * scene)
{
  if (scene->trees)
    g_list_free_full (scene->trees, (GDestroyNotify) ttml_delete_tree);
  if (scene->buf)
    gst_buffer_unref (scene->buf);
  g_slice_free (TtmlScene, scene);
}


static void
ttml_assign_region_times (GList * region_trees, GstClockTime doc_begin,
    GstClockTime doc_duration)
{
  GList *tree;

  for (tree = g_list_first (region_trees); tree; tree = tree->next) {
    GNode *region_node = (GNode *) tree->data;
    TtmlElement *region = (TtmlElement *) region_node->data;
    const gchar *show_background_value =
        ttml_style_set_get_attr (region->style_set, "showBackground");
    gboolean always_visible =
        (g_strcmp0 (show_background_value, "always") == 0);

    GstSubtitleColor region_color = { 0, 0, 0, 0 };
    if (ttml_style_set_contains_attr (region->style_set, "backgroundColor"))
      region_color =
          ttml_parse_colorstring (ttml_style_set_get_attr (region->style_set,
              "backgroundColor"));

    if (always_visible && !ttml_color_is_transparent (&region_color)) {
      GST_CAT_DEBUG (ttmlparse_debug, "Assigning times to region.");
      /* If the input XML document was not encapsulated in a container that
       * provides timing information for the document as a whole (i.e., its
       * PTS and duration) and the region background should be always visible,
       * set region start time to 0 and end time to 24 hours. This ensures that
       * regions with showBackground="always" are visible for the entirety of
       * any real-world stream. */
      region->begin = (doc_begin != GST_CLOCK_TIME_NONE) ? doc_begin : 0;
      region->end = (doc_duration != GST_CLOCK_TIME_NONE) ?
          region->begin + doc_duration : NSECONDS_IN_DAY;
    }
  }
}


/*
 * Promotes @node to the position of its parent, setting the prev, next and
 * parent pointers of @node to that of its original parent. The replaced parent
 * is freed. Should be called only on nodes that are the sole child of their
 * parent, otherwise sibling nodes may be leaked.
 */
static void
ttml_promote_node (GNode * node)
{
  GNode *parent_node = node->parent;
  TtmlElement *parent_element;

  if (!parent_node)
    return;
  parent_element = (TtmlElement *) parent_node->data;

  node->prev = parent_node->prev;
  if (!node->prev)
    parent_node->parent->children = node;
  else
    node->prev->next = node;
  node->next = parent_node->next;
  if (node->next)
    node->next->prev = node;
  node->parent = parent_node->parent;

  parent_node->prev = parent_node->next = NULL;
  parent_node->parent = parent_node->children = NULL;
  g_node_destroy (parent_node);
  ttml_delete_element (parent_element);
}


/*
 * Returns TRUE if @element is of a type that can be joined with another
 * joinable element.
 */
static gboolean
ttml_element_is_joinable (TtmlElement * element)
{
  return element->type == TTML_ELEMENT_TYPE_ANON_SPAN ||
      element->type == TTML_ELEMENT_TYPE_BR;
}


/* Joins adjacent inline element in @tree that have the same styling. */
static void
ttml_join_region_tree_inline_elements (GNode * tree)
{
  GNode *n1, *n2;

  for (n1 = tree; n1; n1 = n1->next) {
    if (n1->children) {
      TtmlElement *element = (TtmlElement *) n1->data;
      ttml_join_region_tree_inline_elements (n1->children);
      if (element->type == TTML_ELEMENT_TYPE_SPAN &&
          g_node_n_children (n1) == 1) {
        GNode *child = n1->children;
        if (n1 == tree)
          tree = child;
        ttml_promote_node (child);
        n1 = child;
      }
    }
  }

  n1 = tree;
  n2 = tree->next;

  while (n1 && n2) {
    TtmlElement *e1 = (TtmlElement *) n1->data;
    TtmlElement *e2 = (TtmlElement *) n2->data;

    if (ttml_element_is_joinable (e1) &&
        ttml_element_is_joinable (e2) && ttml_element_styles_match (e1, e2)) {
      gchar *tmp = e1->text;
      GST_CAT_LOG (ttmlparse_debug,
          "Joining adjacent element text \"%s\" & \"%s\"", e1->text, e2->text);
      e1->text = g_strconcat (e1->text, e2->text, NULL);
      e1->type = TTML_ELEMENT_TYPE_ANON_SPAN;
      g_free (tmp);

      ttml_delete_element (e2);
      g_node_destroy (n2);
      n2 = n1->next;
    } else {
      n1 = n2;
      n2 = n2 ? n2->next : NULL;
    }
  }
}


static void
ttml_join_inline_elements (GList * scenes)
{
  GList *scene_entry;

  for (scene_entry = g_list_first (scenes); scene_entry;
      scene_entry = scene_entry->next) {
    TtmlScene *scene = scene_entry->data;
    GList *region_tree;

    for (region_tree = g_list_first (scene->trees); region_tree;
        region_tree = region_tree->next) {
      GNode *tree = (GNode *) region_tree->data;
      ttml_join_region_tree_inline_elements (tree);
    }
  }
}


static xmlNodePtr
ttml_find_child (xmlNodePtr parent, const gchar * name)
{
  xmlNodePtr child = parent->children;
  while (child && xmlStrcmp (child->name, (const xmlChar *) name) != 0)
    child = child->next;
  return child;
}


GList *
ttml_parse (const gchar * input, GstClockTime begin, GstClockTime duration)
{
  xmlDocPtr doc;
  xmlNodePtr root_node, head_node, body_node;

  GHashTable *styles_table, *regions_table;
  GList *output_buffers = NULL;
  gchar *value;
  guint cellres_x, cellres_y;
  TtmlWhitespaceMode doc_whitespace_mode = TTML_WHITESPACE_MODE_DEFAULT;

  if (!g_utf8_validate (input, -1, NULL)) {
    GST_CAT_ERROR (ttmlparse_debug, "Input isn't valid UTF-8.");
    return NULL;
  }
  GST_CAT_LOG (ttmlparse_debug, "Input:\n%s", input);

  styles_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
      (GDestroyNotify) ttml_delete_element);
  regions_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
      (GDestroyNotify) ttml_delete_element);

  /* Parse input. */
  doc = xmlReadMemory (input, strlen (input), "any_doc_name", NULL, 0);
  if (!doc) {
    GST_CAT_ERROR (ttmlparse_debug, "Failed to parse document.");
    return NULL;
  }
  root_node = xmlDocGetRootElement (doc);

  if (xmlStrcmp (root_node->name, (const xmlChar *) "tt") != 0) {
    GST_CAT_ERROR (ttmlparse_debug, "Root element of document is not tt:tt.");
    xmlFreeDoc (doc);
    return NULL;
  }

  if ((value = ttml_get_xml_property (root_node, "cellResolution"))) {
    gchar *ptr = value;
    cellres_x = (guint) g_ascii_strtoull (ptr, &ptr, 10U);
    cellres_y = (guint) g_ascii_strtoull (ptr, NULL, 10U);
    g_free (value);
  } else {
    cellres_x = DEFAULT_CELLRES_X;
    cellres_y = DEFAULT_CELLRES_Y;
  }

  GST_CAT_DEBUG (ttmlparse_debug, "cellres_x: %u   cellres_y: %u", cellres_x,
      cellres_y);

  if ((value = ttml_get_xml_property (root_node, "space"))) {
    if (g_strcmp0 (value, "preserve") == 0) {
      GST_CAT_DEBUG (ttmlparse_debug, "Preserving whitespace...");
      doc_whitespace_mode = TTML_WHITESPACE_MODE_PRESERVE;
    }
    g_free (value);
  }

  if (!(head_node = ttml_find_child (root_node, "head"))) {
    GST_CAT_ERROR (ttmlparse_debug, "No <head> element found.");
    xmlFreeDoc (doc);
    return NULL;
  }
  ttml_parse_head (head_node, styles_table, regions_table);

  if ((body_node = ttml_find_child (root_node, "body"))) {
    GNode *body_tree;
    GList *region_trees = NULL;
    GList *scenes = NULL;

    body_tree = ttml_parse_body (body_node);
    GST_CAT_LOG (ttmlparse_debug, "body_tree tree contains %u nodes.",
        g_node_n_nodes (body_tree, G_TRAVERSE_ALL));
    GST_CAT_LOG (ttmlparse_debug, "body_tree tree height is %u",
        g_node_max_height (body_tree));

    ttml_inherit_whitespace_mode (body_tree, doc_whitespace_mode);
    ttml_handle_whitespace (body_tree);
    ttml_filter_content_nodes (body_tree);
    if (GST_CLOCK_TIME_IS_VALID (begin) && GST_CLOCK_TIME_IS_VALID (duration))
      ttml_apply_time_window (body_tree, begin, begin + duration);
    ttml_resolve_timings (body_tree);
    ttml_resolve_regions (body_tree);
    region_trees = ttml_split_body_by_region (body_tree, regions_table);
    ttml_resolve_referenced_styles (region_trees, styles_table);
    ttml_inherit_element_styles (region_trees);
    ttml_assign_region_times (region_trees, begin, duration);
    scenes = ttml_create_scenes (region_trees);
    GST_CAT_LOG (ttmlparse_debug, "There are %u scenes in all.",
        g_list_length (scenes));
    ttml_join_inline_elements (scenes);
    ttml_attach_scene_metadata (scenes, cellres_x, cellres_y);
    output_buffers = create_buffer_list (scenes);

    g_list_free_full (scenes, (GDestroyNotify) ttml_delete_scene);
    g_list_free_full (region_trees, (GDestroyNotify) ttml_delete_tree);
    ttml_delete_tree (body_tree);
  }

  xmlFreeDoc (doc);
  g_hash_table_destroy (styles_table);
  g_hash_table_destroy (regions_table);

  return output_buffers;
}
