/* GStreamer
 * (c) 2010, 2012 Alexander Saprykin <xelfium@gmail.com>
 *
 * gsttoc.c: GstToc initialization and parsing/creation
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gsttoc
 * @short_description: Generic table of contents support
 * @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery
 *
 * #GstToc functions are used to create/free #GstToc and #GstTocEntry structures.
 * Also they are used to convert #GstToc into #GstStructure and vice versa.
 *
 * #GstToc lets you to inform other elements in pipeline or application that playing
 * source has some kind of table of contents (TOC). These may be chapters, editions,
 * angles or other types. For example: DVD chapters, Matroska chapters or cue sheet
 * TOC. Such TOC will be useful for applications to display instead of just a
 * playlist.
 *
 * Using TOC is very easy. Firstly, create #GstToc structure which represents root
 * contents of the source. You can also attach TOC-specific tags to it. Then fill
 * it with #GstTocEntry entries by appending them to #GstToc.entries #GstTocEntry.subentries
 * lists. You should use GST_TOC_ENTRY_TYPE_CHAPTER for generic TOC entry and
 * GST_TOC_ENTRY_TYPE_EDITION for the entries which are considered to be alternatives
 * (like DVD angles, Matroska editions and so on).
 *
 * Note that root level of the TOC can contain only either editions or chapters. You
 * should not mix them together at the same level. Otherwise you will get serialization
 * /deserialization errors. Make sure that no one of the entries has negative start and
 *  stop values.
 *
 * Please, use #GstToc.info and #GstTocEntry.info fields in that way: create a #GstStructure,
 * put all info related to your element there and put this structure into the info field under
 * the name of your element. Some fields in the info structure can be used for internal purposes,
 * so you should use it in the way described above to not to overwrite already existent fields.
 *
 * Use gst_event_new_toc() to create a new TOC #GstEvent, and gst_event_parse_toc() to
 * parse received TOC event. Use gst_event_new_toc_select() to create a new TOC select #GstEvent,
 * and gst_event_parse_toc_select() to parse received TOC select event. The same rule for
 * the #GstMessage: gst_message_new_toc() to create new TOC #GstMessage, and
 * gst_message_parse_toc() to parse received TOC message. Also you can create a new TOC query
 * with gst_query_new_toc(), set it with gst_query_set_toc() and parse it with
 * gst_query_parse_toc().
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "gst_private.h"
#include "gstenumtypes.h"
#include "gsttaglist.h"
#include "gststructure.h"
#include "gstvalue.h"
#include "gsttoc.h"
#include "gstpad.h"
#include "gstquark.h"

struct _GstTocEntry
{
  GstMiniObject mini_object;

  GstToc *toc;
  GstTocEntry *parent;

  gchar *uid;
  GstTocEntryType type;
  GstClockTime start, stop;
  GList *subentries;
  GstTagList *tags;
};

struct _GstToc
{
  GstMiniObject mini_object;

  GstTocScope scope;
  GList *entries;
  GstTagList *tags;
};

#undef gst_toc_copy
static GstToc *gst_toc_copy (const GstToc * toc);
static void gst_toc_free (GstToc * toc);
#undef gst_toc_entry_copy
static GstTocEntry *gst_toc_entry_copy (const GstTocEntry * toc);
static void gst_toc_entry_free (GstTocEntry * toc);

GST_DEFINE_MINI_OBJECT_TYPE (GstToc, gst_toc);
GST_DEFINE_MINI_OBJECT_TYPE (GstTocEntry, gst_toc_entry);

/**
 * gst_toc_new:
 * @scope: scope of this TOC
 *
 * Create a new #GstToc structure.
 *
 * Returns: (transfer full): newly allocated #GstToc structure, free it
 *     with gst_toc_unref().
 */
GstToc *
gst_toc_new (GstTocScope scope)
{
  GstToc *toc;

  g_return_val_if_fail (scope == GST_TOC_SCOPE_GLOBAL ||
      scope == GST_TOC_SCOPE_CURRENT, NULL);

  toc = g_slice_new0 (GstToc);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (toc), 0, GST_TYPE_TOC,
      (GstMiniObjectCopyFunction) gst_toc_copy, NULL,
      (GstMiniObjectFreeFunction) gst_toc_free);

  toc->scope = scope;
  toc->tags = gst_tag_list_new_empty ();

  return toc;
}

/**
 * gst_toc_get_scope:
 * @toc: a #GstToc instance
 *
 * Returns: scope of @toc
 */
GstTocScope
gst_toc_get_scope (const GstToc * toc)
{
  g_return_val_if_fail (toc != NULL, GST_TOC_SCOPE_GLOBAL);

  return toc->scope;
}

/**
 * gst_toc_set_tags:
 * @toc: A #GstToc instance
 * @tags: (allow-none) (transfer full): A #GstTagList or %NULL
 *
 * Set a #GstTagList with tags for the complete @toc.
 */
void
gst_toc_set_tags (GstToc * toc, GstTagList * tags)
{
  g_return_if_fail (toc != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));

  if (toc->tags)
    gst_tag_list_unref (toc->tags);
  toc->tags = tags;
}

/**
 * gst_toc_merge_tags:
 * @toc: A #GstToc instance
 * @tags: (allow-none): A #GstTagList or %NULL
 * @mode: A #GstTagMergeMode
 *
 * Merge @tags into the existing tags of @toc using @mode.
 */
void
gst_toc_merge_tags (GstToc * toc, GstTagList * tags, GstTagMergeMode mode)
{
  g_return_if_fail (toc != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));

  if (!toc->tags) {
    toc->tags = gst_tag_list_ref (tags);
  } else {
    GstTagList *tmp = gst_tag_list_merge (toc->tags, tags, mode);
    gst_tag_list_unref (toc->tags);
    toc->tags = tmp;
  }
}

/**
 * gst_toc_get_tags:
 * @toc: A #GstToc instance
 *
 * Gets the tags for @toc.
 *
 * Returns: (transfer none): A #GstTagList for @entry
 */
GstTagList *
gst_toc_get_tags (const GstToc * toc)
{
  g_return_val_if_fail (toc != NULL, NULL);

  return toc->tags;
}

/**
 * gst_toc_append_entry:
 * @toc: A #GstToc instance
 * @entry: (transfer full): A #GstTocEntry
 *
 * Appends the #GstTocEntry @entry to @toc.
 */
void
gst_toc_append_entry (GstToc * toc, GstTocEntry * entry)
{
  g_return_if_fail (toc != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));
  g_return_if_fail (entry->toc == NULL);
  g_return_if_fail (entry->parent == NULL);

  toc->entries = g_list_append (toc->entries, entry);
  entry->toc = toc;

  GST_LOG ("appended %s entry with uid %s to toc %p",
      gst_toc_entry_type_get_nick (entry->type), entry->uid, toc);

  gst_toc_dump (toc);
}

/**
 * gst_toc_get_entries:
 * @toc: A #GstToc instance
 *
 * Gets the list of #GstTocEntry of @toc.
 *
 * Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry for @entry
 */
GList *
gst_toc_get_entries (const GstToc * toc)
{
  g_return_val_if_fail (toc != NULL, NULL);

  return toc->entries;
}

static GstTocEntry *
gst_toc_entry_new_internal (GstTocEntryType type, const gchar * uid)
{
  GstTocEntry *entry;

  entry = g_slice_new0 (GstTocEntry);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (entry), 0, GST_TYPE_TOC_ENTRY,
      (GstMiniObjectCopyFunction) gst_toc_entry_copy, NULL,
      (GstMiniObjectFreeFunction) gst_toc_entry_free);

  entry->uid = g_strdup (uid);
  entry->type = type;
  entry->tags = NULL;
  entry->start = entry->stop = GST_CLOCK_TIME_NONE;

  return entry;
}

/**
 * gst_toc_entry_new:
 * @type: entry type.
 * @uid: unique ID (UID) in the whole TOC.
 *
 * Create new #GstTocEntry structure.
 *
 * Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_unref().
 */
GstTocEntry *
gst_toc_entry_new (GstTocEntryType type, const gchar * uid)
{
  g_return_val_if_fail (uid != NULL, NULL);

  return gst_toc_entry_new_internal (type, uid);
}

static void
gst_toc_free (GstToc * toc)
{
  g_list_foreach (toc->entries, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (toc->entries);

  if (toc->tags != NULL)
    gst_tag_list_unref (toc->tags);

  g_slice_free (GstToc, toc);
}

static void
gst_toc_entry_free (GstTocEntry * entry)
{
  g_return_if_fail (entry != NULL);

  g_list_foreach (entry->subentries, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (entry->subentries);

  g_free (entry->uid);

  if (entry->tags != NULL)
    gst_tag_list_unref (entry->tags);

  g_slice_free (GstTocEntry, entry);
}

static GstTocEntry *
gst_toc_entry_find_sub_entry (const GstTocEntry * entry, const gchar * uid)
{
  GList *cur;
  GstTocEntry *subentry, *subsubentry;

  g_return_val_if_fail (entry != NULL, NULL);
  g_return_val_if_fail (uid != NULL, NULL);

  cur = entry->subentries;
  while (cur != NULL) {
    subentry = cur->data;

    if (g_strcmp0 (subentry->uid, uid) == 0)
      return subentry;

    subsubentry = gst_toc_entry_find_sub_entry (subentry, uid);
    if (subsubentry != NULL)
      return subsubentry;

    cur = cur->next;
  }

  return NULL;
}

/**
 * gst_toc_find_entry:
 * @toc: #GstToc to search in.
 * @uid: UID to find #GstTocEntry with.
 *
 * Find #GstTocEntry with given @uid in the @toc.
 *
 * Returns: (transfer none): #GstTocEntry with specified @uid from the @toc, or NULL if not found.
 */
GstTocEntry *
gst_toc_find_entry (const GstToc * toc, const gchar * uid)
{
  GList *cur;
  GstTocEntry *entry, *subentry;

  g_return_val_if_fail (toc != NULL, NULL);
  g_return_val_if_fail (uid != NULL, NULL);

  cur = toc->entries;
  while (cur != NULL) {
    entry = cur->data;

    if (g_strcmp0 (entry->uid, uid) == 0)
      return entry;

    subentry = gst_toc_entry_find_sub_entry (entry, uid);
    if (subentry != NULL)
      return subentry;
    cur = cur->next;
  }

  return NULL;
}

/**
 * gst_toc_entry_copy:
 * @entry: #GstTocEntry to copy.
 *
 * Copy #GstTocEntry with all subentries (deep copy).
 *
 * Returns: newly allocated #GstTocEntry in case of success, NULL otherwise;
 * free it when done with gst_toc_entry_unref().
 */
static GstTocEntry *
gst_toc_entry_copy (const GstTocEntry * entry)
{
  GstTocEntry *ret, *sub;
  GstTagList *list;
  GList *cur;

  g_return_val_if_fail (entry != NULL, NULL);

  ret = gst_toc_entry_new (entry->type, entry->uid);

  ret->start = entry->start;
  ret->stop = entry->stop;

  if (GST_IS_TAG_LIST (entry->tags)) {
    list = gst_tag_list_copy (entry->tags);
    if (ret->tags)
      gst_tag_list_unref (ret->tags);
    ret->tags = list;
  }

  cur = entry->subentries;
  while (cur != NULL) {
    sub = gst_toc_entry_copy (cur->data);

    if (sub != NULL)
      ret->subentries = g_list_prepend (ret->subentries, sub);

    cur = cur->next;
  }
  ret->subentries = g_list_reverse (ret->subentries);

  return ret;
}

/**
 * gst_toc_copy:
 * @toc: #GstToc to copy.
 *
 * Copy #GstToc with all subentries (deep copy).
 *
 * Returns: newly allocated #GstToc in case of success, NULL otherwise;
 * free it when done with gst_toc_free().
 */
static GstToc *
gst_toc_copy (const GstToc * toc)
{
  GstToc *ret;
  GstTocEntry *entry;
  GList *cur;
  GstTagList *list;

  g_return_val_if_fail (toc != NULL, NULL);

  ret = gst_toc_new (toc->scope);

  if (GST_IS_TAG_LIST (toc->tags)) {
    list = gst_tag_list_copy (toc->tags);
    gst_tag_list_unref (ret->tags);
    ret->tags = list;
  }

  cur = toc->entries;
  while (cur != NULL) {
    entry = gst_toc_entry_copy (cur->data);

    if (entry != NULL)
      ret->entries = g_list_prepend (ret->entries, entry);

    cur = cur->next;
  }
  ret->entries = g_list_reverse (ret->entries);
  return ret;
}

/**
 * gst_toc_entry_set_start_stop_times:
 * @entry: #GstTocEntry to set values.
 * @start: start value to set.
 * @stop: stop value to set.
 *
 * Set @start and @stop values for the @entry.
 */
void
gst_toc_entry_set_start_stop_times (GstTocEntry * entry, gint64 start,
    gint64 stop)
{
  g_return_if_fail (entry != NULL);

  entry->start = start;
  entry->stop = stop;
}

/**
 * gst_toc_entry_get_start_stop_times:
 * @entry: #GstTocEntry to get values from.
 * @start: (out): the storage for the start value, leave #NULL if not need.
 * @stop: (out): the storage for the stop value, leave #NULL if not need.
 *
 * Get start and stop values from the @entry and write them into appropriate storages.
 *
 * Returns: TRUE if all non-NULL storage pointers were filled with appropriate values,
 * FALSE otherwise.
 */
gboolean
gst_toc_entry_get_start_stop_times (const GstTocEntry * entry, gint64 * start,
    gint64 * stop)
{
  gboolean ret = TRUE;

  g_return_val_if_fail (entry != NULL, FALSE);

  if (start != NULL)
    *start = entry->start;
  if (stop != NULL)
    *stop = entry->stop;

  return ret;
}

/**
 * gst_toc_entry_type_get_nick:
 * @type: a #GstTocEntryType.
 *
 * Converts @type to a string representation.
 *
 * Returns: Returns a human-readable string for @type. This string is
 *    only for debugging purpose and should not be displayed in a user
 *    interface.
 */
const gchar *
gst_toc_entry_type_get_nick (GstTocEntryType type)
{
  switch (type) {
    case GST_TOC_ENTRY_TYPE_ANGLE:
      return "angle";
    case GST_TOC_ENTRY_TYPE_VERSION:
      return "version";
    case GST_TOC_ENTRY_TYPE_EDITION:
      return "edition";
    case GST_TOC_ENTRY_TYPE_TITLE:
      return "title";
    case GST_TOC_ENTRY_TYPE_TRACK:
      return "track";
    case GST_TOC_ENTRY_TYPE_CHAPTER:
      return "chapter";
    default:
      break;
  }
  return "invalid";
}

/**
 * gst_toc_entry_get_entry_type:
 * @entry: a #GstTocEntry
 *
 * Returns: @entry's entry type
 */
GstTocEntryType
gst_toc_entry_get_entry_type (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, GST_TOC_ENTRY_TYPE_INVALID);

  return entry->type;
}

/**
 * gst_toc_entry_is_alternative:
 * @entry: a #GstTocEntry
 *
 * Returns: %TRUE if @entry's type is an alternative type, otherwise %FALSE
 */
gboolean
gst_toc_entry_is_alternative (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, FALSE);

  return GST_TOC_ENTRY_TYPE_IS_ALTERNATIVE (entry->type);
}

/**
 * gst_toc_entry_is_sequence:
 * @entry: a #GstTocEntry
 *
 * Returns: %TRUE if @entry's type is a sequence type, otherwise %FALSE
 */
gboolean
gst_toc_entry_is_sequence (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, FALSE);

  return GST_TOC_ENTRY_TYPE_IS_SEQUENCE (entry->type);
}

/**
 * gst_toc_entry_get_uid:
 * @entry: A #GstTocEntry instance
 *
 * Gets the UID of @entry.
 *
 * Returns: (transfer none): The UID of @entry
 */
const gchar *
gst_toc_entry_get_uid (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, NULL);

  return entry->uid;
}

/**
 * gst_toc_entry_append_sub_entry:
 * @entry: A #GstTocEntry instance
 * @subentry: (transfer full): A #GstTocEntry
 *
 * Appends the #GstTocEntry @subentry to @entry.
 */
void
gst_toc_entry_append_sub_entry (GstTocEntry * entry, GstTocEntry * subentry)
{
  g_return_if_fail (entry != NULL);
  g_return_if_fail (subentry != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST
          (subentry)));
  g_return_if_fail (subentry->toc == NULL);
  g_return_if_fail (subentry->parent == NULL);

  entry->subentries = g_list_append (entry->subentries, subentry);
  subentry->toc = entry->toc;
  subentry->parent = entry;

  GST_LOG ("appended %s subentry with uid %s to entry %s",
      gst_toc_entry_type_get_nick (subentry->type), subentry->uid, entry->uid);
}

/**
 * gst_toc_entry_get_uid:
 * @entry: A #GstTocEntry instance
 *
 * Gets the sub-entries of @entry.
 *
 * Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry of @entry
 */
GList *
gst_toc_entry_get_sub_entries (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, NULL);

  return entry->subentries;
}

/**
 * gst_toc_entry_set_tags:
 * @entry: A #GstTocEntry instance
 * @tags: (allow-none) (transfer full): A #GstTagList or %NULL
 *
 * Set a #GstTagList with tags for the complete @entry.
 */
void
gst_toc_entry_set_tags (GstTocEntry * entry, GstTagList * tags)
{
  g_return_if_fail (entry != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));

  if (entry->tags)
    gst_tag_list_unref (entry->tags);
  entry->tags = tags;
}

/**
 * gst_toc_entry_merge_tags:
 * @entry: A #GstTocEntry instance
 * @tags: (allow-none): A #GstTagList or %NULL
 * @mode: A #GstTagMergeMode
 *
 * Merge @tags into the existing tags of @entry using @mode.
 */
void
gst_toc_entry_merge_tags (GstTocEntry * entry, GstTagList * tags,
    GstTagMergeMode mode)
{
  g_return_if_fail (entry != NULL);
  g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));

  if (!entry->tags) {
    entry->tags = gst_tag_list_ref (tags);
  } else {
    GstTagList *tmp = gst_tag_list_merge (entry->tags, tags, mode);
    gst_tag_list_unref (entry->tags);
    entry->tags = tmp;
  }
}

/**
 * gst_toc_entry_get_tags:
 * @entry: A #GstTocEntry instance
 *
 * Gets the tags for @entry.
 *
 * Returns: (transfer none): A #GstTagList for @entry
 */
GstTagList *
gst_toc_entry_get_tags (const GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, NULL);

  return entry->tags;
}

/**
 * gst_toc_entry_get_toc:
 * @entry: A #GstTocEntry instance
 *
 * Gets the parent #GstToc of @entry.
 *
 * Returns: (transfer none): The parent #GstToc of @entry
 */
GstToc *
gst_toc_entry_get_toc (GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, NULL);

  return entry->toc;
}

/**
 * gst_toc_entry_get_parent:
 * @entry: A #GstTocEntry instance
 *
 * Gets the parent #GstTocEntry of @entry.
 *
 * Returns: (transfer none): The parent #GstTocEntry of @entry
 */
GstTocEntry *
gst_toc_entry_get_parent (GstTocEntry * entry)
{
  g_return_val_if_fail (entry != NULL, NULL);

  return entry->parent;
}

#ifndef GST_DISABLE_GST_DEBUG
static void
gst_toc_dump_entries (GList * entries, guint depth)
{
  GList *e;
  gchar *indent;

  indent = g_malloc0 (depth + 1);
  memset (indent, ' ', depth);
  for (e = entries; e != NULL; e = e->next) {
    GstTocEntry *entry = e->data;

    GST_TRACE ("%s+ %s (%s), %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT ", "
        "tags: %" GST_PTR_FORMAT, indent, entry->uid,
        gst_toc_entry_type_get_nick (entry->type),
        GST_TIME_ARGS (entry->start), GST_TIME_ARGS (entry->stop), entry->tags);

    if (entry->subentries != NULL)
      gst_toc_dump_entries (entry->subentries, depth + 2);
  }
  g_free (indent);
}
#endif

void
gst_toc_dump (GstToc * toc)
{
#ifndef GST_DISABLE_GST_DEBUG
  GST_TRACE ("        Toc %p, scope: %s, tags: %" GST_PTR_FORMAT, toc,
      (toc->scope == GST_TOC_SCOPE_GLOBAL) ? "global" : "current", toc->tags);
  gst_toc_dump_entries (toc->entries, 2);
#endif
}
