/* GStreamer
 * 
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstinterface.c: Interface functions
 *
 * 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.
 */

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

#include "gst_private.h"
#include "gstinterface.h"

static void
gst_implements_interface_class_init (GstImplementsInterfaceClass * ifklass);
static gboolean
gst_implements_interface_supported_default (GstImplementsInterface * iface,
    GType iface_type);

GType
gst_implements_interface_get_type (void)
{
  static GType gst_interface_type = 0;

  if (!gst_interface_type) {
    static const GTypeInfo gst_interface_info = {
      sizeof (GstImplementsInterfaceClass),
      (GBaseInitFunc) gst_implements_interface_class_init,
      NULL,
      NULL,
      NULL,
      NULL,
      0,
      0,
      NULL,
      NULL
    };

    gst_interface_type = g_type_register_static (G_TYPE_INTERFACE,
        "GstImplementsInterface", &gst_interface_info, 0);

    g_type_interface_add_prerequisite (gst_interface_type, GST_TYPE_ELEMENT);
  }

  return gst_interface_type;
}

static void
gst_implements_interface_class_init (GstImplementsInterfaceClass * klass)
{
  klass->supported = gst_implements_interface_supported_default;
}

static gboolean
gst_implements_interface_supported_default (GstImplementsInterface * interface,
    GType iface_type)
{
  /* Well, if someone didn't set the virtual function,
   * then something is clearly wrong. So big no-no here */

  return FALSE;
}

/**
 * gst_element_implements_interface:
 * @element: #GstElement to check for the implementation of the interface
 * @iface_type: (final) type of the interface which we want to be implemented
 *
 * Test whether the given element implements a certain interface of type
 * iface_type, and test whether it is supported for this specific instance.
 *
 * Returns: whether or not the element implements the interface.
 */

gboolean
gst_element_implements_interface (GstElement * element, GType iface_type)
{
  if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (element), iface_type)) {
    GstImplementsInterface *iface;
    GstImplementsInterfaceClass *ifclass;

    iface = G_TYPE_CHECK_INSTANCE_CAST (G_OBJECT (element),
        iface_type, GstImplementsInterface);
    ifclass = GST_IMPLEMENTS_INTERFACE_GET_CLASS (iface);

    if (ifclass->supported != NULL &&
        ifclass->supported (iface, iface_type) == TRUE) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
 * gst_implements_interface_cast:
 * @from: the object (any sort) from which to cast to the interface
 * @type: the interface type to cast to
 *
 * cast a given object to an interface type, and check whether this
 * interface is supported for this specific instance.
 *
 * Returns: a gpointer to the interface type
 */

gpointer
gst_implements_interface_cast (gpointer from, GType iface_type)
{
  GstImplementsInterface *iface;

  /* check cast, give warning+fail if it's invalid */
  if (!(iface = G_TYPE_CHECK_INSTANCE_CAST (from, iface_type,
              GstImplementsInterface))) {
    return NULL;
  }

  /* if we're an element, take care that this interface
   * is actually implemented */
  if (GST_IS_ELEMENT (from)) {
    g_return_val_if_fail (gst_element_implements_interface (GST_ELEMENT (from),
            iface_type), NULL);
  }

  return iface;
}

/**
 * gst_implements_interface_check:
 * @from: the object (any sort) from which to check from for the interface
 * @type: the interface type to check for
 *
 * check a given object for an interface implementation, and check
 * whether this interface is supported for this specific instance.
 *
 * Returns: whether or not the object implements the given interface
 */

gboolean
gst_implements_interface_check (gpointer from, GType type)
{
  GstImplementsInterface *iface;

  /* check cast, return FALSE if it fails, don't give a warning... */
  if (!G_TYPE_CHECK_INSTANCE_TYPE (from, type)) {
    return FALSE;
  }

  iface = G_TYPE_CHECK_INSTANCE_CAST (from, type, GstImplementsInterface);

  /* now, if we're an element (or derivative), is this thing
   * actually implemented for real? */
  if (GST_IS_ELEMENT (from)) {
    if (!gst_element_implements_interface (GST_ELEMENT (from), type)) {
      return FALSE;
    }
  }

  return TRUE;
}
