// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_INDEX_H
#define _GSTREAMERMM_INDEX_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/gstindex.h>
#include <gstreamermm/object.h>
#include <gstreamermm/format.h>
#include <glibmm/arrayhandle.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstIndex GstIndex;
typedef struct _GstIndexClass GstIndexClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Index_Class; } // namespace Gst
namespace Gst
{

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

/**
 * @ingroup gstreamermmEnums
 */
enum IndexCertainty
{
  INDEX_UNKNOWN,
  INDEX_CERTAIN,
  INDEX_FUZZY
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 */
enum IndexEntryType
{
  INDEX_ENTRY_ID,
  INDEX_ENTRY_ASSOCIATION,
  INDEX_ENTRY_OBJECT,
  INDEX_ENTRY_FORMAT
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 */
enum IndexLookupMethod
{
  INDEX_LOOKUP_EXACT,
  INDEX_LOOKUP_BEFORE,
  INDEX_LOOKUP_AFTER
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%AssocFlags operator|(AssocFlags, AssocFlags)</tt><br>
 * <tt>%AssocFlags operator&(AssocFlags, AssocFlags)</tt><br>
 * <tt>%AssocFlags operator^(AssocFlags, AssocFlags)</tt><br>
 * <tt>%AssocFlags operator~(AssocFlags)</tt><br>
 * <tt>%AssocFlags& operator|=(AssocFlags&, AssocFlags)</tt><br>
 * <tt>%AssocFlags& operator&=(AssocFlags&, AssocFlags)</tt><br>
 * <tt>%AssocFlags& operator^=(AssocFlags&, AssocFlags)</tt><br>
 */
enum AssocFlags
{
  ASSOCIATION_FLAG_NONE = 0x0,
  ASSOCIATION_FLAG_KEY_UNIT = (1 << 0),
  ASSOCIATION_FLAG_DELTA_UNIT = (1 << 1),
  ASSOCIATION_FLAG_LAST = (1 << 8)
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 */
enum IndexResolverMethod
{
  INDEX_RESOLVER_CUSTOM,
  INDEX_RESOLVER_GTYPE,
  INDEX_RESOLVER_PATH
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%IndexFlags operator|(IndexFlags, IndexFlags)</tt><br>
 * <tt>%IndexFlags operator&(IndexFlags, IndexFlags)</tt><br>
 * <tt>%IndexFlags operator^(IndexFlags, IndexFlags)</tt><br>
 * <tt>%IndexFlags operator~(IndexFlags)</tt><br>
 * <tt>%IndexFlags& operator|=(IndexFlags&, IndexFlags)</tt><br>
 * <tt>%IndexFlags& operator&=(IndexFlags&, IndexFlags)</tt><br>
 * <tt>%IndexFlags& operator^=(IndexFlags&, IndexFlags)</tt><br>
 */
enum IndexFlags
{
  INDEX_WRITABLE = (GST_OBJECT_FLAG_LAST << 0),
  INDEX_READABLE = (GST_OBJECT_FLAG_LAST << 1),
  INDEX_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 8)
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{


/** The basic element of an index.
 */
class IndexEntry
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef IndexEntry CppObjectType;
  typedef GstIndexEntry BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  IndexEntry();

  // Use make_a_copy=true when getting it directly from a struct.
  explicit IndexEntry(GstIndexEntry* castitem, bool make_a_copy = false);

  IndexEntry(const IndexEntry& src);
  IndexEntry& operator=(const IndexEntry& src);

  ~IndexEntry();

  GstIndexEntry*       gobj()       { return gobject_; }
  const GstIndexEntry* gobj() const { return gobject_; }

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

protected:
  GstIndexEntry* gobject_;

private:

public:
  
  /** Gets alternative formats associated with the indexentry.
   * @param format The format of the value the find.
   * @param value A pointer to store the value.
   * @return <tt>true</tt> if there was a value associated with the given
   * format.
   */
  bool assoc_map(Format format, gint64& value) const;


};

/** An association in an entry.
 */
class IndexAssociation
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef IndexAssociation CppObjectType;
  typedef GstIndexAssociation BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

private:


public:
  /// Default constructor
  IndexAssociation();

  /** Constructs a Gst::IndexAssociation from a C GstIndexAssociation type.
   * The @a castitem is left unaffected; its contents are simply copied.
   * @param castitem The GstIndexAssociation to copy contents from.
   */
   explicit IndexAssociation(const GstIndexAssociation* castitem);

  /// The format of the association.
  Gst::Format format;

  /// The value of the association
  gint64 value;


};


/** A class that generates a stream index of one or more elements in a
 * pipeline.
 */

class Index : public Object 
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Index CppObjectType;
  typedef Index_Class CppClassType;
  typedef GstIndex BaseObjectType;
  typedef GstIndexClass BaseClassType;

private:  friend class Index_Class;
  static CppClassType index_class_;

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

protected:
  explicit Index(const Glib::ConstructParams& construct_params);
  explicit Index(GstIndex* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Index();

#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.
  GstIndex*       gobj()       { return reinterpret_cast<GstIndex*>(gobject_); }

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

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

private:


protected:
  Index();

public:
  /** For example,
   * bool on_filter(const Glib::RefPtr<Gst::Index>& index, Gst::IndexEntry
   * entry);.
   * The filter function should return true if the entry is to be added to the
   * index, false otherwise.
   */ 
  typedef sigc::slot<bool, const Glib::RefPtr<Gst::Index>&, Gst::IndexEntry> SlotFilter;

  /** For example,
   * bool on_resolve(const Glib::RefPtr<Gst::Object>& writer, Glib::ustring&
   * writer_string);.
   * The resolve function should return true if an id could be assigned to
   * writer.
   */ 
  typedef sigc::slot<bool, const Glib::RefPtr<Gst::Index>&, const Glib::RefPtr<Gst::Object>&, Glib::ustring&> SlotResolver;

  /** Check if the index can be read from.
   * @return true if index is readable, false otherwise.
   */
  bool is_readable() const;

  /** Check if the index can be written to.
   * @return true if index is writable, false otherwise.
   */
  bool is_writable() const;

  
  /** Tell the index that the writer with the given id is done
   * with this index and is not going to write any more entries
   * to it.
   * @param id The writer that commited the index.
   */
  void commit(int id);
  
  /** Get the id of the current group.
   * @return The id of the current group.
   */
  int get_group() const;
  
  /** Create a new group for the given index. It will be
   * set as the current group.
   * @return The id of the newly created group.
   */
  int new_group();
  
  /** Set the current groupnumber to the given argument.
   * @param groupnum The groupnumber to set.
   * @return <tt>true</tt> if the operation succeeded, <tt>false</tt> if the group
   * did not exist.
   */
  bool set_group(int group_number);
  
  /** Set the certainty of the given index.
   * @param certainty The certainty to set.
   */
  void set_certainty(IndexCertainty certainty);
  
  /** Get the certainty of the given index.
   * @return The certainty of the index.
   */
  IndexCertainty get_certainty() const;
  
  /** Before entries can be added to the index, a writer
   * should obtain a unique id. The methods to add new entries
   * to the index require this id as an argument.
   * 
   * The application can implement a custom function to map the writer object
   * to a string. That string will be used to register or look up an id
   * in the index.
   * 
   * <note>
   * The caller must not hold @a writer's Gst::OBJECT_LOCK, as the default
   * resolver may call functions that take the object lock as well, and
   * the lock is not recursive.
   * </note>
   * @param writer The GstObject to allocate an id for.
   * @param id A pointer to a <tt>int</tt> to hold the id.
   * @return <tt>true</tt> if the writer would be mapped to an id.
   */
  bool get_writer_id(const Glib::RefPtr<Gst::Object>& writer, int& id) const;

// This conversion is used for next few add* methods (add_format,
// add_association, etc.).  A copy is taken so the original is not freed by the
// wrapper.
 

  /** Adds a format entry into the index. This function is
   * used to map dynamic GstFormat ids to their original
   * format key.
   * 
   * Free-function: gst_index_entry_free
   * @param id The id of the index writer.
   * @param format The format to add to the index.
   * @return A pointer to the newly added entry in the index.
   */
  Gst::IndexEntry add_format(int id, Format format);

 
  /** Associate given format/value pairs with each other.
   * @param id The id of the index writer.
   * @param flags Optinal flags for this entry.
   * @param n Number of associations.
   * @param list List of associations.
   * @return A pointer to the newly added entry in the index.
   */
  Gst::IndexEntry add_association(int id, AssocFlags flags, int n, const Glib::ArrayHandle<const Gst::IndexAssociation>& list);

  
  /** Add an id entry into the index.
   * @param id The id of the index writer.
   * @param description The description of the index writer.
   * @return A pointer to the newly added entry in the index.
   */
  Gst::IndexEntry add_id(int id, const Glib::ustring& description);

  /** Finds the given format/value in the index.
   *
   * @param id The id of the index writer.
   * @param value The value to find.
   * @param method The lookup method to use.
   * @param flags Flags for the entry.
   * @param format The format of the value.
   * @return The entry associated with the value or 0 if the value was not
   * found. 
   */
  Gst::IndexEntry get_assoc_entry(int id, gint64 value,
    IndexLookupMethod method = Gst::INDEX_LOOKUP_EXACT,
    AssocFlags flags = Gst::ASSOCIATION_FLAG_NONE,
    Format format = Gst::FORMAT_DEFAULT) const;

  /** Lets the app register a custom filter slot so that it can select what
   * entries should be stored in the index.
   *
   * @param slot The filter slot to register.
   */
  void set_filter(const SlotFilter& slot);

  /** Lets the app register a custom slot to map index ids to writer
   * descriptions.
   * @param slot The resolver slot to register.
   */
  void set_resolver(const SlotResolver& slot);

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Select a predefined object to string mapper.
   *
   * 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< Gst::Index::SlotResolver > property_resolver() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Select a predefined object to string mapper.
   *
   * 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< Gst::Index::SlotResolver > property_resolver() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  /** Emitted when a new entry is added to the index.
   *
* @par Slot Prototype:
   * <tt>void on_my_%entry_added(const Gst::IndexEntry& entry)</tt>
   *
   */

  Glib::SignalProxy1< void,const Gst::IndexEntry& > signal_entry_added();


    virtual bool get_writer_id_vfunc(int& writer_id, const Glib::ustring& writer_string) const;


    virtual void commit_vfunc(gint id);


  virtual void add_entry_vfunc(Gst::IndexEntry& entry);

  //TODO: Leave this vfunc for later because it is not absolutely necessary
  //right now.
  //_WRAP_VFUNC(void get_assoc_entry(Gst::LookupMethod method, Gst::AssocFlags flags, Gst::Format format, gint64 value, const SlotCompareData& compare_slot), "get_assoc_entry")

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_entry_added().
  virtual void on_entry_added(const Gst::IndexEntry& entry);


};

} //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::IndexEntry
   */
Gst::IndexEntry wrap(GstIndexEntry* object, bool take_copy = false);

} // namespace Glib


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


#endif /* _GSTREAMERMM_INDEX_H */

