// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_CAPS_H
#define _GSTREAMERMM_CAPS_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/gstcaps.h>
#include <gstreamermm/structure.h>
#include <libxml++/nodes/node.h>


namespace Gst
{

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

/**
 * @ingroup gstreamermmEnums
 */
enum CapsIntersectMode
{
  CAPS_INTERSECT_ZIG_ZAG,
  CAPS_INTERSECT_FIRST
};


struct Structure;

/** A class that describes sets of media formats.
 * Caps (capabilities) are lightweight objects describing media formats. They
 * are composed of an array of Gst::Structure.
 *
 * Caps are exposed on Gst::PadTemplate to describe all possible types a given
 * pad can handle. They are also stored in the Gst::Registry along with a
 * description of the Gst::Element.
 *
 * Caps are exposed on the element pads using the Gst::Pad::get_caps() method.
 * This method describes the possible types that the pad can handle or produce
 * at runtime.
 *
 * Caps are also attached to buffers to describe to content of the data
 * pointed to by the buffer with Gst::Buffer::set_caps(). Gst::Caps attached
 * to a Gst::Buffer allow for format negotiation upstream and downstream.
 *
 * A Gst::Caps can be constructed with the following code fragment:
 *
 * @code
 * Glib::RefPtr<Gst::Caps> caps = Gst::Caps::create_simple("video/x-raw-yuv");
 * caps->set_simple("format", Gst::Fourcc('I', '4', '2', '0'));
 * caps->set_simple("framerate", Gst::Fraction(25, 1));
 * caps->set_simple("pixel-aspect-ratio", Gst::Fraction(1, 1));
 * caps->set_simple("width", 320);
 * caps->set_simple("height", 240);
 * @endcode
 */
class Caps 
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef Caps CppObjectType;
  typedef GstCaps BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  static Glib::RefPtr<Caps> create();

  /** Increment the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void reference()   const;

  /** Decrement the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void unreference() const;

  ///Provides access to the underlying C instance.
  GstCaps*       gobj();

  ///Provides access to the underlying C instance.
  const GstCaps* gobj() const;

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

protected:
  // Do not derive this.  Gst::Caps can neither be constructed nor deleted.
  Caps();
  void operator delete(void*, std::size_t);

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


public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type() G_GNUC_CONST;
#endif

public:
  /** Creates a new Gst::Caps that indicates that it is compatible with any
   * media format.
   *
   * @return The new Gst::Caps.
   */
  static Glib::RefPtr<Gst::Caps> create_any();

  /** Creates a new Gst::Caps that contains one Gst::Structure.
   *
   * @param media_type The media type of the structure.
   * @return The new Gst::Caps.
   */
  static Glib::RefPtr<Gst::Caps> create_simple(const Glib::ustring& media_type);

  /** Creates a new Gst::Caps and adds the given Gst::Structure.
   * Use append_structure() to add additional structures.
   *
   * @param first_struct The first structure to add.
   * @return Returns the new Gst::Caps.
   */
  static Glib::RefPtr<Gst::Caps> create(const Structure& first_struct);

  
  /** Converts @a caps from a string representation.
   * @param string A string to convert to Gst::Caps.
   * @return A newly allocated Gst::Caps.
   */
  static Glib::RefPtr<Gst::Caps> create_from_string(const Glib::ustring& string);

  
  /** Creates a new Gst::Caps as a copy of the old @a caps. The new caps will have a
   * refcount of 1, owned by the caller. The structures are copied as well.
   * 
   * Note that this function is the semantic equivalent of a ref()
   * followed by a make_writable(). If you only want to hold on to a
   * reference to the data, you should use ref().
   * 
   * When you are finished with the caps, call unref() on it.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> copy() const;
  
  /** Creates a new Gst::Caps and appends a copy of the nth structure
   * contained in @a caps.
   * @param nth The nth structure to copy.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> copy_nth(guint nth) const;
  
  /** Appends the structures contained in @a caps2 to @a caps1. The structures in
   *  @a caps2 are not copied -- they are transferred to @a caps1, and then @a caps2 is
   * freed. If either caps is ANY, the resulting caps will be ANY.
   * @param caps2 The Gst::Caps to append.
   */
  void append(const Glib::RefPtr<Gst::Caps>& caps);
  
  /** Appends the structures contained in @a caps2 to @a caps1 if they are not yet
   * expressed by @a caps1. The structures in @a caps2 are not copied -- they are
   * transferred to @a caps1, and then @a caps2 is freed.
   * If either caps is ANY, the resulting caps will be ANY.
   * @param caps2 The Gst::Caps to merge in.
   */
  void merge(const Glib::RefPtr<Gst::Caps>& caps);

  /** Appends a structure to caps.
   *
   * @param structure The Gst::Structure to append.
   */
  void append_structure(const Structure& structure);
  

  /** Appends a structure to caps if its not already expressed by caps.
   *
   * @param structure The Gst::Structure to merge.
   */
  void merge_structure(Structure& structure);
  

  /** Finds the structure in caps that has the index @a idx, and returns it.
   *
   * @param index The index of the structure.
   * @return The Gst::Structure corresponding to index.
   */
  const Structure get_structure(guint idx) const;

  
  /** removes the stucture with the given index from the list of structures
   * contained in @a caps.
   * @param idx Index of the structure to remove.
   */
  void remove_structure(guint idx);
  
  /** Gets the number of structures contained in @a caps.
   * @return The number of structures that @a caps contains.
   */
  guint size() const;

// There's no need to take an extra reference because we are stealing the
// structure.
 

  /** Retrieves the stucture with the given index from the list of structures
   * contained in @a caps. The caller becomes the owner of the returned structure.
   * @param index Index of the structure to retrieve.
   * @return A pointer to the Gst::Structure corresponding
   * to @a index.
   */
  Structure steal_structure(guint index);

  /** Sets fields in a simple Gst::Caps. A simple Gst::Caps is one that only
   * has one structure. This method, like the Gst::Structure::set_field()
   * methods, translates certain GTypes to GStreamer specific GTypes for
   * functional compatibility.
   *
   * @param name Field to set.
   * @param value The value which the field should be set to.
   */
  void set_simple(const Glib::ustring& name, const Glib::ValueBase& value);
  

  /** Sets fields in a simple Gst::Caps. A simple Gst::Caps is one that only
   * has one structure. This method, like the Gst::Structure::set_field()
   * methods, translates certain GTypes to GStreamer specific GTypes for
   * functional compatibility.
   *
   * @param name Field to set.
   * @param data A value which the field should be set to (this can be any
   * supported C++ type).
   */
  template <class DataType>
  void set_simple(const Glib::ustring& name, const DataType& data);

  /** Sets fields in a simple Gst::Caps. A simple Gst::Caps is one that only
   * has one structure.
   *
   * @param name Field to set.
   * @param data A C string (const char*) which the field should be set to.
   */
  void set_simple(const Glib::ustring& name, const char* data);

  
  /** Sets the given @a field on all structures of @a caps to the given @a value.
   * This is a convenience function for calling Gst::Structure::set_value() on
   * all structures of @a caps.
   * @param field Name of the field to set.
   * @param value Value to set the field to.
   */
  void set_value(const Glib::ustring& field, const Glib::ValueBase& value);

  /** Sets the given @a field on all structures to the given value. This is a
   * convenience function for calling Gst::Structure::set_value()  on all
   * structures.
   *
   * @param name Field to set.
   * @param data A value which the field should be set to (this can be any
   * supported C++ type).
   */
  template <class DataType>
  void set_value(const Glib::ustring& name, const DataType& data);

  
  /** Determines if @a caps represents any media format.
   * @return <tt>true</tt> if @a caps represents any format.
   */
  bool is_any() const;
  
  /** Determines if @a caps represents no media formats.
   * @return <tt>true</tt> if @a caps represents no formats.
   */
  bool empty() const;
  
  /** Fixed Gst::Caps describe exactly one format, that is, they have exactly
   * one structure, and each field in the structure describes a fixed type.
   * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
   * @return <tt>true</tt> if @a caps is fixed.
   */
  bool is_fixed() const;
  
  /** Checks if the given caps represent the same set of caps.
   * <note>This function does not work reliably if optional properties for caps
   * are included on one caps and omitted on the other.</note>
   * 
   * This function deals correctly with passing <tt>0</tt> for any of the caps.
   * @param caps2 Another Gst::Caps.
   * @return <tt>true</tt> if both caps are equal.
   */
  bool equals(const Glib::RefPtr<const Gst::Caps>& other_caps) const;
  
  /** Tests if two Gst::Caps are equal.  This function only works on fixed
   * Gst::Caps.
   * @param caps2 The Gst::Caps to test.
   * @return <tt>true</tt> if the arguments represent the same format.
   */
  bool equals_fixed(const Glib::RefPtr<const Gst::Caps>& other_caps) const;
  
  /** A given Gst::Caps structure is always compatible with another if
   * every media format that is in the first is also contained in the
   * second.  That is, @a caps1 is a subset of @a caps2.
   * @param caps2 The Gst::Caps to test.
   * @return <tt>true</tt> if @a caps1 is a subset of @a caps2.
   */
  bool is_always_compatible(const Glib::RefPtr<const Gst::Caps>& other_caps) const;
  
  /** Checks if all caps represented by @a subset are also represented by @a superset.
   * <note>This function does not work reliably if optional properties for caps
   * are included on one caps and omitted on the other.</note>
   * @param superset A potentially greater Gst::Caps.
   * @return <tt>true</tt> if @a subset is a subset of @a superset.
   */
  bool is_subset(const Glib::RefPtr<const Gst::Caps>& superset_caps) const;
  
  /** Tries intersecting @a caps1 and @a caps2 and reports whether the result would not
   * be empty
   * @param caps2 A Gst::Caps to intersect.
   * @return <tt>true</tt> if intersection would be not empty.
   */
  bool can_intersect(const Glib::RefPtr<const Gst::Caps>& caps2) const;

  //This is const (returns a non const) because it always creates a new instance:
  
  /** Creates a new Gst::Caps that contains all the formats that are common
   * to both @a caps1 and @a caps2. Defaults to Gst::CAPS_INTERSECT_ZIG_ZAG mode.
   * @param caps2 A Gst::Caps to intersect.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> get_intersect(const Glib::RefPtr<const Gst::Caps>& other_caps) const;

  //This is const (returns a non const) because it always creates a new instance:
  
  /** Creates a new Gst::Caps that contains all the formats that are common
   * to both @a caps1 and @a caps2, the order is defined by the Gst::CapsIntersectMode
   * used.
   * @param caps2 A Gst::Caps to intersect.
   * @param mode The intersection algorithm/mode to use.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> get_intersect(const Glib::RefPtr<const Gst::Caps>& other_caps, CapsIntersectMode p2) const;

  //This is const (returns a non const) because it always creates a new instance:
  
  /** Creates a new Gst::Caps that contains all the formats that are in
   * either @a caps1 and @a caps2.
   * @param caps2 A Gst::Caps to union.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> get_union(const Glib::RefPtr<const Gst::Caps>& other_caps) const;

  //This is const (returns a non const) because it always creates a new instance:
  
  /** Creates a new Gst::Caps that represents the same set of formats as
   *  @a caps, but contains no lists.  Each list is expanded into separate
   *  @a GstStructures.
   * @return The new Gst::Caps.
   */
  Glib::RefPtr<Gst::Caps> get_normal() const;

  
  /** Modifies the given @a caps inplace into a representation that represents the
   * same set of formats, but in a simpler form.  Component structures that are
   * identical are merged.  Component structures that have values that can be
   * merged are also merged.
   * @return <tt>true</tt>, if the caps could be simplified.
   */
  bool simplify();

  /** Serializes a Gst::Caps to XML and adds it as a child node of @a parent.
   * @param parent A XML parent node.
   * @return The parent XML Node.
   */
  xmlpp::Node* save(xmlpp::Node* parent) const;
  

  /** Creates a Gst::Caps from its XML serialization.
   * @param parent A XML node.
   * @return A new Gst::Caps structure.
   */
  static Glib::RefPtr<Gst::Caps> load(xmlpp::Node* parent);

  
  /** Converts @a caps to a string representation.  This string representation
   * can be converted back to a Gst::Caps by from_string().
   * 
   * For debugging purposes its easier to do something like this:
   * 
   * [C example ellipted]
   * This prints the caps in human readble form.
   * @return A newly allocated string representing @a caps.
   */
  Glib::ustring to_string() const;

  //This is const (returns a non const) because it always creates a new instance:
  
  /** Subtracts the @a subtrahend from the @a minuend.
   * <note>This function does not work reliably if optional properties for caps
   * are included on one caps and omitted on the other.</note>
   * @param subtrahend Gst::Caps to subtract.
   * @return The resulting caps.
   */
  Glib::RefPtr<Gst::Caps> get_difference(const Glib::RefPtr<const Gst::Caps>& subtrahend_caps) const;

  
  /** Returns a writable copy of @a caps.
   * 
   * If there is only one reference count on @a caps, the caller must be the owner,
   * and so this function will return the caps object unchanged. If on the other
   * hand there is more than one reference on the object, a new caps object will
   * be returned. The caller's reference on @a caps will be removed, and instead the
   * caller will own a reference to the returned object.
   * 
   * In short, this function unrefs the caps in the argument and refs the caps
   * that it returns. Don't access the argument after calling this function. See
   * also: ref().
   * @return The same Gst::Caps object.
   */
  Glib::RefPtr<Gst::Caps> create_writable();
  
  /** Destructively discard all but the first structure from @a caps. Useful when
   * fixating. @a caps must be writable.
   */
  void truncate();


};

/******************************* Gst::Caps *******************************/

#ifndef DOXYGEN_SHOULD_SKIP_THIS

template <class DataType>
void Caps::set_simple(const Glib::ustring& name, const DataType& data)
{
  typedef Glib::Value<DataType> ValueType;

  ValueType value;
  value.init(ValueType::value_type());
  value.set(data);
  this->set_simple(name, reinterpret_cast<Glib::ValueBase&>(value));
}

template <class DataType>
void Caps::set_value(const Glib::ustring& name, const DataType& data)
{
  typedef Glib::Value<DataType> ValueType;

  ValueType value;
  value.init(ValueType::value_type());
  value.set(data);
  this->set_value(name, reinterpret_cast<Glib::ValueBase&>(value));
}

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

} //namespace Gst

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value< Glib::RefPtr<Gst::Caps> > : public ValueBase_Boxed
{
public:
  static GType value_type() { return Gst::Caps::get_type(); }
  void set(const Glib::RefPtr<Gst::Caps>& caps) { set_boxed(Glib::unwrap(caps)); }
  Glib::RefPtr<Gst::Caps> get()                 { return Glib::RefPtr<Gst::Caps>(reinterpret_cast<Gst::Caps*>(get_boxed())); }
};

}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


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

} // namespace Glib


#endif /* _GSTREAMERMM_CAPS_H */

