// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_EVENT_H
#define _GSTREAMERMM_EVENT_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/gstevent.h>
#include <gstreamermm/miniobject.h>
#include <gstreamermm/wrap.h>
#include <gstreamermm/format.h>
#include <gstreamermm/clock.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstEvent GstEvent;
typedef struct _GstEventClass GstEventClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Event_Class; } // namespace Gst
namespace Gst
{

enum EventType
{
  EVENT_UNKNOWN = GST_EVENT_UNKNOWN,
  /* bidirectional events */
  EVENT_FLUSH_START = GST_EVENT_FLUSH_START,
  EVENT_FLUSH_STOP = GST_EVENT_FLUSH_STOP,
  /* downstream serialized events */
  EVENT_EOS = GST_EVENT_EOS,
  EVENT_NEWSEGMENT = GST_EVENT_NEWSEGMENT,
  EVENT_TAG = GST_EVENT_TAG,
  EVENT_BUFFERSIZE = GST_EVENT_BUFFERSIZE,
  /* upstream events */
  EVENT_QOS = GST_EVENT_QOS,
  EVENT_SEEK = GST_EVENT_SEEK,
  EVENT_NAVIGATION = GST_EVENT_NAVIGATION,
  EVENT_LATENCY = GST_EVENT_LATENCY,

  /* custom events start here */
  EVENT_CUSTOM_UPSTREAM = GST_EVENT_CUSTOM_UPSTREAM,
  EVENT_CUSTOM_DOWNSTREAM = GST_EVENT_CUSTOM_DOWNSTREAM,
  EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_CUSTOM_DOWNSTREAM_OOB,
  EVENT_CUSTOM_BOTH = GST_EVENT_CUSTOM_BOTH,
  EVENT_CUSTOM_BOTH_OOB = GST_EVENT_CUSTOM_BOTH_OOB
};

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

/**
 * @ingroup gstreamermmEnums
 */
enum SeekType
{
  SEEK_TYPE_NONE,
  SEEK_TYPE_CUR,
  SEEK_TYPE_SET,
  SEEK_TYPE_END
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%SeekFlags operator|(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator&(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator^(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator~(SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator|=(SeekFlags&, SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator&=(SeekFlags&, SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator^=(SeekFlags&, SeekFlags)</tt><br>
 */
enum SeekFlags
{
  SEEK_FLAG_NONE = 0x0,
  SEEK_FLAG_FLUSH = (1 << 0),
  SEEK_FLAG_ACCURATE = (1 << 1),
  SEEK_FLAG_KEY_UNIT = (1 << 2),
  SEEK_FLAG_SEGMENT = (1 << 3),
  SEEK_FLAG_SKIP = (1 << 4)
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%EventTypeFlags operator|(EventTypeFlags, EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags operator&(EventTypeFlags, EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags operator^(EventTypeFlags, EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags operator~(EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags& operator|=(EventTypeFlags&, EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags& operator&=(EventTypeFlags&, EventTypeFlags)</tt><br>
 * <tt>%EventTypeFlags& operator^=(EventTypeFlags&, EventTypeFlags)</tt><br>
 */
enum EventTypeFlags
{
  EVENT_TYPE_UPSTREAM = 1 << 0,
  EVENT_TYPE_DOWNSTREAM = 1 << 1,
  EVENT_TYPE_SERIALIZED = 1 << 2
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{


class Message;
class Structure;
class TagList;

namespace Enums
{

/** Gets a printable name for the given event type.
 *
 * @param type The event type.
 * @return A reference to the static name of the event.
 */
Glib::ustring get_name(EventType type);

/** Gets the unique quark for the given event type.
 *
 * @param type The event type.
 * @return The quark associated with the event type.
 */
Glib::QueryQuark get_quark(EventType type);

/** Gets the Gst::EventTypeFlags associated with type.
 * @param type A Gst::EventType.
 * @return A Gst::EventTypeFlags.
 */
EventTypeFlags get_flags(EventType type);

} //namespace Enums

/** A class that represents events that are passed up and down a pipeline.
 * The event class provides factory methods to construct and functions query
 * (parse) events.
 *
 * Events are usually created by using the Gst::Event derrived classes'
 * create() methods. To send an event application will usually use
 * Gst::Element::send_event() and elements will use Gst::Pad::send_event() or
 * Gst::Pad::push_event().
 *
 * Events that have been received can be parsed with their respective parse()
 * functions.
 *
 * Events are passed between elements in parallel to the data stream. Some
 * events are serialized with buffers, others are not. Some events only travel
 * downstream, others only upstream. Some events can travel both upstream and
 * downstream.
 *
 * The events are used to signal special conditions in the datastream such as
 * EOS (end of stream) or the start of a new stream-segment. Events are also
 * used to flush the pipeline of any pending data.
 *
 * Most of the event API is used inside plugins. Applications usually only
 * construct and use seek events. To do that Gst::EventSeek::create() is used
 * to create a seek event. It takes the needed parameters to specity seeking
 * time and mode.  The event is then sent to the element like so:
 * @code
 * pipeline->send_event(event);
 * @endcode
 */

class Event : public MiniObject
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Event CppObjectType;
  typedef Event_Class CppClassType;
  typedef GstEvent BaseObjectType;
  typedef GstEventClass BaseClassType;

private:
  friend class Event_Class;
  static CppClassType event_class_;

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

protected:
  explicit Event(GstEvent* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Event();

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

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

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

private:

  
public:
  /** Wrap a GstEvent in a C++ instance, creating an instance of a derived
   * Gst::Event. Gst::wrap() would just create a Gst::Event (rather than a
   * derived one) because the derived Gst::Event classes do not correspond
   * to GType types in the GStreamer API.
   */
  static Glib::RefPtr<Gst::Event> wrap(GstEvent* event, bool take_copy = false);

// A copy is taken so that the original is not freed by the wrapper.
 

  /** Access the structure of the event.
   * @return The structure of the event. The structure is still
   * owned by the event, which means that you should not free it and
   * that the pointer becomes invalid when you free the event.
   * 
   * MT safe.
   */
  Gst::Structure get_structure() const;

  
  /** Checks if @a event has the given @a name. This function is usually used to
   * check the name of a custom event.
   * @param name Name to check.
   * @return <tt>true</tt> if @a name matches the name of the event structure.
   */
  bool has_name(const Glib::ustring& name) const;

  
  /** Retrieve the sequence number of a event.
   * 
   * Events have ever-incrementing sequence numbers, which may also be set
   * explicitly via set_seqnum(). Sequence numbers are typically used to
   * indicate that a event corresponds to some other set of events or messages,
   * for example an EOS event corresponding to a SEEK event. It is considered good
   * practice to make this correspondence when possible, though it is not
   * required.
   * 
   * Note that events and messages share the same sequence number incrementor;
   * two events or messages will never have the same sequence number unless
   * that correspondence was made explicitly.
   * @return The event's sequence number.
   * 
   * MT safe.
   */
  guint32 get_seqnum() const;
  
  /** Set the sequence number of a event.
   * 
   * This function might be called by the creator of a event to indicate that the
   * event relates to other events or messages. See get_seqnum() for
   * more information.
   * 
   * MT safe.
   * @param seqnum A sequence number.
   */
  void set_seqnum(guint32 seqnum);

  /** Checks if an event is writable.  If not, a writable copy is made and
   * returned.
   * @return A Gst::Event (possibly the same reference) that is writable. 
   */
  Glib::RefPtr<Gst::Event> create_writable();

  /** Check if an event can travel downstream.
   */
  bool is_downstream() const;

  /** Check if an event is serialized with the data stream.
   */
  bool is_serialized() const;

  /** Check if an event can travel upstream.
   */
  bool is_upstream() const;

  /** Get the Gst::EventType of the event.
   */
   EventType get_event_type() const;
 
  /** Get the Gst::ClockTime timestamp of the event. This is the time when the
   * event was created.
   */
   ClockTime get_timestamp() const;
 
  /** The source Gst::Object that generated this event.
   */
   Glib::RefPtr<Gst::Object> get_source();
  Glib::RefPtr<const Gst::Object> get_source() const;
 
  /** Virtual function called when the Gst::Event needs to be copied.
   */
  virtual Glib::RefPtr<Gst::MiniObject> copy_vfunc() const;

  /** Virtual function called when the Gst::Event is about to be finalized.
   */
  virtual void finalize_vfunc();

protected:

  
protected:
  // This method is used in the create() methods to convert a wrapped GstEvent
  // to one of the more specific Gst::Event types.
  template <class EventType>
    static inline Glib::RefPtr<EventType> wrap(GstEvent* event,
    bool take_copy = false);


public:

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

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

  //Default Signal Handlers::


};

//TODO: Modify create methods of derived Event classes to return
//Glib::RefPtr<...> to the derived class and not just Gst::Event. Must deal
//with GstStructure immutability problem (bug #510301) first because casting
//Glib::RefPtrs references the objects which causes problems when GStreamer API
//tries to modify the GstStructures of the objects.

/** A flush start event.  See create() for more details.
 */
class EventFlushStart : public Event
{
public:
  explicit EventFlushStart(GstEvent* event);

  /** Allocate a new flush start event. The flush start event can be sent
   * upstream and downstream and travels out-of-bounds with the dataflow.
   *
   * It marks pads as being flushing and will make them return
   * Gst::FLOW_WRONG_STATE when used for data flow with Gst::Pad::push(),
   * Gst::Pad::chain(), Gst::Pad::alloc_buffer(), Gst::Pad::get_range() and
   * Gst::Pad::pull_range(). Any event (except a Gst::EVENT_FLUSH_STOP)
   * received on a flushing pad will return false immediately.
   *
   * Elements should unlock any blocking functions and exit their streaming
   * functions as fast as possible when this event is received.
   *
   * This event is typically generated after a seek to flush out all queued
   * data in the pipeline so that the new media is played as soon as possible.
   *
   * @return A new flush start event.
   */
  static Glib::RefPtr<Gst::EventFlushStart> create();
};

/**  A flush stop event.  See create() for more details.
 */
class EventFlushStop : public Event
{
public:
  explicit EventFlushStop(GstEvent* event);

  /** Allocate a new flush stop event. The flush stop event can be sent
   * upstream and downstream and travels out-of-bounds with the dataflow. It is
   * typically sent after sending a Gst::EventFlushStart event to make the pads
   * accept data again.
   *
   * Elements can process this event synchronized with the dataflow since the
   * preceeding Gst::EventFlushStart event stopped the dataflow.
   *
   * This event is typically generated to complete a seek and to resume
   * dataflow.
   *
   * @return A new flush stop event.
   */
  static Glib::RefPtr<Gst::EventFlushStop> create();
};

/** An end of stream event. See create() for more details.
 */
class EventEos : public Event
{
public:
  explicit EventEos(GstEvent* event);

  /** Create a new EOS event. The eos event can only travel downstream
   * synchronized with the buffer flow. Elements that receive the EOS event on
   * a pad can return Gst::FLOW_UNEXPECTED as a Gst::FlowReturn when data after
   * the EOS event arrives.
   *
   * The EOS event will travel down to the sink elements in the pipeline which
   * will then post the Gst::MESSAGE_EOS on the bus after they have finished
   * playing any buffered data.
   *
   * When all sinks have posted an EOS message, an EOS message is forwarded to
   * the application.
   *
   * @return The new EOS event. 
   */
  static Glib::RefPtr<Gst::EventEos> create();
};

/** A new segment event.  See create() for more details.
 */
class EventNewSegment : public Event
{
public:
  explicit EventNewSegment(GstEvent* event);

  /** Allocate a new newsegment event with the given format/values tripplets
   *
   * The newsegment event marks the range of buffers to be processed. All data
   * not within the segment range is not to be processed. This can be used
   * intelligently by plugins to apply more efficient methods of skipping
   * unneeded data.
   *
   * The position value of the segment is used in conjunction with the start
   * value to convert the buffer timestamps into the stream time. This is
   * usually done in sinks to report the current stream_time. position
   * represents the stream_time of a buffer carrying a timestamp of start.
   * position cannot be -1.
   *
   * start cannot be -1, stop can be -1. If there is a valid stop given, it
   * must be greater or equal the start, including when the indicated playback
   * rate is < 0.
   *
   * The applied_rate value provides information about any rate adjustment that
   * has already been made to the timestamps and content on the buffers of the
   * stream. (rate * applied_rate) should always equal the rate that has been
   * requested for playback. For example, if an element has an input segment
   * with intended playback rate of 2.0 and applied_rate of 1.0, it can adjust
   * incoming timestamps and buffer content by half and output a newsegment
   * event with rate of 1.0 and applied_rate of 2.0
   *
   * After a newsegment event, the buffer stream time is calculated with:
   *
   * position + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
   *
   * @param update Is this segment an update to a previous one.
   * @param rate A new rate for playback.
   * @param format The format of the segment values.
   * @param start The start value of the segment.
   * @param stop The stop value of the segment.
   * @param position Stream position.
   * @param applied_rate The rate factor which has already been applied.
   * @return A new newsegment event.
   *
   * Since 0.10.6
   */
  static Glib::RefPtr<Gst::EventNewSegment> create(bool update, double rate,
    Format format, gint64 strat, gint64 stop, gint64 position,
    double applied_rate = 1.0);

  /** Get the update flag, rate, format, start, stop and position in the
   * newsegment event.
   *
   * @param update A reference to store the update flag of the segment.
   * @param rate A reference to store the rate of the segment.
   * @param format A reference to store the format of the newsegment values.
   * @param start A reference to store the start value in.
   * @param stop A reference to store the stop value in.
   * @param position A reference to store the stream time in.
   */
  void parse(bool& update, double& rate, Format& format, gint64& start,
    gint64& stop, gint64& position) const;
  

  /** Get the update, rate, format, start, stop, position and applied_rate in
   * the newsegment event. See create() for a full description of the
   * newsegment event.
   *
   * @param update A reference to store the update flag of the segment.
   * @param rate A reference to store the rate of the segment.
   * @param format A reference to store the format of the newsegment values.
   * @param start A reference to store the start value in.
   * @param stop A reference to store the stop value in.
   * @param position A reference to store the stream time in.
   * @param applied_rate A reference to store the applied_rate of the segment.
   *
   * Since 0.10.6.
   */
  void parse(bool& update, double& rate, Format& format, gint64& start,
    gint64& stop, gint64& position, double& applied_rate) const;
  

  /** Get the position in the newsegment event. See create() for a full
   * description of the newsegment event.
   * @return The position.
   *
   * Since 0.10.6.
   */
  gint64 parse() const;

  /** Get the update in the newsegment event. See create() for a full
   * description of the newsegment event.
   *
   * @return The update.
   *
   * Since 0.10.6.
   */
  bool parse_update() const;

  /** Get the rate in the newsegment event. See create() for a full description
   * of the newsegment event.
   *
   * @return The rate.
   *
   * Since 0.10.6.
   */
  double parse_rate() const;

  /** Get the format in the newsegment event. See create() for a full
   * description of the newsegment event.
   *
   * @return The format.
   *
   * Since 0.10.6.
   */
  Format parse_format() const;

  /** Get the start in the newsegment event. See create() for a full
   * description of the newsegment event.
   *
   * @return The start.
   *
   * Since 0.10.6.
   */
  gint64 parse_start() const;

  /** Get the stop in the newsegment event. See create() for a full description
   * of the newsegment event.
   *
   * @return The stop.
   *
   * Since 0.10.6.
   */
  gint64 parse_stop() const;

  /** Get the applied_rate in the newsegment event. See create() for a full
   * description of the newsegment event.
   *
   * @return The applied rate.
   *
   * Since 0.10.6.
   */
  double parse_applied_rate() const;
};

/** A tag event.
 */
class EventTag : public Event
{
public:
  explicit EventTag(GstEvent* event);

  /** Generates a metadata tag event from the given taglist.
   * @param taglist Metadata list.
   * @return A new Gst::Event.
   */
  static Glib::RefPtr<Gst::EventTag> create(const Gst::TagList& taglist);

  /** Parses a tag event and stores the results in the given taglist location.
   * @return Metadata list.
   */
  Gst::TagList parse() const;
  
};

/** A buffer size event.  See create() for more details.
 */
class EventBufferSize : public Event
{
public:
  explicit EventBufferSize(GstEvent* event);

  /** Create a new buffersize event. The event is sent downstream and notifies
   * elements that they should provide a buffer of the specified dimensions.
   *
   * When the async flag is set, a thread boundary is prefered.
   *
   * @param format Buffer format.
   * @param minsize Minimum buffer size.
   * @param maxsize Maximum buffer size.
   * @param async Thread behavior.
   * @return A new Gst::EventBufferSize.
   */
  static Glib::RefPtr<Gst::EventBufferSize>
    create(Format format, gint64 minsize, gint64 maxsize, bool async);

  /** Get the format, minsize, maxsize and async-flag in the buffersize event.
   *
   * @param format A reference to store the format in.
   * @param minsize A reference to store the minsize in.
   * @param maxsize A reference to store the maxsize in.
   * @param async A reference to store the async-flag in.
   */
  void parse(Format& format, gint64& minsize, gint64& maxsize, bool& async)
    const;
  

  /** Get the minsize in the buffersize event.
   *
   * @return The mininum size.
   */
  gint64 parse() const;

  /** Get the format, in the buffersize event.
   *
   * @return The format.
   */
  Gst::Format parse_format() const;

  /** Get the maxsize in the buffersize event.
   *
   * @return The maximum size.
   */
  gint64 parse_max_size() const;

  /** Get the async-flag in the buffersize event.
   *
   * @return The async flag.
   */
  bool parse_async() const;
};

/** A QOS event.  See create() for more details.
 */
class EventQos : public Event
{
public:
  explicit EventQos(GstEvent* event);

  /** Allocate a new qos event with the given values. The QOS event is
   * generated in an element that wants an upstream element to either reduce or
   * increase its rate because of high/low CPU load or other resource usage
   * such as network performance. Typically sinks generate these events for
   * each buffer they receive.
   *
   * proportion indicates the real-time performance of the streaming in the
   * element that generated the QoS event (usually the sink). The value is
   * generally computed based on more long term statistics about the streams
   * timestamps compared to the clock. A value < 1.0 indicates that the
   * upstream element is producing data faster than real-time. A value > 1.0
   * indicates that the upstream element is not producing data fast enough. 1.0
   * is the ideal proportion value. The proportion value can safely be used to
   * lower or increase the quality of the element.
   *
   * diff is the difference against the clock in running time of the last
   * buffer that caused the element to generate the QOS event. A negative value
   * means that the buffer with timestamp arrived in time. A positive value
   * indicates how late the buffer with timestamp was.
   *
   * timestamp is the timestamp of the last buffer that cause the element to
   * generate the QOS event. It is expressed in running time and thus an ever
   * increasing value.
   *
   * The upstream element can use the diff and timestamp values to decide
   * whether to process more buffers. For possitive diff, all buffers with
   * timestamp <= timestamp + diff will certainly arrive late in the sink as
   * well.
   *
   * The application can use general event probes to intercept the QoS event
   * and implement custom application specific QoS handling.
   *
   * @param proportion The proportion of the qos message.
   * @param diff The time difference of the last clock sync.
   * @param timestamp The timestamp of the buffer.
   * @return A new QOS event.
   */
  static Glib::RefPtr<Gst::EventQos> create(double proportion,
    ClockTimeDiff diff, ClockTime timestamp);

  /** Get the proportion, diff and timestamp in the qos event. See create() for
   * more information about the different QoS values.
   *
   * @param proportion A reference to store the proportion in.
   * @param diff A reference to store the diff in.
   * @param timestamp A reference to store the timestamp in.
   */
  void parse(double& proportion, ClockTimeDiff& diff, ClockTime& timestamp) const;
  

  /** Get the proportion in the qos event. See create() for more information
   * about the different QoS values.
   *
   * @return The proportion.
   */
  double parse() const;

  /** Get the diff in the qos event. See create() for more information about
   * the different QoS values.
   *
   * @return The difference.
   */
  ClockTimeDiff parse_diff() const;

  /** Get the timestamp in the qos event. See create() for more information
   * about the different QoS values.
   * @return The timestamp.
   */
  ClockTime parse_timestamp() const;
};

/** A seek event.  See create() for more details.
 */
class EventSeek : public Event
{
public:
  explicit EventSeek(GstEvent* event);

  /** Allocate a new seek event with the given parameters.
   *
   * The seek event configures playback of the pipeline between start to stop
   * at the speed given in rate, also called a playback segment. The start and
   * stop values are expressed in format.
   *
   * A rate of 1.0 means normal playback rate, 2.0 means double speed.
   * Negatives values means backwards playback. A value of 0.0 for the rate is
   * not allowed and should be accomplished instead by PAUSING the pipeline.
   *
   * A pipeline has a default playback segment configured with a start position
   * of 0, a stop position of -1 and a rate of 1.0. The currently configured
   * playback segment can be queried with Gst::QUERY_SEGMENT.
   *
   * start_type and stop_type specify how to adjust the currently configured
   * start and stop fields in segment. Adjustments can be made relative or
   * absolute to the last configured values. A type of Gst::SEEK_TYPE_NONE
   * means that the position should not be updated.
   *
   * When the rate is positive and start has been updated, playback will start
   * from the newly configured start position.
   *
   * For negative rates, playback will start from the newly configured stop
   * position (if any). If the stop position if updated, it must be different
   * from -1 for negative rates.
   *
   * It is not possible to seek relative to the current playback position, to
   * do this, PAUSE the pipeline, query the current playback position with
   * Gst::QUERY_POSITION and update the playback segment current position with
   * a Gst::SEEK_TYPE_SET to the desired position.
   *
   * @param rate The new playback rate.
   * @param format The format of the seek values.
   * @param flags The optional seek flags.
   * @param start_type The type and flags for the new start position.
   * @param start The value of the new start position.
   * @param stop_type The type and flags for the new stop position.
   * @param stop The value of the new stop position.
   * @return A new seek event.
   */
  static Glib::RefPtr<Gst::EventSeek> create(double rate, Format format,
    SeekFlags flags, SeekType start_type, gint64 start, SeekType stop_type,
    gint64 stop);

  /** Parses a seek event and stores the results in the given result locations.
   *
   * @param rate Result location for the rate.
   * @param format Result location for the stream format.
   * @param flags Result location for the Gst::SeekFlags.
   * @param start_type Result location for the Gst::SeekType of the start
   * position.
   * @param start Result location for the start postion expressed in format.
   * @param stop_type Result location for the Gst::SeekType of the stop
   * position.
   * @param stop Result location for the stop postion expressed in format.
   */
  void parse(double& rate, Format& format, SeekFlags& flags,
    SeekType& start_type, gint64& start, SeekType& stop_type,
    gint64& stop) const;
  

  /** Parses the start of a seek event.
   * @return The start.
   */
  gint64 parse() const;

  /** Parses the rate of a seek event.
   * @return The rate.
   */
  double parse_rate() const;

  /** Parses the format of a seek event.
   * @return The format.
   */
  Format parse_format() const;

  /** Parses the flags of a seek event.
   * @return The flags.
   */
  SeekFlags parse_flags() const;

  /** Parses the start type of a seek event.
   * @return The start type.
   */
  SeekType parse_start_type() const;

  /** Parses the stop type of a seek event.
   * @return The stop type.
   */
  SeekType parse_stop_type() const;

  /** Parses the stop of a seek event.
   * @param The stop.
   */
  gint64 parse_stop() const;
};

/** A Navigation event.  See create() for more details.
 */
class EventNavigation : public Event
{
public:
  explicit EventNavigation(GstEvent* event);

  /** Create a new navigation event from the given description.
   *
   * @param structure Description of the event.
   * @return A new Gst::EventNavigation.
   */
  static Glib::RefPtr<Gst::EventNavigation> create(Gst::Structure& structure);
};

/** A latency event.  See create() for more details.
 */
class EventLatency : public Event
{
public:
  explicit EventLatency(GstEvent* event);

  /** Create a new latency event. The event is sent upstream from the sinks and
   * notifies elements that they should add an additional latency to the
   * timestamps before synchronising against the clock.
   *
   * The latency is mostly used in live sinks and is always expressed in the
   * time format.
   *
   * @param latency The new latency value.
   * @return A new Gst::EventLatency.
   *
   * Since 0.10.12.
   */
  static Glib::RefPtr<Gst::EventLatency> create(ClockTime latency);

  /** Get the latency in the latency event.
   *
   * @return The latency. 
   */
  ClockTime parse() const;
  
};

/** A step event.  See create() for more details.
 */
class EventStep : public Event
{
public:
  explicit EventStep(GstEvent* event);

  /** Create a new step event. The purpose of the step event is to instruct a
   * sink to skip @a amount (expressed in @a format) of media. It can be used
   * to implement stepping through the video frame by frame or for doing fast
   * trick modes.
   *
   * A rate of <= 0.0 is not allowed, pause the pipeline or reverse the
   * playback direction of the pipeline to get the same effect.
   *
   * The @a flush flag will clear any pending data in the pipeline before
   * starting the step operation.
   *
   * The @a intermediate flag instructs the pipeline that this step operation
   * is part of a larger step operation.
   *
   * @param format The format of amount.
   * @param amount The amount of data to step.
   * @param rate The step rate.
   * @param flush Flushing steps.
   * @param intermediate Intermediate steps.
   * @return A new Gst::Event.
   *
   * Since 0.10.24.
   */
  static Glib::RefPtr<Gst::EventStep> create(Gst::Format format,
    guint64 amount, double rate, bool flush, bool intermediate);

  /** Parse the step event.
   *
   * @param format A reference to store the format in.
   * @param amount A reference to store the amount in.
   * @param rate A reference to store the rate in.
   * @param flush A reference to store the flush boolean in.
   * @param intermediate A reference to store the intermediate boolean in.
   */
  void parse(Gst::Format& format, guint64& amount, double& rate,
    bool& flush, bool& intermediate) const;
  

  /** Get the amount in a step event.
   * @return The amount.
   */
  guint64 parse() const;

  /** Get the format in a step event.
   * @return The format.
   */
  Gst::Format parse_format() const;

  /** Get the rate in a step event.
   * @return The rate.
   */
  double parse_rate() const;

  /** Get the flush in a step event.
   * @return The flush flag.
   */
  bool parse_flush() const;

  /** Get the intermediate flag in a step event.
   * @return The intermediate flag.
   */
  bool parse_intermediate() const;
};

/** A sink-message event.  See create() for more details.
 */
class EventSinkMessage : public Event
{
public:
  explicit EventSinkMessage(GstEvent* event);

  /** Create a new sink-message event.  The purpose of the sink-message event
   * is to instruct a sink to post the message contained in the event
   * synchronized with the stream.
   *
   * @param msg The message to be posted.
   * @return A new Gst::EventSinkMessage.
   */
  static Glib::RefPtr<Gst::EventSinkMessage>
    create(const Glib::RefPtr<Gst::Message>& message);

  /** Parse the sink-message event.
   * @return the sink-messge's event message.
   */
  Glib::RefPtr<Gst::Message> parse();
  

  /** Parse the sink-message event.
   * @return the sink-messge's event message.
   */
  Glib::RefPtr<const Gst::Message> parse() const;
};

/****************************** Gst::Event **************************/

template <class EventType>
  Glib::RefPtr<EventType> Event::wrap(GstEvent* event, bool take_copy)
{
  Glib::RefPtr<Gst::Event> result = wrap(event, take_copy);
  return Glib::RefPtr<EventType>::cast_dynamic(result);
}

} //namespace Gst


namespace Gst
{
  /** @relates Gst::Event
   * @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.
   */
  Glib::RefPtr<Gst::Event> wrap(GstEvent* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_EVENT_H */

