// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_BIN_H
#define _GSTREAMERMM_BIN_H


#include <glibmm.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 <gstreamermm/element.h>
#include <gstreamermm/childproxy.h>
#include <gstreamermm/pad.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstBin GstBin;
typedef struct _GstBinClass GstBinClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Bin_Class; } // namespace Gst
namespace Gst
{

class Pad;
class GhostPad;

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

/** A base class and element that can contain other elements.
 * Gst::Bin is an element that can contain other Gst::Element, allowing them to
 * be managed as a group. Pads from the child elements can be ghosted to the
 * bin, see Gst::GhostPad. This makes the bin look like any other elements and
 * enables creation of higher-level abstraction elements.
 *
 * A new Gst::Bin is created with create(). Use a Gst::Pipeline instead if you
 * want to create a toplevel bin because a normal bin doesn't have a bus or
 * handle clock distribution of its own.
 *
 * After the bin has been created you will typically add elements to it with
 * add(). You can remove elements with remove().
 *
 * An element can be retrieved from a bin with get_element(), using the
 * elements name. get_element_recurse_up() is mainly used for internal purposes
 * and will query the parent bins when the element is not found in the current
 * bin.
 *
 * An iterator of elements in a bin can be retrieved with iterate_elements().
 * Various other iterators exist to retrieve the elements in a bin.
 *
 * The element-added signal is fired whenever a new element is added to the
 * bin. Likewise the element-removed signal is fired whenever an element is
 * removed from the bin.
 *
 * Notes:
 *
 * A Gst::Bin internally intercepts every Gst::Message posted by its children
 * and implements the following default behaviour for each of them:
 *
 * - Gst::MESSAGE_EOS - This message is only posted by sinks in the PLAYING
 * state. If all sinks posted the EOS message, this bin will post and EOS
 * message upwards.
 *
 * - Gst::MESSAGE_SEGMENT_START - just collected and never forwarded upwards.
 * The messages are used to decide when all elements have completed playback of
 * their segment.
 *
 * - Gst::MESSAGE_SEGMENT_DONE - Is posted by Gst::Bin when all elements that
 * posted a Gst::MESSAGE_SEGMENT_START have posted a Gst::MESSAGE_SEGMENT_DONE.
 *
 * - Gst::MESSAGE_DURATION - Is posted by an element that detected a change in
 * the stream duration. The default bin behaviour is to clear any cached
 * duration values so that the next duration query will perform a full duration
 * recalculation. The duration change is posted to the application so that it
 * can refetch the new duration with a duration query.
 *
 * - Gst::MESSAGE_CLOCK_LOST - This message is posted by an element when it can
 * no longer provide a clock. The default bin behaviour is to check if the lost
 * clock was the one provided by the bin. If so and the bin is currently in the
 * PLAYING state, the message is forwarded to the bin parent. This message is
 * also generated when a clock provider is removed from the bin. If this
 * message is received by the application, it should PAUSE the pipeline and set
 * it back to PLAYING to force a new clock distribution.
 *
 * - Gst::MESSAGE_CLOCK_PROVIDE - This message is generated when an element can
 * provide a clock. This mostly happens when a new clock provider is added to
 * the bin. The default behaviour of the bin is to mark the currently selected
 * clock as dirty, which will perform a clock recalculation the next time the
 * bin is asked to provide a clock. This message is never sent tot the
 * application but is forwarded to the parent of the bin.
 *
 * - OTHERS - posted upwards.
 *
 * A Gst::Bin implements the following default behaviour for answering to a
 * Gst::Query:
 *
 * - Gst::QUERY_DURATION - If the query has been asked before with the same
 * format and the bin is a toplevel bin (ie. has no parent), use the cached
 * previous value. If no previous value was cached, the query is sent to all
 * sink elements in the bin and the MAXIMUM of all values is returned. If the
 * bin is a toplevel bin the value is cached. If no sinks are available in the
 * bin, the query fails.
 *
 * - Gst::QUERY_POSITION - The query is sent to all sink elements in the bin
 * and the MAXIMUM of all values is returned. If no sinks are available in the
 * bin, the query fails.
 *
 * - OTHERS - the query is forwarded to all sink elements, the result of the
 * first sink that answers the query successfully is returned. If no sink is in
 * the bin, the query fails.
 *
 * A Gst::Bin will by default forward any event sent to it to all sink
 * elements. If all the sinks return true, the bin will also return true, else
 * false is returned. If no sinks are in the bin, the event handler will return
 * true.
 *
 * Last reviewed on 2006-04-28 (0.10.6)
 * @ingroup GstBaseClasses
 */

class Bin
: public Element,
  public ChildProxy
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Bin CppObjectType;
  typedef Bin_Class CppClassType;
  typedef GstBin BaseObjectType;
  typedef GstBinClass BaseClassType;

private:  friend class Bin_Class;
  static CppClassType bin_class_;

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

protected:
  explicit Bin(const Glib::ConstructParams& construct_params);
  explicit Bin(GstBin* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Bin();

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

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

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

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

private:

  
protected:
  explicit Bin(const Glib::ustring& name);
  Bin();

public:
  /** Creates a new bin with the given name.
   *
   * @param name The name of the new bin.
   * @return A new Gst::Bin.
   */
  
  static Glib::RefPtr<Bin> create(const Glib::ustring& name);


  /** Creates a new bin with a unique generic name.
   *
   * @return A new Gst::Bin.
   */
   
  static Glib::RefPtr<Bin> create();


  /** Adds the given element to the bin.
   * This sets the element's parent, and thus takes ownership of the element.
   * An element can only be added to one bin.
   *
   * If the element's pads are linked to other pads then the pads will be
   * unlinked before the element is added to the bin.
   *
   * MT safe.
   *
   * @param element The Gst::Element to add.
   * @return This Gst::Bin if successful, for chained calls to add().
   *
   * @throws std::runtime_error if the Bin does not want to accept the Element.
   */
  Glib::RefPtr<Gst::Bin> add(const Glib::RefPtr<Gst::Element>& element);
  

  /** Removes the element from the bin, unparenting it as well. Unparenting the
   * element means that the element will be dereferenced, so if the bin holds
   * the only reference to the element, the element will be freed in the
   * process of removing it from the bin.
   *
   * If the element's pads are linked to other pads, the pads will be unlinked
   * before the element is removed from the bin.
   *
   * MT safe.
   *
   * element the Gst::Element to remove
   * Returns this Gst::Bin if successful, for chained calls to remove().
   *
   * @throws std::runtime_error if the Bin does not want to remove the Element.
   */
  Glib::RefPtr<Gst::Bin> remove(const Glib::RefPtr<Gst::Element>& element);
  

  //We could add a bool recurse_up = false parameter, 
  //but get_element() and get_element_recurse_up() seem different enough to be separate.
  //One recurses down and the other recurses up, so it's not just additional behaviour. 
  
  /** Gets the element with the given name from a bin. This
   * function recurses into child bins.
   * @param name The element name to search for.
   * @return The Gst::Element with the given name, or <tt>0</tt>.
   */
  Glib::RefPtr<Gst::Element> get_element(const Glib::ustring& name);
  
  /** Gets the element with the given name from a bin. This
   * function recurses into child bins.
   * @param name The element name to search for.
   * @return The Gst::Element with the given name, or <tt>0</tt>.
   */
  Glib::RefPtr<const Gst::Element> get_element(const Glib::ustring& name) const;

  
  /** Gets the element with the given name from this bin. If the
   * element is not found, a recursion is performed on the parent bin.
   * @param name The element name to search for.
   * @return The Gst::Element with the given name, or <tt>0</tt>.
   */
  Glib::RefPtr<Gst::Element> get_element_recurse_up(const Glib::ustring& name);
  
  /** Gets the element with the given name from this bin. If the
   * element is not found, a recursion is performed on the parent bin.
   * @param name The element name to search for.
   * @return The Gst::Element with the given name, or <tt>0</tt>.
   */
  Glib::RefPtr<const Gst::Element> get_element_recurse_up(const Glib::ustring& name) const;
 
  
  /** Looks for an element inside the bin that implements the given
   * interface. If such an element is found, it returns the element.
   * You can cast this element to the given interface afterwards.  If you want
   * all elements that implement the interface, use
   * iterate_all_by_interface(). This function recurses into child bins.
   * 
   * MT safe.  Caller owns returned reference.
   * @param iface The Type of an interface.
   * @return A Gst::Element inside the bin implementing the interface.
   */
  Glib::RefPtr<Gst::Element> get_element(GType interface);
  
  /** Looks for an element inside the bin that implements the given
   * interface. If such an element is found, it returns the element.
   * You can cast this element to the given interface afterwards.  If you want
   * all elements that implement the interface, use
   * iterate_all_by_interface(). This function recurses into child bins.
   * 
   * MT safe.  Caller owns returned reference.
   * @param iface The Type of an interface.
   * @return A Gst::Element inside the bin implementing the interface.
   */
  Glib::RefPtr<const Gst::Element> get_element(GType interface) const;

  /** Adds a ghost pad to the bin using an element's static pad as a target.
   * @param element The element with the target static pad.
   * @param pad_name The static pad to use as the target.
   * @param name An optional name for the ghost pad.
   * @return The newly created Gst::GhostPad.
   */
  Glib::RefPtr<Gst::GhostPad> add_ghost_pad(const Glib::RefPtr<Gst::Element>&
    element, const Glib::ustring& pad_name, const Glib::ustring& name =
    Glib::ustring());

  
  /** Recursively looks for elements with an unlinked pad of the given
   * direction within the specified bin and returns an unlinked pad
   * if one is found, or <tt>0</tt> otherwise. If a pad is found, the caller
   * owns a reference to it and should use Gst::Object::unref() on the
   * pad when it is not needed any longer.
   * 
   * @newin{0,10}.20
   * @param direction Whether to look for an unlinked source or sink pad.
   * @return Unlinked pad of the given direction, or <tt>0</tt>.
   */
  Glib::RefPtr<Gst::Pad> find_unlinked_pad(PadDirection dir);
  
  /** Recursively looks for elements with an unlinked pad of the given
   * direction within the specified bin and returns an unlinked pad
   * if one is found, or <tt>0</tt> otherwise. If a pad is found, the caller
   * owns a reference to it and should use Gst::Object::unref() on the
   * pad when it is not needed any longer.
   * 
   * @newin{0,10}.20
   * @param direction Whether to look for an unlinked source or sink pad.
   * @return Unlinked pad of the given direction, or <tt>0</tt>.
   */
  Glib::RefPtr<const Gst::Pad> find_unlinked_pad(PadDirection dir) const;
  

  /** Gets an iterator for the elements in this bin.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_elements();
  
  /** Gets an iterator for the elements in this bin.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_elements() const;
  
  /** Gets an iterator for the elements in this bin.
   * This iterator recurses into GstBin children.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_recurse();
  
  /** Gets an iterator for the elements in this bin.
   * This iterator recurses into GstBin children.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_recurse() const;
  
  /** Gets an iterator for the elements in this bin in topologically
   * sorted order. This means that the elements are returned from
   * the most downstream elements (sinks) to the sources.
   * 
   * This function is used internally to perform the state changes
   * of the bin elements and for clock selection.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_sorted();
  
  /** Gets an iterator for the elements in this bin in topologically
   * sorted order. This means that the elements are returned from
   * the most downstream elements (sinks) to the sources.
   * 
   * This function is used internally to perform the state changes
   * of the bin elements and for clock selection.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_sorted() const;
  
  /** Gets an iterator for all elements in the bin that have no sinkpads and have
   * the Gst::ELEMENT_IS_SINK flag unset.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_sources();
  
  /** Gets an iterator for all elements in the bin that have no sinkpads and have
   * the Gst::ELEMENT_IS_SINK flag unset.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_sources() const;
  
  /** Gets an iterator for all elements in the bin that have the
   * Gst::ELEMENT_IS_SINK flag set.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_sinks();
  
  /** Gets an iterator for all elements in the bin that have the
   * Gst::ELEMENT_IS_SINK flag set.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @return A Gst::Iterator of Gst::Element, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_sinks() const;
  
  /** Looks for all elements inside the bin that implements the given
   * interface. You can safely cast all returned elements to the given interface.
   * The function recurses inside child bins. The iterator will yield a series
   * of Gst::Element that should be unreffed after use.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @param iface The Type of an interface.
   * @return A Gst::Iterator of Gst::Element for all elements in the bin
   * implementing the given interface, or <tt>0</tt>.
   */
  Gst::Iterator<Gst::Element> iterate_by_interface(GType iface);
  
  /** Looks for all elements inside the bin that implements the given
   * interface. You can safely cast all returned elements to the given interface.
   * The function recurses inside child bins. The iterator will yield a series
   * of Gst::Element that should be unreffed after use.
   * 
   * Each element yielded by the iterator will have its refcount increased, so
   * unref after use.
   * 
   * MT safe.  Caller owns returned value.
   * @param iface The Type of an interface.
   * @return A Gst::Iterator of Gst::Element for all elements in the bin
   * implementing the given interface, or <tt>0</tt>.
   */
  Gst::Iterator<const Gst::Element> iterate_by_interface(GType iface) const;

  
  /** Query @a bin for the current latency using and reconfigures this latency to all the
   * elements with a LATENCY event.
   * 
   * This method is typically called on the pipeline when a Gst::MESSAGE_LATENCY
   * is posted on the bus.
   * 
   * This function simply emits the 'do-latency' signal so any custom latency
   * calculations will be performed.
   * 
   * @newin{0,10}.22.
   * @return <tt>true</tt> if the latency could be queried and reconfigured.
   */
  bool recalculate_latency();

 
  /** Gets the bin's list of children.
   */
   Glib::ListHandle< Glib::RefPtr<Gst::Element> > get_children() const;
 
  /** Gets the number of children in the bin.
   */
   int get_num_children() const;
 
 
  /** Will be emitted after the element was added to the bin.
   *
   * @par Prototype:
   * <tt>void on_my_%element_added(const Glib::RefPtr<Gst::Element>& element)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Gst::Element>& > signal_element_added();


  /** Will be emitted after the element was removed from the bin.
   *
   * @par Prototype:
   * <tt>void on_my_%element_removed(const Glib::RefPtr<Gst::Element>& element)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Gst::Element>& > signal_element_removed();


  //TODO: The default signal handler is marked as private in the C header. Is that intendend?
  
  /**
   * @par Prototype:
   * <tt>bool on_my_%do_latency()</tt>
   */

  Glib::SignalProxy0< bool > signal_do_latency();


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The bin will handle Asynchronous state changes.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_async_handling() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The bin will handle Asynchronous state changes.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_async_handling() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  /** Method to add an element to a bin.
   */
    virtual bool add_element_vfunc(const Glib::RefPtr<Gst::Element>& element);


  /** Method to remove an element from a bin.
   */
    virtual bool remove_element_vfunc(const Glib::RefPtr<Gst::Element>& element);


  /** Method to handle a message from the children.
   */
    virtual void handle_message_vfunc(const Glib::RefPtr<Gst::Message>& message);


public:

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

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

  //Default Signal Handlers::
  virtual void on_element_added(const Glib::RefPtr<Gst::Element>& element);
  virtual void on_element_removed(const Glib::RefPtr<Gst::Element>& element);
  virtual bool on_do_latency();


};

} //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::Bin
   */
  Glib::RefPtr<Gst::Bin> wrap(GstBin* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_BIN_H */

