/*  This file is part of the QbtGStreamer project, a Qt GStreamer Wrapper
    Copyright (C) 2006 Tim Beaulen <tbscope@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#ifndef QBTGSTREAMERBIN
#define QBTGSTREAMERBIN

#include "qbtgstreamerelement.h"
#include "qbtgstreamer_export.h"

#include <QString>
#include <QList>

#include <gst/gst.h>

class QbtGStreamerBinPrivate
{
public:
    QbtGStreamerBinPrivate()
        : //refCount(1),
          bin(0)
    {
    }

    //int refCount;
    GstBin *bin;
};

class QBTGSTREAMER_EXPORT QbtGStreamerBin : public QbtGStreamerElement
{
    friend class QbtGStreamerBinPrivate;

public:
    /*!
     \brief Create a new bin

     Creates a new bin with the given name.

     \param name The name of the bin.
    */
    QbtGStreamerBin(const QString &name = "");
    ~QbtGStreamerBin();

    /*!
     \brief Add an element to the bin

     Adds the given element to the bin. Sets the element's parent, and thus takes ownership of the element. Note that an element can only be added to one bin.

     If the element's pads are linked to other pads, the pads will be unlinked before the element is added to the bin.

     \param element The element to be added to this bin.

     \return True if the element could be added, false if the bin does not want to accept the element.
    */
    bool addElement(QbtGStreamerElement *element);

    /*!
     \brief Remove an element from the bin

     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 you want the element to still exist after removing, you need to call gst_object_ref() before 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.

     \param element The element to be removed from this bin.

     \return True if the element could be removed, false if the bin does not want to remove the element.
    */
    bool removeElement(QbtGStreamerElement *element);

    /*!
     \brief Get an element with a given name from the bin or the child bins.

     Gets the element with the given name from the bin. This function recurses into child bins. 
     Returns NULL if no element with the given name is found in the bin. 
     
     Multithread safe. Caller owns returned reference.

     \param name The element name to search for 

     \return The element with the given name, or NULL
    */
    QbtGStreamerElement *elementByName(const QString &name);

    /*!
     \brief Get an element with a given name from the bin or the parent bin.

     Gets the element with the given name from this bin. If the element is not found, a recursion is performed on the parent bin. 
     Returns NULL if no element with the given name is found in the bin. 
     
     Multithread safe. Caller owns returned reference.

     \param name The element name to search for 

     \return The element with the given name, or NULL
    */
    QbtGStreamerElement *elementByNameRecurseUp(const QString &name);

    /*!
     \brief Get an element with a given name from the bin or the child bins.

     Gets the element with the given name from the bin. This function recurses into child bins. 
     Returns NULL if no element with the given name is found in the bin. 
     
     Multithread safe. Caller owns returned reference.

     \param name The element name to search for 

     \return The element with the given name, or NULL
    */
    //QbtGStreamerElement *elementByInteface(int interface);

    QList<QbtGStreamerElement *> elements();

    GstBin *gstBin();
    void setGstBin(GstBin *bin);

private:
    QbtGStreamerBinPrivate *d;
};

#if 0
These are functions that still need to be added or checked!
-----------------------------------------------------------


GstElement* gst_bin_get_by_interface        (GstBin *bin,
                                             GType interface);
GstIterator* gst_bin_iterate_recurse        (GstBin *bin);
GstIterator* gst_bin_iterate_sinks          (GstBin *bin);
GstIterator* gst_bin_iterate_sorted         (GstBin *bin);
GstIterator* gst_bin_iterate_sources        (GstBin *bin);
GstIterator* gst_bin_iterate_all_by_interface
                                            (GstBin *bin,
                                             GType interface);

void        gst_bin_add_many                (GstBin *bin,
                                             GstElement *element_1,
                                             ...);
void        gst_bin_remove_many             (GstBin *bin,
                                             GstElement *element_1,
                                             ...);
GstPad*     gst_bin_find_unconnected_pad    (GstBin *bin,
                                             GstPadDirection direction);

enum        GstBinFlags;

#endif

#endif
