/* GStreamer
 * Copyright (C) 2013 Collabora Ltd.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) 2013 Sebastian Dröge <slomo@circular-chaos.org>
 *
 * gstcontext.h: Header for GstContext subsystem
 *
 * 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.
 */

/**
 * SECTION:gstcontext
 * @short_description: Lightweight objects to represent element contexts
 * @see_also: #GstMiniObject, #GstElement
 *
 * #GstContext is a container object used to store contexts like a device
 * context, a display server connection and similar concepts that should
 * be shared between multiple elements.
 *
 * Applications can set a context on a complete pipeline by using
 * gst_element_set_context(), which will then be propagated to all
 * child elements. Elements can handle these in #GstElementClass.set_context()
 * and merge them with the context information they already have.
 *
 * When an element needs a context it will do the following actions in this
 * order until one step succeeds:
 * 1. Check if the element already has a context
 * 2. Query downstream with GST_QUERY_CONTEXT for the context
 * 3. Query upstream with GST_QUERY_CONTEXT for the context
 * 4. Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required
 *    context types and afterwards check if a usable context was set now
 * 5. Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message
 *    on the bus.
 *
 * Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously
 * known context on the element that asks for it if possible. Otherwise the
 * application should provide one if it can.
 *
 * #GstContext<!-- -->s can be persistent.
 * A persistent #GstContext is kept in elements when they reach
 * %GST_STATE_NULL, non-persistent ones will be removed.
 * Also, a non-persistent context won't override a previous persistent
 * context set to an element.
 *
 * Since: 1.2
 */

#include "gst_private.h"
#include <string.h>
#include "gstcontext.h"
#include "gstquark.h"

struct _GstContext
{
  GstMiniObject mini_object;

  gchar *context_type;
  GstStructure *structure;
  gboolean persistent;
};

#define GST_CONTEXT_STRUCTURE(c)  (((GstContext *)(c))->structure)

GType _gst_context_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstContext, gst_context);

void
_priv_gst_context_initialize (void)
{
  GST_CAT_INFO (GST_CAT_GST_INIT, "init contexts");

  /* the GstMiniObject types need to be class_ref'd once before it can be
   * done from multiple threads;
   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
  gst_context_get_type ();

  _gst_context_type = gst_context_get_type ();
}

static void
_gst_context_free (GstContext * context)
{
  GstStructure *structure;

  g_return_if_fail (context != NULL);

  GST_CAT_LOG (GST_CAT_CONTEXT, "finalize context %p: %" GST_PTR_FORMAT,
      context, GST_CONTEXT_STRUCTURE (context));

  structure = GST_CONTEXT_STRUCTURE (context);
  if (structure) {
    gst_structure_set_parent_refcount (structure, NULL);
    gst_structure_free (structure);
  }
  g_free (context->context_type);

  g_slice_free1 (sizeof (GstContext), context);
}

static void gst_context_init (GstContext * context);

static GstContext *
_gst_context_copy (GstContext * context)
{
  GstContext *copy;
  GstStructure *structure;

  GST_CAT_LOG (GST_CAT_CONTEXT, "copy context %p: %" GST_PTR_FORMAT, context,
      GST_CONTEXT_STRUCTURE (context));

  copy = g_slice_new0 (GstContext);

  gst_context_init (copy);

  copy->context_type = g_strdup (context->context_type);

  structure = GST_CONTEXT_STRUCTURE (context);
  GST_CONTEXT_STRUCTURE (copy) = gst_structure_copy (structure);
  gst_structure_set_parent_refcount (GST_CONTEXT_STRUCTURE (copy),
      &copy->mini_object.refcount);

  copy->persistent = context->persistent;

  return GST_CONTEXT_CAST (copy);
}

static void
gst_context_init (GstContext * context)
{
  gst_mini_object_init (GST_MINI_OBJECT_CAST (context), 0, _gst_context_type,
      (GstMiniObjectCopyFunction) _gst_context_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_context_free);
}

/**
 * gst_context_new:
 * @context_type: Context type
 * @persistent: Persistent context
 *
 * Create a new context.
 *
 * Returns: (transfer full): The new context.
 *
 * Since: 1.2
 */
GstContext *
gst_context_new (const gchar * context_type, gboolean persistent)
{
  GstContext *context;
  GstStructure *structure;

  g_return_val_if_fail (context_type != NULL, NULL);

  context = g_slice_new0 (GstContext);

  GST_CAT_LOG (GST_CAT_CONTEXT, "creating new context %p", context);

  structure = gst_structure_new_id_empty (GST_QUARK (CONTEXT));
  gst_structure_set_parent_refcount (structure, &context->mini_object.refcount);
  gst_context_init (context);

  context->context_type = g_strdup (context_type);
  GST_CONTEXT_STRUCTURE (context) = structure;
  context->persistent = persistent;

  return context;
}

/**
 * gst_context_get_context_type:
 * @context: The #GstContext.
 *
 * Get the type of @context.
 *
 * Returns: The type of the context.
 *
 * Since: 1.2
 */
const gchar *
gst_context_get_context_type (const GstContext * context)
{
  g_return_val_if_fail (GST_IS_CONTEXT (context), NULL);

  return context->context_type;
}

/**
 * gst_context_has_context_type:
 * @context: The #GstContext.
 * @context_type: Context type to check.
 *
 * Checks if @context has @context_type.
 *
 * Returns: %TRUE if @context has @context_type.
 *
 * Since: 1.2
 */
gboolean
gst_context_has_context_type (const GstContext * context,
    const gchar * context_type)
{
  g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE);
  g_return_val_if_fail (context_type != NULL, FALSE);

  return strcmp (context->context_type, context_type) == 0;
}

/**
 * gst_context_get_structure:
 * @context: The #GstContext.
 *
 * Access the structure of the context.
 *
 * Returns: (transfer none): The structure of the context. The structure is
 * still owned by the context, which means that you should not modify it,
 * free it and that the pointer becomes invalid when you free the context.
 *
 * Since: 1.2
 */
const GstStructure *
gst_context_get_structure (const GstContext * context)
{
  g_return_val_if_fail (GST_IS_CONTEXT (context), NULL);

  return GST_CONTEXT_STRUCTURE (context);
}

/**
 * gst_context_writable_structure:
 * @context: The #GstContext.
 *
 * Get a writable version of the structure.
 *
 * Returns: The structure of the context. The structure is still
 * owned by the context, which means that you should not free it and
 * that the pointer becomes invalid when you free the context.
 * This function checks if @context is writable.
 *
 * Since: 1.2
 */
GstStructure *
gst_context_writable_structure (GstContext * context)
{
  g_return_val_if_fail (GST_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (gst_context_is_writable (context), NULL);

  return GST_CONTEXT_STRUCTURE (context);
}

/**
 * gst_context_is_persistent:
 * @context: The #GstContext.
 *
 * Check if @context is persistent.
 *
 * Returns: %TRUE if the context is persistent.
 *
 * Since: 1.2
 */
gboolean
gst_context_is_persistent (const GstContext * context)
{
  g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE);

  return context->persistent;
}
