// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_SEGMENT_H
#define _GSTREAMERMM_SEGMENT_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 <gstreamermm/clock.h>
#include <gstreamermm/format.h>
#include <gstreamermm/event.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
extern "C" { typedef struct _GstSegment GstSegment; }
#endif

namespace Gst
{

/** A class that describes the configured region of interest in a media file.
 * This helper structure holds the relevant values for tracking the region of
 * interest in a media file, called a segment.
 *
 * The structure can be used for two purposes:
 * 
 *  - performing seeks (handling seek events)
 *  - tracking playback regions (handling newsegment events)
 *
 * The segment is usually configured by the application with a seek event which
 * is propagated upstream and eventually handled by an element that performs
 * the seek.
 *
 * The configured segment is then propagated back downstream with a newsegment
 * event. This information is then used to clip media to the segment
 * boundaries.
 *
 * A segment structure is initialized with init(), which takes a Format that
 * will be used as the format of the segment values. The segment will be
 * configured with a start value of 0 and a stop/duration of -1, which is
 * undefined. The default rate and applied_rate is 1.0.
 *
 * If the segment is used for managing seeks, the segment duration should be
 * set with set_duration(). The public duration field contains the duration of
 * the segment. When using the segment for seeking, the start and time members
 * should normally be left to their default 0 value. The stop position is left
 * to -1 unless explicitly configured to a different value after a seek event.
 *
 * The current position in the segment should be set with the set_last_stop().
 * The public last_stop field contains the last set stop position in the
 * segment.
 *
 * For elements that perform seeks, the current segment should be updated with
 * the set_seek() and the values from the seek event. This method will update
 * all the segment fields. The last_stop field will contain the new playback
 * position. If the cur_type was different from Gst::SEEK_TYPE_NONE, playback
 * continues from the last_stop position, possibly with updated flags or rate.
 *
 * For elements that want to use Gst::Segment to track the playback region, use
 * set_newsegment() to update the segment fields with the information from the
 * newsegment event. The clip() method can be used to check and clip the media
 * data to the segment boundaries.
 *
 * For elements that want to synchronize to the pipeline clock,
 * to_running_time() can be used to convert a timestamp to a value that can be
 * used to synchronize to the clock. This function takes into account all
 * accumulated segments as well as any rate or applied_rate conversions.
 *
 * For elements that need to perform operations on media data in stream_time,
 * to_stream_time() can be used to convert a timestamp and the segment info to
 * stream time (which is always between 0 and the duration of the stream).
 *
 * Last reviewed on 2007-05-17 (0.10.13)
 */
class Segment
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef Segment CppObjectType;
  typedef GstSegment BaseObjectType;

  static GType get_type() G_GNUC_CONST;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  Segment();

  explicit Segment(GstSegment* gobject, bool make_a_copy = true);

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

  ~Segment();

  void swap(Segment& other);

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

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

protected:
  GstSegment* gobject_;

private:

  
public:
  
  /** Clip the given @a start and @a stop values to the segment boundaries given
   * in @a segment. @a start and @a stop are compared and clipped to @a segment 
   * start and stop values.
   * 
   * If the function returns <tt>false</tt>, @a start and @a stop are known to fall
   * outside of @a segment and @a clip_start and @a clip_stop are not updated.
   * 
   * When the function returns <tt>true</tt>, @a clip_start and @a clip_stop will be
   * updated. If @a clip_start or @a clip_stop are different from @a start or @a stop
   * respectively, the region fell partially in the segment.
   * 
   * Note that when @a stop is -1, @a clip_stop will be set to the end of the
   * segment. Depending on the use case, this may or may not be what you want.
   * @param format The format of the segment.
   * @param start The start position in the segment.
   * @param stop The stop position in the segment.
   * @param clip_start The clipped start position in the segment.
   * @param clip_stop The clipped stop position in the segment.
   * @return <tt>true</tt> if the given @a start and @a stop times fall partially or 
   * completely in @a segment, <tt>false</tt> if the values are completely outside 
   * of the segment.
   */
  bool clip(Format format, gint64 start, gint64 stop, gint64& clip_start, gint64& clip_stop) const;
  
  /** The start/last_stop positions are set to 0 and the stop/duration
   * fields are set to -1 (unknown). The default rate of 1.0 and no
   * flags are set.
   * 
   * Initialize @a segment to its default values.
   * @param format The format of the segment.
   */
  void init(Format format);
  
  /** Set the duration of the segment to @a duration. This function is mainly
   * used by elements that perform seeking and know the total duration of the
   * segment. 
   * 
   * This field should be set to allow seeking requests relative to the
   * duration.
   * @param format The format of the segment.
   * @param duration The duration of the segment info or -1 if unknown.
   */
  void set_duration(Format format, gint64 duration);
  
  /** Set the last observed stop position in the segment to @a position.
   * 
   * This field should be set to allow seeking requests relative to the
   * current playing position.
   * @param format The format of the segment.
   * @param position The position.
   */
  void set_last_stop(Format format, gint64 position);
  
  /** Update the segment structure with the field values of a new segment event and
   * with a default applied_rate of 1.0.
   * @param update Flag indicating a new segment is started or updated.
   * @param rate The rate of the segment.
   * @param format The format of the segment.
   * @param start The new start value.
   * @param stop The new stop value.
   * @param time The new stream time.
   */
  void set_newsegment(bool update, double rate, Format format, gint64 start, gint64 stop, gint64 time);
  
  /** Update the segment structure with the field values of a new segment event.
   * @param update Flag indicating a new segment is started or updated.
   * @param rate The rate of the segment.
   * @param applied_rate The applied rate of the segment.
   * @param format The format of the segment.
   * @param start The new start value.
   * @param stop The new stop value.
   * @param time The new stream time.
   */
  void set_newsegment(bool update, double rate, double applied_rate, Format format, gint64 start, gint64 stop, gint64 time);
  
  /** Update the segment structure with the field values of a seek event (see
   * Gst::Event::new_seek()).
   * 
   * After calling this method, the segment field last_stop and time will
   * contain the requested new position in the segment. The new requested
   * position in the segment depends on @a rate and @a start_type and @a stop_type. 
   * 
   * For positive @a rate, the new position in the segment is the new @a segment
   * start field when it was updated with a @a start_type different from
   * Gst::SEEK_TYPE_NONE. If no update was performed on @a segment start position
   * (Gst::SEEK_TYPE_NONE), @a start is ignored and @a segment last_stop is
   * unmodified.
   * 
   * For negative @a rate, the new position in the segment is the new @a segment
   * stop field when it was updated with a @a stop_type different from
   * Gst::SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
   * duration of the segment will be used to update the stop position.
   * If no update was performed on @a segment stop position (Gst::SEEK_TYPE_NONE),
   *  @a stop is ignored and @a segment last_stop is unmodified.
   * 
   * The applied rate of the segment will be set to 1.0 by default.
   * If the caller can apply a rate change, it should update @a segment
   * rate and applied_rate after calling this function.
   * 
   *  @a update will be set to <tt>true</tt> if a seek should be performed to the segment 
   * last_stop field. This field can be <tt>false</tt> if, for example, only the @a rate
   * has been changed but not the playback position.
   * @param rate The rate of the segment.
   * @param format The format of the segment.
   * @param flags The seek flags for the segment.
   * @param start_type The seek method.
   * @param start The seek start value.
   * @param stop_type The seek method.
   * @param stop The seek stop value.
   * @param update Boolean holding whether last_stop was updated.
   */

  void set_seek(double rate, Format format, SeekFlags flags, SeekType start_type, gint64 start, SeekType stop_type, gint64 stop, bool& update);
  
  /** Translate @a position to the total running time using the currently configured 
   * and previously accumulated segments. Position is a value between @a segment
   * start and stop time.
   * 
   * This function is typically used by elements that need to synchronize to the
   * global clock in a pipeline. The runnning time is a constantly increasing value
   * starting from 0. When init() is called, this value will reset to
   * 0.
   * 
   * This function returns -1 if the position is outside of @a segment start and stop.
   * @param format The format of the segment.
   * @param position The position in the segment.
   * @return The position as the total running time or -1 when an invalid position
   * was given.
   */
  gint64 to_running_time(Format format, gint64 position) const;
  
  /** Translate @a position to stream time using the currently configured 
   * segment. The @a position value must be between @a segment start and
   * stop value. 
   * 
   * This function is typically used by elements that need to operate on
   * the stream time of the buffers it receives, such as effect plugins.
   * In those use cases, @a position is typically the buffer timestamp or 
   * clock time that one wants to convert to the stream time.
   * The stream time is always between 0 and the total duration of the 
   * media stream.
   * @param format The format of the segment.
   * @param position The position in the segment.
   * @return The position in stream_time or -1 when an invalid position
   * was given.
   */
  gint64 to_stream_time(Format format, gint64 position) const;
  
  /** Convert @a running_time into a position in the segment so that
   * to_running_time() with that position returns @a running_time.
   * @param format The format of the segment.
   * @param running_time The running_time in the segment.
   * @return The position in the segment for @a running_time. This function returns
   * -1 when @a running_time is -1 or when it is not inside @a segment.
   */
  gint64 to_position(Format format, gint64 running_time) const;
  
  /** Adjust the start/stop and accum values of @a segment such that the next valid
   * buffer will be one with @a running_time.
   * @param format The format of the segment.
   * @param running_time The running_time in the segment.
   * @return <tt>true</tt> if the segment could be updated successfully. If <tt>false</tt> is
   * returned, @a running_time is -1 or not in @a segment.
   */
  bool set_running_time(Format format, gint64 running_time);


};

} //namespace Gst


namespace Gst
{

/** @relates Gst::Segment
 * @param lhs The left-hand side
 * @param rhs The right-hand side
 */
inline void swap(Segment& lhs, Segment& rhs)
  { 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::Segment
 */
Gst::Segment wrap(GstSegment* object, bool take_copy = false);

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

} // namespace Glib


#endif /* _GSTREAMERMM_SEGMENT_H */

