// Generated by gmmproc 2.50.1 -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_STRUCTURE_H
#define _GSTREAMERMM_STRUCTURE_H


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

/* gstreamermm - a C++ wrapper for gstreamer
 *
 * Copyright 2008-2016 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/clock.h>
#include <gstreamermm/enums.h>
#include <gstreamermm/value.h>
#include <glibmm/date.h>
#include <glibmm/datetime.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
extern "C" { typedef struct _GstStructure GstStructure; }
#endif

namespace Gst
{

/**
 * Generic class containing fields of names and values.
 * A Gst::Structure is a collection of key/value pairs. The keys are expressed
 * as GQuarks and the values can be of any GType.
 *
 * In addition to the key/value pairs, a Gst::Structure also has a name. The name
 * starts with a letter and can be filled by letters, numbers and any of "/-_.:".
 *
 * Gst::Structure is used by various GStreamer subsystems to store information
 * in a flexible and extensible way. A Gst::Structure does not have a refcount
 * because it usually is part of a higher level object such as Gst::Caps,
 * Gst::Message, Gst::Event, Gst::Query.
 *
 * A Gst::Structure can be created with constructor, which take a name
 * and an optional set of key/value pairs along with the types of the values.
 *
 * Field values can be changed with set_field() or set_fields().
 *
 * Field values can be retrieved with gst_get_field().
 *
 * Fields can be removed with remove_field().
 *
 * Strings in structures must be ASCII or UTF-8 encoded.
 *
 * Be aware that the current Gst::Caps / Gst::Structure serialization into string
 * has limited support for nested Gst::Caps / Gst::Structure fields. It can only
 * support one level of nesting. Using more levels will lead to unexpected
 * behavior when using serialization features, such as Gst::Caps::to_string() or
 * gst_value_serialize() and their counterparts.
 *
 * Last reviewed on 2016-07-12 (1.8.0)
 */
class Structure
{
 public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  using CppObjectType = Structure;
  using BaseObjectType = GstStructure;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

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

  Structure();

  explicit Structure(GstStructure* gobject, bool make_a_copy = true);

  Structure(const Structure& other);
  Structure& operator=(const Structure& other);

  Structure(Structure&& other) noexcept;
  Structure& operator=(Structure&& other) noexcept;

  ~Structure() noexcept;

  void swap(Structure& other) noexcept;

  ///Provides access to the underlying C instance.
  GstStructure*       gobj()       { return gobject_; }

  ///Provides access to the underlying C instance.
  const GstStructure* 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.
  GstStructure* gobj_copy() const;

protected:
  GstStructure* gobject_;

private:

  
public:
  /** Creates a Structure with the given @a name. Parses the list of variable
   * arguments and sets fields to the values listed. Variable arguments
   * should be passed as field name and value
   */
  template<class ...DataTypes>
  explicit Structure(const Glib::ustring &name, DataTypes... data);

  /** Creates a Gst::Structure from a string representation.
   *
   * @param the_string A string representation of a Gst::Structure. See to_string().
   * @return A Structure. This will be invalid (see operator=) when the string 
   * could not be parsed.
   */
  static Structure create_from_string(const Glib::ustring& the_string);
  

  /** Use this to discover if the Structure is a valid object.
   */
  operator const void*() const;

  /** Release the ownership of underlying GstStructure instance.
   *
   * Gst::Structure's underlying instance is set to nullptr, therefore underlying
   * object can't be accessed through this Gst::Structure anymore.
   * @return an underlying instance of GstStructure object.
   *
   * Most users should not use release(). It can spoil the automatic destruction
   * of the managed object.
   */
  GstStructure* release() noexcept;

  
  /** Get the name of @a structure as a string.
   * 
   * @return The name of the structure.
   */
  Glib::ustring get_name() const;
  
  /** Checks if the structure has the given name
   * 
   * @param name Structure name to check for.
   * @return <tt>true</tt> if @a name matches the name of the structure.
   */
  bool has_name(const Glib::ustring& name) const;
  
  /** Sets the name of the structure to the given @a name.  The string
   * provided is copied before being used. It must not be empty, start with a
   * letter and can be followed by letters, numbers and any of "/-_.:".
   * 
   * @param name The new name of the structure.
   */
  void set_name(const Glib::ustring& name);
  
  /** Get the name of @a structure as a GQuark.
   * 
   * @return The quark representing the name of the structure.
   */
  Glib::QueryQuark get_name_id() const;
  
  /** Removes all fields in a GstStructure.
   */
  void remove_all_fields();
  
  /** Finds the field with the given name, and returns the type of the
   * value it contains.  If the field is not found, G_TYPE_INVALID is
   * returned.
   * 
   * @param fieldname The name of the field.
   * @return The Value of the field.
   */
  GType get_field_type(const Glib::ustring& fieldname) const;
  
  /** Get the number of fields in the structure.
   * 
   * @return The number of fields in the structure.
   */
  int size() const;
  
  /** Get the name of the given field number, counting from 0 onwards.
   * 
   * @param index The index to get the name of.
   * @return The name of the given field number.
   */
  Glib::ustring get_nth_field_name(guint index) const;
  
  /** Converts @a structure to a human-readable string representation.
   * 
   * For debugging purposes its easier to do something like this:
   * 
   * [C example ellipted]
   * This prints the structure in human readable form.
   * 
   * The current implementation of serialization will lead to unexpected results
   * when there are nested Gst::Caps / Gst::Structure deeper than one level.
   * 
   * @return A pointer to string allocated by Glib::malloc().
   */
  Glib::ustring to_string() const;
  
  /** Fixates a Gst::Structure by changing the given field to the nearest
   * integer to @a target that is a subset of the existing field.
   * 
   * @param name A field in @a structure.
   * @param target The target value of the fixation.
   * @return <tt>true</tt> if the structure could be fixated.
   */
  bool fixate_field_nearest_int(const Glib::ustring& name, int target);
  
  /** Fixates a Gst::Structure by changing the given field to the nearest
   * double to @a target that is a subset of the existing field.
   * 
   * @param name A field in @a structure.
   * @param target The target value of the fixation.
   * @return <tt>true</tt> if the structure could be fixated.
   */
  bool fixate_field_nearest_double(const Glib::ustring& name, double target);
  
  /** Fixates a Gst::Structure by changing the given @a name field to the given
   *  @a target string if that field is not fixed yet.
   * 
   * @param name A field in @a structure.
   * @param target The target value of the fixation.
   * @return <tt>true</tt> if the structure could be fixated.
   */
  bool fixate_field_string(const Glib::ustring& name, const Glib::ustring& target);
  
  /** Fixates a Gst::Structure by changing the given field with its fixated value.
   * 
   * @param name A field in @a structure.
   * @return <tt>true</tt> if the structure field could be fixated.
   */
  bool fixate_field(const Glib::ustring& name);
  
  /** Fixates a Gst::Structure by changing the given @a name field to the given
   *  @a target boolean if that field is not fixed yet.
   * 
   * @param name A field in @a structure.
   * @param target The target value of the fixation.
   * @return <tt>true</tt> if the structure could be fixated.
   */
  bool fixate_field_boolean(const Glib::ustring& name, bool target);
  
  /** Intersects @a struct1 and @a struct2 and returns the intersection.
   * 
   * @param struct2 A Gst::Structure.
   * @return Intersection of @a struct1 and @a struct2.
   */
  Gst::Structure intersect(const Gst::Structure& struct2) const;
  
  /** Tests if the two Gst::Structure are equal.
   * 
   * @param struct2 A Gst::Structure.
   * @return <tt>true</tt> if the two structures have the same name and field.
   */
  bool is_equal(const Gst::Structure& struct2) const;
  
  /** Checks if @a subset is a subset of @a superset, i.e.\ has the same
   * structure name and for all fields that are existing in @a superset,
   *  @a subset has a value that is a subset of the value in @a superset.
   * 
   * @param superset A potentially greater Gst::Structure.
   * @return <tt>true</tt> if @a subset is a subset of @a superset.
   */
  bool is_subset(const Gst::Structure& superset) const;
  
  /** Tries intersecting @a struct1 and @a struct2 and reports whether the result
   * would not be empty.
   * 
   * @param struct2 A Gst::Structure.
   * @return <tt>true</tt> if intersection would not be empty.
   */
  bool can_intersect(const Gst::Structure& struct2) const;
  
  /** Fixate all values in @a structure using gst_value_fixate().
   *  @a structure will be modified in-place and should be writable.
   */
  void fixate();
  
  /** Read the GstFlagSet flags and mask out of the structure into the
   * provided pointers.
   * 
   * @param fieldname The name of a field.
   * @param value_flags A pointer to a <tt>unsigned int</tt> for the flags field.
   * @param value_mask A pointer to a <tt>unsigned int</tt> for the mask field.
   * @return <tt>true</tt> if the values could be set correctly. If there was no field
   * with @a fieldname or the existing field did not contain a GstFlagSet, this
   * function returns <tt>false</tt>.
   */
  bool get_flagset(const Glib::ustring& fieldname, guint& value_flags, guint& value_mask) const;

  
  /** Check if @a structure contains a field named @a fieldname.
   * 
   * @param fieldname The name of a field.
   * @return <tt>true</tt> if the structure contains a field with the given name.
   */
  bool has_field(const Glib::ustring& fieldname) const;
  

  /** Check if @a structure contains a field named @a fieldname and with GType @a type.
   * 
   * @param fieldname The name of a field.
   * @param type The type of a value.
   * @return <tt>true</tt> if the structure contains a field with the given name and type.
   */
  bool has_field(const Glib::ustring& fieldname, GType type) const;
  

  /** Get the value of the field with name @a fieldname.
   *
   * @param fieldname The name of the field to get.
   * @param value The Value class in which to store the value.
   */
  void get_field(const Glib::ustring& fieldname, Glib::ValueBase& value) const;

  /** Get the value of the field with name @a fieldname.
   *
   * @param fieldname The name of the field to get.
   * @param value The Value class in which to store the value.
   */
  template<typename DataType>
  void get_field(const Glib::ustring& fieldname, Glib::Value<DataType>& value) const;

    /** Gets the value of field @a fieldname with GType enum type @a enumtype
   * into integer @a value.  Caller is responsible for making sure the
   * field exists and has the correct type.  A call to this method would look
   * like so:
   * @code
   * ...
   * int state;
   * structure.get_field("state", Glib::Value<Gst::State>::value_type(),
   * state);
   * ...
   * @endcode
   *
   * @param fieldname The name of a field.
   * @param enumtype The enum GType of the field.
   * @param value An output parameter that will be set with the value.
   * @return true if @a value could be set correctly. If there was no field
   * with @a fieldname or the existing field did not contain an enum, this
   * function returns false.
   */
  bool get_field(const Glib::ustring& fieldname, GType enumtype, int& value) const;
  

  /** Gets the value of field @a fieldname into DataType @a value.
   * The caller is responsible for making sure the field exists and has the
   * correct type.
   *
   * @param fieldname The name of a field.
   * @param value The DataType to set.
   */
  template<typename DataType>
  bool get_field(const Glib::ustring& fieldname, DataType& value) const;

  // These are ignored because they are useful in the C API but are either
  // variable argument functions or their functionality is already provided.
  

  /** Sets the field with name @a fieldname to value. If the field does not
   * exist, it is created. If the field exists, the previous value is replaced
   * and freed.
   *
   * @param fieldname The name of the field to set.
   * @param value The value to set the field to.
   */
  void set_field(const Glib::ustring& fieldname, const Glib::ValueBase& value);
  

  /** Sets the field with name @a fieldname to value. If the field does not
   * exist, it is created. If the field exists, the previous value is replaced
   * and freed.
   *
   * @param fieldname The name of the field to set.
   * @param value The value to set the field to.
   */
  template<typename DataType>
  void set_field(const Glib::ustring& fieldname, const Glib::Value<DataType>& value);

  /** Sets the field with name @a fieldname to value. If the field does not
   * exist, it is created. If the field exists, the previous value is replaced
   * and freed.
   *
   * @param fieldname The name of the field to set.
   * @param value The value to set the field to.
   */
  void set_field(const Glib::ustring& fieldname, const char* value);

  /** Sets the fields with name @a fieldname to values. If one of the fields does not
   * exist, it is created. If the field exists, the previous value is replaced
   * and freed.
   *
   * @param fieldname The name of the field to set.
   * @param value The value to set the field to.
   * @param further_data List of pairs of the format: fieldname, value.
   */
  template<class DataType, class ...DataTypes>
  void set_fields(const Glib::ustring & fieldname, const DataType& value, DataTypes ...further_data);

  /** Sets the field with name @a fieldname to the value @a value of the enum
   * type @a enum_type. If the field does not exist, it is created. If the
   * field exists, the previous value is replaced and freed.  Caller is
   * responsible for making sure that @a value is a valid @a enumtype.  A call
   * to this method would look like so:
   * @code
   * ...
   * structure.set_field("state", Glib::Value<Gst::State>::value_type(),
   * Gst::STATE_PAUSED);
   * ...
   * @endcode
   *
   * @param fieldname The name of the field to set.
   * @param enumtype The enum GType that @a value should be treated as.
   * @param value The value to set the field to.
   */
  void set_field(const Glib::ustring& fieldname, GType enumtype, int value);

  /** Sets the field with name @a fieldname field to the DataType @a value.
   * If the field does not exist, it is created. If the field exists,
   * the previous value is replaced and freed. Please note that when setting
   * fields to special types such as Gst::Fourcc and Gst::Fraction and
   * Glib::Date they are converted to the GStreamer GTypes and thus when
   * attempting to get these fields back as GValues, they will have the
   * GStreamer GType.
   *
   * @param fieldname The name of the field to set.
   * @param value The value to set the field to.
   */
  template<typename DataType>
  void set_field(const Glib::ustring& fieldname, const DataType& value);

  // These take ownership of the GValue so they are not wrapped.
  

  /** Removes the field with name @a fieldname. If the field with the given
   * name does not exist, the structure is unchanged.
   *
   * @param fieldname The name of the field to remove.
   */
  void remove_field(const Glib::ustring& fieldname);
  

  /** For example,
   * bool on_foreach(const Glib::ustring& id, const Glib::ValueBase& value);.
   * The on_foreach function should return true if the foreach operation should
   * continue, or false if the operation should stop with false.
   */
  typedef sigc::slot<bool, const Glib::ustring&, const Glib::ValueBase&> SlotForeach;

  /** Calls the provided slot once for each field in the Gst::Structure. The
   * slot must not modify the fields. See also map_in_place().
   *
   * @param slot A slot to call for each field.
   * @return true if the supplied slot returns true For each of the fields,
   * false otherwise.
   */
  bool foreach(const SlotForeach& slot);
  

  /** For example,
   * bool on_map(const Glib::ustring& id, Glib::ValueBase& value);.
   * The map function should return true if the map operation should continue,
   * or false if the operation should stop with false.
   */
  typedef sigc::slot<bool, const Glib::ustring&, Glib::ValueBase&> SlotMap;

  /** Calls the provided slot once for each field in the Gst::Structure. In
   * contrast to foreach(), the function may modify but not delete the fields.
   * The structure must be mutable.
   *
   * @param slot A slot to call for each field.
   * @return true if the supplied slot returns true For each of the fields,
   * false otherwise.
   */
  bool map_in_place(const SlotMap& slot);
  

  /** Fixates a Gst::Structure by changing the given field to the nearest
   * fraction to given Gst::Fraction that is a subset of the existing field.
   *
   * @param field_name A field in structure.
   * @param target The target value of the fixation.
   * @return true If the structure could be fixated.
   */
  bool fixate_nearest_fraction(const Glib::ustring& field_name, const Gst::Fraction& target);
  

  //Variable argument functions are ignored.
  

private:
  // This method is used for varadic template recursion
  void set_fields() {}


};

template<class ...DataTypes>
Structure::Structure(const Glib::ustring &name, DataTypes... data)
{
  gobject_ = gst_structure_new_empty(name.c_str());
  set_fields(data...);
}

template<class DataType, class ...DataTypes>
void Structure::set_fields(const Glib::ustring & name, const DataType& data, DataTypes ...further_data)
{
  this->set_field(name, data);
  this->set_fields(further_data...);
}

template<typename DataType>
bool Structure::get_field(const Glib::ustring& fieldname, DataType& value) const
{
  typedef Glib::Value<DataType> ValueType;

  bool ret = ValueType::value_type() == get_field_type(fieldname);

  if (ret)
  {
    ValueType v;
    this->get_field(fieldname, reinterpret_cast<Glib::ValueBase&>(v));
    value = v.get();
  }

  return ret;
}

template<typename DataType>
void Structure::set_field(const Glib::ustring& fieldname, const DataType& value)
{
  typedef Glib::Value<DataType> ValueType;
  ValueType v;
  v.init(ValueType::value_type());
  v.set(value);
  this->set_field(fieldname, reinterpret_cast<const Glib::ValueBase&>(v));
}

template<typename DataType>
void Structure::get_field(const Glib::ustring& fieldname, Glib::Value<DataType>& value) const
{
  get_field(fieldname, reinterpret_cast<Glib::ValueBase&>(value));
}

template<typename DataType>
void Structure::set_field(const Glib::ustring& fieldname, const Glib::Value<DataType>& value)
{
  set_field(fieldname, reinterpret_cast<const Glib::ValueBase&>(value));
}

} //namespace Gst


namespace Gst
{

/** @relates Gst::Structure
 * @param lhs The left-hand side
 * @param rhs The right-hand side
 */
inline void swap(Structure& lhs, Structure& rhs) noexcept
  { lhs.swap(rhs); }

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

#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <>
class Value<Gst::Structure> : public Glib::Value_Boxed<Gst::Structure>
{};
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

} // namespace Glib


#endif /* _GSTREAMERMM_STRUCTURE_H */

