// -*- c++ -*-
// Generated by gmmproc 2.42.0 -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_ELEMENT_H
#define _GSTREAMERMM_ELEMENT_H


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* gstreamermm - a C++ wrapper for gstreamer
 *
 * Copyright 2008 The gstreamermm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gst/gst.h>
#include <gstreamermm/object.h>
#include <gstreamermm/clock.h>
#include <gstreamermm/enums.h>
#include <gstreamermm/error.h>
#include <gstreamermm/event.h>
#include <gstreamermm/message.h>
#include <gstreamermm/pad.h>
#include <gstreamermm/query.h>
#include <gstreamermm/context.h>
#include <glibmm/arrayhandle.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstElement GstElement;
typedef struct _GstElementClass GstElementClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Element_Class; } // namespace Gst
namespace Gst
{

/** @defgroup GstBaseClasses gstreamermm Base Classes
 *  Wrapped GStreamer base classes (plug-ins derrive from these).
 */

/** @defgroup GstPlugins gstreamermm Plugins
 *  Wrapped GStreamer plugins.
 */

 /** @defgroup GstInterfaces gstreamermm Interfaces
 *  Wrapped GStreamer interfaces and classes related to them.
 */

class Bus;
class Caps;
class Clock;
class ElementFactory;
class Event;
class Message;
class Pad;
class PadTemplate;
class Query;
class TagList;

//Gst::Iterator<> forward declaration.
template <class CppType>
class Iterator;

/** @addtogroup gstreamermmEnums gstreamermm Enums and Flags */

/** 
 *  @var ElementFlags ELEMENT_FLAG_LOCKED_STATE
 *  Ignore state changes from parent.
 * 
 *  @var ElementFlags ELEMENT_FLAG_SINK
 *  The element is a sink.
 * 
 *  @var ElementFlags ELEMENT_FLAG_SOURCE
 *  The element is a source.
 * 
 *  @var ElementFlags ELEMENT_FLAG_PROVIDE_CLOCK
 *  The element can provide a clock.
 * 
 *  @var ElementFlags ELEMENT_FLAG_REQUIRE_CLOCK
 *  The element requires a clock.
 * 
 *  @var ElementFlags ELEMENT_FLAG_INDEXABLE
 *  The element can use an index.
 * 
 *  @var ElementFlags ELEMENT_FLAG_LAST
 *  Offset to define more flags.
 * 
 *  @enum ElementFlags
 * 
 * The standard flags that an element may have.
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%ElementFlags operator|(ElementFlags, ElementFlags)</tt><br>
 * <tt>%ElementFlags operator&(ElementFlags, ElementFlags)</tt><br>
 * <tt>%ElementFlags operator^(ElementFlags, ElementFlags)</tt><br>
 * <tt>%ElementFlags operator~(ElementFlags)</tt><br>
 * <tt>%ElementFlags& operator|=(ElementFlags&, ElementFlags)</tt><br>
 * <tt>%ElementFlags& operator&=(ElementFlags&, ElementFlags)</tt><br>
 * <tt>%ElementFlags& operator^=(ElementFlags&, ElementFlags)</tt><br>
 */
enum ElementFlags
{
  ELEMENT_FLAG_LOCKED_STATE = (GST_OBJECT_FLAG_LAST << 0),
  ELEMENT_FLAG_SINK = (GST_OBJECT_FLAG_LAST << 1),
  ELEMENT_FLAG_SOURCE = (GST_OBJECT_FLAG_LAST << 2),
  ELEMENT_FLAG_PROVIDE_CLOCK = (GST_OBJECT_FLAG_LAST << 3),
  ELEMENT_FLAG_REQUIRE_CLOCK = (GST_OBJECT_FLAG_LAST << 4),
  ELEMENT_FLAG_INDEXABLE = (GST_OBJECT_FLAG_LAST << 5),
  ELEMENT_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 10)
};

/** @ingroup gstreamermmEnums */
inline ElementFlags operator|(ElementFlags lhs, ElementFlags rhs)
  { return static_cast<ElementFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ElementFlags operator&(ElementFlags lhs, ElementFlags rhs)
  { return static_cast<ElementFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ElementFlags operator^(ElementFlags lhs, ElementFlags rhs)
  { return static_cast<ElementFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ElementFlags operator~(ElementFlags flags)
  { return static_cast<ElementFlags>(~static_cast<unsigned>(flags)); }

/** @ingroup gstreamermmEnums */
inline ElementFlags& operator|=(ElementFlags& lhs, ElementFlags rhs)
  { return (lhs = static_cast<ElementFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup gstreamermmEnums */
inline ElementFlags& operator&=(ElementFlags& lhs, ElementFlags rhs)
  { return (lhs = static_cast<ElementFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup gstreamermmEnums */
inline ElementFlags& operator^=(ElementFlags& lhs, ElementFlags rhs)
  { return (lhs = static_cast<ElementFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::ElementFlags> : public Glib::Value_Flags<Gst::ElementFlags>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{


//TODO: Fix gmmproc so that definition in gst_enums.defs does not cause errors
//and this can be wrapped with _WRAP_ENUM.
enum StateChange
{
  STATE_CHANGE_NULL_TO_READY = GST_STATE_CHANGE_NULL_TO_READY,
  STATE_CHANGE_READY_TO_PAUSED = GST_STATE_CHANGE_READY_TO_PAUSED,
  STATE_CHANGE_PAUSED_TO_PLAYING = GST_STATE_CHANGE_PAUSED_TO_PLAYING,
  STATE_CHANGE_PLAYING_TO_PAUSED = GST_STATE_CHANGE_PLAYING_TO_PAUSED,
  STATE_CHANGE_PAUSED_TO_READY = GST_STATE_CHANGE_PAUSED_TO_READY,
  STATE_CHANGE_READY_TO_NULL = GST_STATE_CHANGE_READY_TO_NULL 
};

/** 
 *  @var StateChangeReturn STATE_CHANGE_FAILURE
 *  The state change failed.
 * 
 *  @var StateChangeReturn STATE_CHANGE_SUCCESS
 *  The state change succeeded.
 * 
 *  @var StateChangeReturn STATE_CHANGE_ASYNC
 *  The state change will happen asynchronously.
 * 
 *  @var StateChangeReturn STATE_CHANGE_NO_PREROLL
 *  The state change succeeded but the element cannot produce data in Gst::STATE_PAUSED. This typically happens with live sources.
 * 
 *  @enum StateChangeReturn
 * 
 * The possible return values from a state change function such as 
 * Gst::Element::set_state(). Only @a GST_STATE_CHANGE_FAILURE is a real failure.
 * @ingroup gstreamermmEnums
 */
enum StateChangeReturn
{
  STATE_CHANGE_FAILURE,
  STATE_CHANGE_SUCCESS,
  STATE_CHANGE_ASYNC,
  STATE_CHANGE_NO_PREROLL
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::StateChangeReturn> : public Glib::Value_Enum<Gst::StateChangeReturn>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{


namespace Enums
{

/**  Gets a string representing the given state.
 *
 * @param state A Gst::State to get the name of.
 * @return A Glib::ustring with the name of the state.
 */
Glib::ustring get_name(State state);

/** Gets a string representing the given state change result.
 *
 * @param state_ret A Gst::StateChangeReturn to get the name of.
 * @return A Glib::ustring with the name of the state change result.
 */
Glib::ustring get_name(StateChangeReturn state_ret);

} //namespace Enums

/** The abstract base class for all pipeline elements.
 * Gst::Element is the abstract base class needed to construct an element that
 * can be used in a GStreamer pipeline. Please refer to the plugin writers
 * guide for more information on creating Gst::Element subclasses.
 *
 * The name of a Gst::Element can be get with get_name() and set with
 * set_name().
 *
 * All elements have pads (of the type Gst::Pad). These pads link to pads on
 * other elements. Gst::Buffer flow between these linked pads. An Element has a
 * GList of Gst::Pad structures for all their input (or sink) and output (or
 * source) pads.  Core and plug-in writers can add and remove pads with
 * add_pad() and remove_pad().
 *
 * A pad of an element can be retrieved by name with get_request_pad() or
 * get_static_pad(). An iterator of all pads can be retrieved with
 * iterate_pads().
 *
 * Gst::Elements can be linked through their pads. Use the link() function to
 * link elements. Use link_filtered() to link two elements constrained by a
 * specified set of Gst::Caps. For finer control, use link_pads() and
 * link_pads_filtered() to specify the pads to link on each element by name.
 *
 * Each element has a state (see State). You can get and set the state of an
 * element with get_state() and set_state(). To get a string representation of
 * a State, use Gst::Enums::get_name().
 *
 * Note that clock slection and distribution is normally handled by the
 * toplevel Gst::Pipeline so the clock functions are only to be used in very
 * specific situations.
 *
 * Last reviewed on 2006-03-12 (0.10.5).
 * @ingroup GstBaseClasses
 */

class Element : public Gst::Object
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Element CppObjectType;
  typedef Element_Class CppClassType;
  typedef GstElement BaseObjectType;
  typedef GstElementClass BaseClassType;

private:  friend class Element_Class;
  static CppClassType element_class_;

private:
  // noncopyable
  Element(const Element&);
  Element& operator=(const Element&);

protected:
  explicit Element(const Glib::ConstructParams& construct_params);
  explicit Element(GstElement* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Element();

  /** Get the GType for this class, for use with the underlying GObject type system.
   */
  static GType get_type()      G_GNUC_CONST;

#ifndef DOXYGEN_SHOULD_SKIP_THIS


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GstElement*       gobj()       { return reinterpret_cast<GstElement*>(gobject_); }

  ///Provides access to the underlying C GObject.
  const GstElement* gobj() const { return reinterpret_cast<GstElement*>(gobject_); }

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GstElement* gobj_copy();

private:


public:
  /** Links this source element to the @dest element.
   * The link must be from source to destination - the other direction will not
   * be tried.  The function looks for existing pads that aren't linked yet. It
   * will request new pads if necessary. Such pads need to be released manually
   * when unlinking.  If multiple links are possible, only one is established.
   *
   * Make sure you have added your elements to a bin or pipeline with
   * Gst::Bin::add() before trying to link them.
   *
   * @param dest the Gst::Element containing the destination pad.
   * @return the destination element for further linking if desired.
   * @throws std::runtime_error If the elements could not be linked.
   */
  Glib::RefPtr<Gst::Element> link(const Glib::RefPtr<Gst::Element>& dest);
  

  /** Adds a pad (link point) to @a element. @a pad's parent will be set to @a element;
   * see Gst::Object::set_parent() for refcounting information.
   * 
   * Pads are not automatically activated so elements should perform the needed
   * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
   * state. See Gst::Pad::set_active() for more information about activating pads.
   * 
   * The pad and the element should be unlocked when calling this function.
   * 
   * This function will emit the Gst::Element::signal_pad_added() signal on the element.
   * 
   * @param pad The Gst::Pad to add to the element.
   * @return <tt>true</tt> if the pad could be added. This function can fail when
   * a pad with the same name already existed or the pad already had another
   * parent.
   * 
   * MT safe.
   */
  bool add_pad(const Glib::RefPtr<Gst::Pad>& pad);
  
  /** Creates a pad for each pad template that is always available.
   * This function is only useful during object initialization of
   * subclasses of Gst::Element.
   * 
   */
  void create_all_pads();

  
  /** Looks for an unlinked pad to which the given pad can link. It is not
   * guaranteed that linking the pads will work, though it should work in most
   * cases.
   * 
   * This function will first attempt to find a compatible unlinked ALWAYS pad,
   * and if none can be found, it will request a compatible REQUEST pad by looking
   * at the templates of @a element.
   * 
   * @param pad The Gst::Pad to find a compatible one for.
   * @param caps The Gst::Caps to use as a filter.
   * @return The Gst::Pad to which a link can be made, or <tt>0</tt>
   * if one cannot be found. Gst::Object::unref() after usage.
   */
  Glib::RefPtr<Gst::Pad> create_compatible_pad(const Glib::RefPtr<const Gst::Pad>& pad, const Glib::RefPtr<const Gst::Caps>& caps);
  
  /** Retrieves a pad template from @a element that is compatible with @a compattempl.
   * Pads from compatible templates can be linked together.
   * 
   * @param compattempl The Gst::PadTemplate to find a compatible
   * template for.
   * @return A compatible Gst::PadTemplate, or <tt>0</tt> if none
   * was found. No unreferencing is necessary.
   */
  Glib::RefPtr<Gst::PadTemplate> get_compatible_pad_template(const Glib::RefPtr<const Gst::PadTemplate>& compattempl);
  
  /** Retrieves a pad template from @a element that is compatible with @a compattempl.
   * Pads from compatible templates can be linked together.
   * 
   * @param compattempl The Gst::PadTemplate to find a compatible
   * template for.
   * @return A compatible Gst::PadTemplate, or <tt>0</tt> if none
   * was found. No unreferencing is necessary.
   */
  Glib::RefPtr<const Gst::PadTemplate> get_compatible_pad_template(const Glib::RefPtr<const Gst::PadTemplate>& compattempl) const;

  //TODO: The documentation says "The pad should be released with gst_element_release_request_pad().", which is odd. murrayc
  
  /** Retrieves a pad from the element by name (e.g.\ "src_\\%d"). This version only
   * retrieves request pads. The pad should be released with
   * release_request_pad().
   * 
   * This method is slow and will be deprecated in the future. New code should
   * use request_pad() with the requested template.
   * 
   * @param name The name of the request Gst::Pad to retrieve.
   * @return Requested Gst::Pad if found, otherwise <tt>0</tt>.
   * Release after usage.
   */
  Glib::RefPtr<Gst::Pad> get_request_pad(const Glib::ustring& name);

  //TODO: The documentation says "The pad should be released with gst_element_release_request_pad().", which is odd. murrayc
  
  /** Retrieves a request pad from the element according to the provided template.
   * Pad templates can be looked up using
   * Gst::ElementFactory::get_static_pad_templates().
   * 
   * The pad should be released with release_request_pad().
   * 
   * @param templ A Gst::PadTemplate of which we want a pad of.
   * @param name The name of the request Gst::Pad
   * to retrieve. Can be <tt>0</tt>.
   * @param caps The caps of the pad we want to
   * request. Can be <tt>0</tt>.
   * @return Requested Gst::Pad if found, otherwise <tt>0</tt>.
   * Release after usage.
   */
  Glib::RefPtr<Gst::Pad> request_pad(const Glib::RefPtr<Gst::PadTemplate>& templ, const Glib::ustring& name, const Glib::RefPtr<const Gst::Caps>& caps);

  /// A request_pad() convenience overload.
  Glib::RefPtr<Gst::Pad> request_pad(const Glib::RefPtr<Gst::PadTemplate>& templ, const Glib::ustring& name);

  /// A request_pad() convenience overload.
  Glib::RefPtr<Gst::Pad> request_pad(const Glib::RefPtr<Gst::PadTemplate>& templ, const Glib::RefPtr<const Gst::Caps>& caps);

  /// A request_pad() convenience overload.
  Glib::RefPtr<Gst::Pad> request_pad(const Glib::RefPtr<Gst::PadTemplate>& templ);

  
  /** Retrieves a pad from @a element by name. This version only retrieves
   * already-existing (i.e. 'static') pads.
   * 
   * @param name The name of the static Gst::Pad to retrieve.
   * @return The requested Gst::Pad if found, otherwise <tt>0</tt>.
   * unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::Pad> get_static_pad(const Glib::ustring& name);
  
  /** Retrieves a pad from @a element by name. This version only retrieves
   * already-existing (i.e. 'static') pads.
   * 
   * @param name The name of the static Gst::Pad to retrieve.
   * @return The requested Gst::Pad if found, otherwise <tt>0</tt>.
   * unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<const Gst::Pad> get_static_pad(const Glib::ustring& name) const;
  //gtkmmproc error: gst_element_get_pad : ignored method defs lookup failed

  
  /** Use this function to signal that the element does not expect any more pads
   * to show up in the current pipeline. This function should be called whenever
   * pads have been added by the element itself. Elements with Gst::PAD_SOMETIMES
   * pad templates use this in combination with autopluggers to figure out that
   * the element is done initializing its pads.
   * 
   * This function emits the Gst::Element::signal_no_more_pads() signal.
   * 
   * MT safe.
   * 
   */
  void no_more_pads();

  
  /** Makes the element free the previously requested pad as obtained with
   * get_request_pad().
   * MT safe.
   * @param pad The Gst::Pad to release.
   */
  void release_request_pad(const Glib::RefPtr<Gst::Pad>& pad);

  
  /** Removes @a pad from @a element. @a pad will be destroyed if it has not been
   * referenced elsewhere using Gst::Object::unparent().
   * 
   * This function is used by plugin developers and should not be used
   * by applications. Pads that were dynamically requested from elements
   * with get_request_pad() should be released with the
   * release_request_pad() function instead.
   * 
   * Pads are not automatically deactivated so elements should perform the needed
   * steps to deactivate the pad in case this pad is removed in the PAUSED or
   * PLAYING state. See Gst::Pad::set_active() for more information about
   * deactivating pads.
   * 
   * The pad and the element should be unlocked when calling this function.
   * 
   * This function will emit the Gst::Element::signal_pad_removed() signal on the element.
   * 
   * @param pad The Gst::Pad to remove from the element.
   * @return <tt>true</tt> if the pad could be removed. Can return <tt>false</tt> if the
   * pad does not belong to the provided element.
   * 
   * MT safe.
   */
  bool remove_pad(const Glib::RefPtr<Gst::Pad>& pad);
  
  /** Retrieves an iterator of @a element's pads. The iterator should
   * be freed after usage. Also more specialized iterators exists such as
   * iterate_src_pads() or iterate_sink_pads().
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<Gst::Pad> iterate_pads();
  
  /** Retrieves an iterator of @a element's pads. The iterator should
   * be freed after usage. Also more specialized iterators exists such as
   * iterate_src_pads() or iterate_sink_pads().
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<const Gst::Pad> iterate_pads() const;
  
  /** Retrieves an iterator of @a element's sink pads.
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<Gst::Pad> iterate_sink_pads();
  
  /** Retrieves an iterator of @a element's sink pads.
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<const Gst::Pad> iterate_sink_pads() const;
  
  /** Retrieves an iterator of @a element's source pads.
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<Gst::Pad> iterate_src_pads();
  
  /** Retrieves an iterator of @a element's source pads.
   * 
   * The order of pads returned by the iterator will be the order in which
   * the pads were added to the element.
   * 
   * @return The Gst::Iterator of Gst::Pad.
   * 
   * MT safe.
   */
  Gst::Iterator<const Gst::Pad> iterate_src_pads() const;
  
  /** Unlinks all source pads of the source element with all sink pads
   * of the sink element to which they are linked.
   * 
   * If the link has been made using link(), it could have created an
   * requestpad, which has to be released using release_request_pad().
   * 
   * @param dest The sink Gst::Element to unlink.
   */
  void unlink(const Glib::RefPtr<Gst::Element>& dest);
  
  /** Sets the context of the element. Increases the refcount of the context.
   * 
   * MT safe.
   * 
   * @param context The Gst::Context to set.
   */
  void set_context(const Glib::RefPtr<Gst::Context>& context);
  

  //This is not like link() because link() was written to return the
  //destination element as a convenience for further linking to compensate for
  //C API's convenience function gst_element_link_many().
  
  /** Links the two named pads of the source and destination elements.
   * Side effect is that if one of the pads has no parent, it becomes a
   * child of the parent of the other element.  If they have different
   * parents, the link fails.
   * 
   * @param srcpadname The name of the Gst::Pad in source element
   * or <tt>0</tt> for any pad.
   * @param dest The Gst::Element containing the destination pad.
   * @param destpadname The name of the Gst::Pad in destination element,
   * or <tt>0</tt> for any pad.
   * @return <tt>true</tt> if the pads could be linked, <tt>false</tt> otherwise.
   */
  bool link_pads(const Glib::ustring& srcpadname, const Glib::RefPtr<Gst::Element>& dest, const Glib::ustring& destpadname);

  
  /** Unlinks the two named pads of the source and destination elements.
   * 
   * This is a convenience function for Gst::Pad::unlink().
   * 
   * @param srcpadname The name of the Gst::Pad in source element.
   * @param dest A Gst::Element containing the destination pad.
   * @param destpadname The name of the Gst::Pad in destination element.
   */
  void unlink_pads(const Glib::ustring& srcpadname, const Glib::RefPtr<Gst::Element>& dest, const Glib::ustring& destpadname);

  //This is not like link() because link() was written to return the
  //destination element as a convenience for further linking to compensate for
  //C API's convenience function gst_element_link_many().
  
  /** Links the two named pads of the source and destination elements. Side effect
   * is that if one of the pads has no parent, it becomes a child of the parent of
   * the other element. If they have different parents, the link fails. If @a caps
   * is not #<tt>0</tt>, makes sure that the caps of the link is a subset of @a caps.
   * 
   * @param srcpadname The name of the Gst::Pad in source element
   * or <tt>0</tt> for any pad.
   * @param dest The Gst::Element containing the destination pad.
   * @param destpadname The name of the Gst::Pad in destination element
   * or <tt>0</tt> for any pad.
   * @param filter The Gst::Caps to filter the link,
   * or #<tt>0</tt> for no filter.
   * @return <tt>true</tt> if the pads could be linked, <tt>false</tt> otherwise.
   */
  bool link_pads(const Glib::ustring& srcpadname, const Glib::RefPtr<Gst::Element>& dest, const Glib::ustring& destpadname, const Glib::RefPtr<Gst::Caps>& filter);

  //This is not like link() because link() was written to return the
  //destination element as a convenience for further linking to compensate for
  //C API's convenience function gst_element_link_many().
  
  /** Links the two named pads of the source and destination elements.
   * Side effect is that if one of the pads has no parent, it becomes a
   * child of the parent of the other element.  If they have different
   * parents, the link fails.
   * 
   * Calling link_pads_full() with @a flags == Gst::PAD_LINK_CHECK_DEFAULT
   * is the same as calling link_pads() and the recommended way of
   * linking pads with safety checks applied.
   * 
   * This is a convenience function for Gst::Pad::link_full().
   * 
   * @param srcpadname The name of the Gst::Pad in source element
   * or <tt>0</tt> for any pad.
   * @param dest The Gst::Element containing the destination pad.
   * @param destpadname The name of the Gst::Pad in destination element,
   * or <tt>0</tt> for any pad.
   * @param flags The Gst::PadLinkCheck to be performed when linking pads.
   * @return <tt>true</tt> if the pads could be linked, <tt>false</tt> otherwise.
   */
  bool link_pads(const Glib::ustring& srcpadname, const Glib::RefPtr<Gst::Element>& dest, const Glib::ustring& destpadname, PadLinkCheck flags);

  /** Links @a src to @a dest using the given caps as filtercaps. The link must
   * be from source to destination; the other direction will not be tried. The
   * function looks for existing pads that aren't linked yet. It will request
   * new pads if necessary. If multiple links are possible, only one is
   * established.
   *
   * Make sure you have added your elements to a bin or pipeline with
   * Gst::Bin::add() before trying to link them.
   *
   * @param dest The Gst::Element containing the destination pad.
   * @param filter The Gst::Caps to filter the link.
   * @return the destination element for further linking if desired.
   * @throws std::runtime_error If the elements could not be linked.
   */
  Glib::RefPtr<Gst::Element> link(const Glib::RefPtr<Gst::Element>& dest, const Glib::RefPtr<Gst::Caps>& filter);
  

  /** Set the base time of an element. See get_base_time().
   * 
   * MT safe.
   * 
   * @param time The base time to set.
   */
  void set_base_time(ClockTime time);
  
  /** Returns the base time of the element. The base time is the
   * absolute time of the clock when this element was last put to
   * PLAYING. Subtracting the base time from the clock time gives
   * the running time of the element.
   * 
   * @return The base time of the element.
   * 
   * MT safe.
   */
  ClockTime get_base_time() const;
  
  /** Set the start time of an element. The start time of the element is the
   * running time of the element when it last went to the PAUSED state. In READY
   * or after a flushing seek, it is set to 0.
   * 
   * Toplevel elements like Gst::Pipeline will manage the start_time and
   * base_time on its children. Setting the start_time to Gst::CLOCK_TIME_NONE
   * on such a toplevel element will disable the distribution of the base_time to
   * the children and can be useful if the application manages the base_time
   * itself, for example if you want to synchronize capture from multiple
   * pipelines, and you can also ensure that the pipelines have the same clock.
   * 
   * MT safe.
   * 
   * @param time The base time to set.
   */
  void set_start_time(Gst::ClockTime time);
  
  /** Returns the start time of the element. The start time is the
   * running time of the clock when this element was last put to PAUSED.
   * 
   * Usually the start_time is managed by a toplevel element such as
   * Gst::Pipeline.
   * 
   * MT safe.
   * 
   * @return The start time of the element.
   */
  Gst::ClockTime get_start_time() const;
  
  /** Sets the bus of the element. Increases the refcount on the bus.
   * For internal use only, unless you're testing elements.
   * 
   * MT safe.
   * 
   * @param bus The Gst::Bus to set.
   */
  void set_bus(const Glib::RefPtr<Gst::Bus>& bus);
  
  /** Returns the bus of the element. Note that only a Gst::Pipeline will provide a
   * bus for the application.
   * 
   * @return The element's Gst::Bus. unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::Bus> get_bus();
  
  /** Returns the bus of the element. Note that only a Gst::Pipeline will provide a
   * bus for the application.
   * 
   * @return The element's Gst::Bus. unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<const Gst::Bus> get_bus() const;

  
  /** Retrieves the factory that was used to create this element.
   * 
   * @return The Gst::ElementFactory used for creating this
   * element. no refcounting is needed.
   */
  Glib::RefPtr<Gst::ElementFactory> get_factory();
  
  /** Retrieves the factory that was used to create this element.
   * 
   * @return The Gst::ElementFactory used for creating this
   * element. no refcounting is needed.
   */
  Glib::RefPtr<const Gst::ElementFactory> get_factory() const;

  // We don't wrap the gst_element_get_name(), gst_element_set_name(), 
  // gst_element_get_parent(), and gst_element_set_parent() macros because they 
  // just calls the base (GstObject) class's functions anyway.

  
  /** Sets the clock for the element. This function increases the
   * refcount on the clock. Any previously set clock on the object
   * is unreffed.
   * 
   * @param clock The Gst::Clock to set for the element.
   * @return <tt>true</tt> if the element accepted the clock. An element can refuse a
   * clock when it, for example, is not able to slave its internal clock to the
   *  @a clock or when it requires a specific clock to operate.
   * 
   * MT safe.
   */
  bool set_clock(const Glib::RefPtr<Gst::Clock>& clock);
  
  /** Gets the currently configured clock of the element. This is the clock as was
   * last set with set_clock().
   * 
   * @return The Gst::Clock of the element. unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::Clock> get_clock();
  
  /** Gets the currently configured clock of the element. This is the clock as was
   * last set with set_clock().
   * 
   * @return The Gst::Clock of the element. unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<const Gst::Clock> get_clock() const;
  
  /** Get the clock provided by the given element.
   * <note>An element is only required to provide a clock in the PAUSED
   * state. Some elements can provide a clock in other states.</note>
   * 
   * @return The GstClock provided by the element or <tt>0</tt>
   * if no clock could be provided.  Unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::Clock> provide_clock();
  
  /** Get the clock provided by the given element.
   * <note>An element is only required to provide a clock in the PAUSED
   * state. Some elements can provide a clock in other states.</note>
   * 
   * @return The GstClock provided by the element or <tt>0</tt>
   * if no clock could be provided.  Unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<const Gst::Clock> provide_clock() const;
  
  /** Sets the state of the element. This function will try to set the
   * requested state by going through all the intermediary states and calling
   * the class's state change function for each.
   * 
   * This function can return Gst::STATE_CHANGE_ASYNC, in which case the
   * element will perform the remainder of the state change asynchronously in
   * another thread.
   * An application can use get_state() to wait for the completion
   * of the state change or it can wait for a Gst::MESSAGE_ASYNC_DONE or
   * Gst::MESSAGE_STATE_CHANGED on the bus.
   * 
   * State changes to Gst::STATE_READY or Gst::STATE_NULL never return
   * Gst::STATE_CHANGE_ASYNC.
   * 
   * @param state The element's new Gst::State.
   * @return Result of the state change using Gst::StateChangeReturn.
   * 
   * MT safe.
   */
  StateChangeReturn set_state(State state);
  
  /** Gets the state of the element.
   * 
   * For elements that performed an ASYNC state change, as reported by
   * set_state(), this function will block up to the
   * specified timeout value for the state change to complete.
   * If the element completes the state change or goes into
   * an error, this function returns immediately with a return value of
   * Gst::STATE_CHANGE_SUCCESS or Gst::STATE_CHANGE_FAILURE respectively.
   * 
   * For elements that did not return Gst::STATE_CHANGE_ASYNC, this function
   * returns the current and pending state immediately.
   * 
   * This function returns Gst::STATE_CHANGE_NO_PREROLL if the element
   * successfully changed its state but is not able to provide data yet.
   * This mostly happens for live sources that only produce data in
   * Gst::STATE_PLAYING. While the state change return is equivalent to
   * Gst::STATE_CHANGE_SUCCESS, it is returned to the application to signal that
   * some sink elements might not be able to complete their state change because
   * an element is not producing data to complete the preroll. When setting the
   * element to playing, the preroll will complete and playback will start.
   * 
   * @param state A pointer to Gst::State to hold the state.
   * Can be <tt>0</tt>.
   * @param pending A pointer to Gst::State to hold the pending
   * state. Can be <tt>0</tt>.
   * @param timeout A Gst::ClockTime to specify the timeout for an async
   * state change or Gst::CLOCK_TIME_NONE for infinite timeout.
   * @return Gst::STATE_CHANGE_SUCCESS if the element has no more pending state
   * and the last state change succeeded, Gst::STATE_CHANGE_ASYNC if the
   * element is still performing a state change or
   * Gst::STATE_CHANGE_FAILURE if the last state change failed.
   * 
   * MT safe.
   */
  StateChangeReturn get_state(State& state, State& pending, ClockTime timeout) const;
  
  /** Locks the state of an element, so state changes of the parent don't affect
   * this element anymore.
   * 
   * MT safe.
   * 
   * @param locked_state <tt>true</tt> to lock the element's state.
   * @return <tt>true</tt> if the state was changed, <tt>false</tt> if bad parameters were given
   * or the elements state-locking needed no change.
   */
  bool set_locked_state(gboolean locked_state);
  
  /** Checks if the state of an element is locked.
   * If the state of an element is locked, state changes of the parent don't
   * affect the element.
   * This way you can leave currently unused elements inside bins. Just lock their
   * state before changing the state from Gst::STATE_NULL.
   * 
   * MT safe.
   * 
   * @return <tt>true</tt>, if the element's state is locked.
   */
  bool is_locked_state() const;
  
  /** Abort the state change of the element. This function is used
   * by elements that do asynchronous state changes and find out
   * something is wrong.
   * 
   * This function should be called with the STATE_LOCK held.
   * 
   * MT safe.
   * 
   */
  void abort_state();
  
  /** Commit the state change of the element and proceed to the next
   * pending state if any. This function is used
   * by elements that do asynchronous state changes.
   * The core will normally call this method automatically when an
   * element returned Gst::STATE_CHANGE_SUCCESS from the state change function.
   * 
   * If after calling this method the element still has not reached
   * the pending state, the next state change is performed.
   * 
   * This method is used internally and should normally not be called by plugins
   * or applications.
   * 
   * @param ret The previous state return value.
   * @return The result of the commit state change.
   * 
   * MT safe.
   */
  StateChangeReturn continue_state(StateChangeReturn ret);
  
  /** Brings the element to the lost state. The current state of the
   * element is copied to the pending state so that any call to
   * get_state() will return Gst::STATE_CHANGE_ASYNC.
   * 
   * An ASYNC_START message is posted. If the element was PLAYING, it will
   * go to PAUSED. The element will be restored to its PLAYING state by
   * the parent pipeline when it prerolls again.
   * 
   * This is mostly used for elements that lost their preroll buffer
   * in the Gst::STATE_PAUSED or Gst::STATE_PLAYING state after a flush,
   * they will go to their pending state again when a new preroll buffer is
   * queued. This function can only be called when the element is currently
   * not in error or an async state change.
   * 
   * This function is used internally and should normally not be called from
   * plugins or applications.
   * 
   */
  void lost_state();
  
  /** Tries to change the state of the element to the same as its parent.
   * If this function returns <tt>false</tt>, the state of element is undefined.
   * 
   * @return <tt>true</tt>, if the element's state could be synced to the parent's state.
   * 
   * MT safe.
   */
  bool sync_state_with_parent();
  
  /** Perform @a transition on @a element.
   * 
   * This function must be called with STATE_LOCK held and is mainly used
   * internally.
   * 
   * @param transition The requested transition.
   * @return The Gst::StateChangeReturn of the state transition.
   */
  StateChangeReturn change_state(StateChange transition);

  /** Post an error, warning or info message on the bus from inside an element.
   *
   * type must be of Gst::MESSAGE_ERROR, Gst::MESSAGE_WARNING or
   * Gst::MESSAGE_INFO.
   *
   * MT safe.
   *
   * @param code The GError code belonging to the domain.
   * @param line The source code line where the error was generated.
   * @param type The GstMessageType.
   * @param domain The GStreamer GError domain this message belongs to.
   * @param text A text string to be used as a replacement for the default
   * message connected to code.
   * @param debug A debug message to be used as a replacement for the default
   * debugging information.
   * @param file The source code file where the error was generated.
   * @param function The source code function where the error was generated.
   */
  void post_message(int code, int line, MessageType type = Gst::MESSAGE_INFO,
    const Glib::QueryQuark& domain = get_core_error_quark(),
    const Glib::ustring& text = Glib::ustring(),
    const Glib::ustring& debug = Glib::ustring(),
    const Glib::ustring& file = Glib::ustring(),
    const Glib::ustring& function = Glib::ustring());
  

  /** Post a message on the element's Gst::Bus. This function takes ownership of the
   * message; if you want to access the message after this call, you should add an
   * additional reference before calling.
   * 
   * @param message A Gst::Message to post.
   * @return <tt>true</tt> if the message was successfully posted. The function returns
   * <tt>false</tt> if the element did not have a bus.
   * 
   * MT safe.
   */
  bool post_message(const Glib::RefPtr<Gst::Message>& message);

  
  /** Performs a query on the given element.
   * 
   * For elements that don't implement a query handler, this function
   * forwards the query to a random srcpad or to the peer of a
   * random linked sinkpad of this element.
   * 
   * Please note that some queries might need a running pipeline to work.
   * 
   * @param query The Gst::Query.
   * @return <tt>true</tt> if the query could be performed.
   * 
   * MT safe.
   */
  bool query(const Glib::RefPtr<Gst::Query>& query) const;
  
  /** Queries an element to convert @a src_val in @a src_format to @a dest_format.
   * 
   * @param src_format A Gst::Format to convert from.
   * @param src_val A value to convert.
   * @param dest_format The Gst::Format to convert to.
   * @param dest_val A pointer to the result.
   * @return <tt>true</tt> if the query could be performed.
   */
  bool query_convert(Gst::Format src_format, gint64 src_val, Format dest_format, gint64& dest_val) const;
  
  /** Queries an element (usually top-level pipeline or playbin element) for the
   * stream position in nanoseconds. This will be a value between 0 and the
   * stream duration (if the stream duration is known). This query will usually
   * only work once the pipeline is prerolled (i.e. reached PAUSED or PLAYING
   * state). The application will receive an ASYNC_DONE message on the pipeline
   * bus when that is the case.
   * 
   * If one repeatedly calls this function one can also create a query and reuse
   * it in query().
   * 
   * @param format The Gst::Format requested.
   * @param cur A location in which to store the current
   * position, or <tt>0</tt>.
   * @return <tt>true</tt> if the query could be performed.
   */
  bool query_position(Gst::Format format, gint64& cur) const;

  /** Queries an element for the stream position.
   *
   * @param format On return will
   * contain the Gst::Format used.
   * @return true if the query could be performed.
   */
  bool query_position(Gst::Format format) const;

  
  /** Queries an element (usually top-level pipeline or playbin element) for the
   * total stream duration in nanoseconds. This query will only work once the
   * pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The application
   * will receive an ASYNC_DONE message on the pipeline bus when that is the case.
   * 
   * If the duration changes for some reason, you will get a DURATION_CHANGED
   * message on the pipeline bus, in which case you should re-query the duration
   * using this function.
   * 
   * @param format The Gst::Format requested.
   * @param duration A location in which to store the total duration, or <tt>0</tt>.
   * @return <tt>true</tt> if the query could be performed.
   */
  bool query_duration(Gst::Format format, gint64& duration) const;

  /** Queries an element for the total stream duration.
   *
   * @param format On return contains
   * the Gst::Format used.
   * @return true if the query could be performed.
   */
  bool query_duration(Gst::Format format) const;

  
  /** Simple API to perform a seek on the given element, meaning it just seeks
   * to the given position relative to the start of the stream. For more complex
   * operations like segment seeks (e.g. for looping) or changing the playback
   * rate or seeking relative to the last configured playback segment you should
   * use seek().
   * 
   * In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
   * guaranteed to return <tt>true</tt> on a seekable media type or <tt>false</tt> when the media
   * type is certainly not seekable (such as a live stream).
   * 
   * Some elements allow for seeking in the READY state, in this
   * case they will store the seek event and execute it when they are put to
   * PAUSED. If the element supports seek in READY, it will always return <tt>true</tt> when
   * it receives the event in the READY state.
   * 
   * @param format A Gst::Format to execute the seek in, such as Gst::FORMAT_TIME.
   * @param seek_flags Seek options; playback applications will usually want to use
   * GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT here.
   * @param seek_pos Position to seek to (relative to the start); if you are doing
   * a seek in Gst::FORMAT_TIME this value is in nanoseconds -
   * multiply with Gst::SECOND to convert seconds to nanoseconds or
   * with Gst::MSECOND to convert milliseconds to nanoseconds.
   * @return <tt>true</tt> if the seek operation succeeded. Flushing seeks will trigger a
   * preroll, which will emit Gst::MESSAGE_ASYNC_DONE.
   */
  bool seek(Format format, SeekFlags seek_flags, gint64 seek_pos);
  
  /** Sends a seek event to an element. See gst_event_new_seek() for the details of
   * the parameters. The seek event is sent to the element using
   * send_event().
   * 
   * MT safe.
   * 
   * @param rate The new playback rate.
   * @param format The format of the seek values.
   * @param flags The optional seek flags.
   * @param start_type The type and flags for the new start position.
   * @param start The value of the new start position.
   * @param stop_type The type and flags for the new stop position.
   * @param stop The value of the new stop position.
   * @return <tt>true</tt> if the event was handled. Flushing seeks will trigger a
   * preroll, which will emit Gst::MESSAGE_ASYNC_DONE.
   */
  bool seek(double rate, Format format, SeekFlags flags, SeekType cur_type, gint64 cur, SeekType stop_type, gint64 stop);

  /** Sends an event to an element. If the element doesn't implement an event
   * handler, the event will be pushed on a random linked sink pad for upstream
   * events or a random linked source pad for downstream events.
   *
   * This function takes owership of the provided event.
   *
   * @param event The Gst::Event to send to the element.
   * @return true if the event was handled. MT safe. 
   */
  bool send_event(const Glib::RefPtr<Gst::Event>& event);
  

  /**
   * @par Slot Prototype:
   * <tt>void on_my_%no_more_pads()</tt>
   *
   * This signals that the element will not generate more dynamic pads.
   * Note that this signal will usually be emitted from the context of
   * the streaming thread.
   * 
   */

  Glib::SignalProxy0< void > signal_no_more_pads();


  /**
   * @par Slot Prototype:
   * <tt>void on_my_%pad_added(const Glib::RefPtr<Gst::Pad>& new_pad)</tt>
   *
   * a new Gst::Pad has been added to the element. Note that this signal will
   * usually be emitted from the context of the streaming thread. Also keep in
   * mind that if you add new elements to the pipeline in the signal handler
   * you will need to set them to the desired target state with
   * Gst::Element::set_state() or Gst::Element::sync_state_with_parent().
   * 
   * @param new_pad The pad that has been added.
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Gst::Pad>& > signal_pad_added();

  
  /**
   * @par Slot Prototype:
   * <tt>void on_my_%pad_removed(const Glib::RefPtr<Gst::Pad>& old_pad)</tt>
   *
   * a Gst::Pad has been removed from the element
   * 
   * @param old_pad The pad that has been removed.
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Gst::Pad>& > signal_pad_removed();


  /** Called when a request pad is to be released.
   */
    virtual void release_pad_vfunc(const Glib::RefPtr<Gst::Pad>& pad);


  /** Called when a new pad is requested.
   */
    virtual Glib::RefPtr<Gst::Pad> request_new_pad_vfunc(Glib::RefPtr<Gst::PadTemplate> templ, const Glib::ustring& name, const Glib::RefPtr<const Gst::Caps>& caps);


  /** Get the state of the element.
   */
    virtual StateChangeReturn get_state_vfunc(State& state, State& pending, ClockTime timeout) const;


  /** Set a new state on the element.
   */
    virtual StateChangeReturn set_state_vfunc(State state);


  /** Called by set_state to perform an incremental state change.
   */
    virtual StateChangeReturn change_state_vfunc(StateChange transition);


  /** Set a Gst::Bus on the element.
   */
    virtual void set_bus_vfunc(const Glib::RefPtr<Gst::Bus>& bus);


  /** Gets the Gst::Clock provided by the element.
   */
    virtual Glib::RefPtr<Gst::Clock> provide_clock_vfunc();


  // This vfunc is hand-coded because it is necessary for the callback to
  // return true instead of false (as would happen with the default gmmproc
  // callback) because GstElement does not set its set_clock() vfunc
  // by default and yet gst_element_set_clock() returns true when GstElement's
  // set_clock() vfunc is not set (it's a strange thing, but look at
  // gst_element_class_init() and gst_element_set_clock() for insight).
  /** Set the Gst::Clock on the element.
   */
  virtual bool set_clock_vfunc(const Glib::RefPtr<Gst::Clock>& clock);

 
  /** Send a Gst::Event to the element.
   */
    virtual bool send_event_vfunc(const Glib::RefPtr<Gst::Event>& event);


  /** Perform a Gst::Query on the element.
   */
    virtual bool query_vfunc(const Glib::RefPtr<Gst::Query>& query) const;


  /** Set a Gst::Context on the element
   */
    virtual void set_context_vfunc(const Glib::RefPtr<Gst::Context>& context);


  Glib::RefPtr<Gst::PadTemplate> get_pad_template(const Glib::ustring &factory_name) const;

  /**
   * Sets specified property. Allows to create property-chain
   * (e.g. element->property("location", "test.ogg")->property("num_buffers", 20);
   */
  template<typename T>
   Glib::RefPtr<Gst::Element> property(const Glib::ustring& name, const T& value)
   {
       set_property(name, value);
       return Glib::RefPtr<Gst::Element>( dynamic_cast<Gst::Element*> (Glib::wrap_auto ((GObject*)(gobj()), true)) );
   }

protected:

  
public:

public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::
  /// This is a default handler for the signal signal_no_more_pads().
  virtual void on_no_more_pads();
  /// This is a default handler for the signal signal_pad_added().
  virtual void on_pad_added(const Glib::RefPtr<Gst::Pad>& new_pad);
  /// This is a default handler for the signal signal_pad_removed().
  virtual void on_pad_removed(const Glib::RefPtr<Gst::Pad>& old_pad);


};

} // namespace Gst


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gst::Element
   */
  Glib::RefPtr<Gst::Element> wrap(GstElement* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_ELEMENT_H */

