// Generated by gtkmmproc -- DO NOT MODIFY!


#include <glibmm.h>

#include <gstreamermm/message.h>
#include <gstreamermm/private/message_p.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/gstenumtypes.h>
#include <gst/interfaces/mixer.h>
#include <gstreamermm/element.h>
#include <gstreamermm/mixer.h>
#include <gstreamermm/pad.h>
#include <gstreamermm/structure.h>
#include <gstreamermm/taglist.h>

#include <iostream>

namespace
{

extern "C"
{

static void Message_gstreamermm_callback_destroy(void* data,
  GstMiniObject* /* where_the_object_was */)
{
  // This works for any of the Gst::Message derived classes because none of
  // them have member variables so in essence they are all the same size.
  delete static_cast<Gst::Message*>(data);
}

}

}

namespace Gst
{

namespace Enums
{

Glib::ustring get_name(MessageType t)
{
  return gst_message_type_get_name(static_cast<GstMessageType>(t));
}

Glib::QueryQuark get_quark(MessageType t)
{
  return Glib::QueryQuark(gst_message_type_to_quark(static_cast<GstMessageType>(t)));
}

} //namespace Enums

Glib::RefPtr<Gst::Message> Message::create_writable()
{
  return wrap(gst_message_make_writable(gobj()));
}

MessageEos::MessageEos(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageEos>
  MessageEos::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_eos(Glib::unwrap(src));
  return Gst::Message::wrap<MessageEos>(message, false);
}

MessageError::MessageError(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageError>
  MessageError::create(const Glib::RefPtr<Gst::Object>& src,
  Glib::Error& error, const std::string& debug)
{
  GstMessage* message = gst_message_new_error(Glib::unwrap(src), error.gobj(),
    reinterpret_cast<const gchar*>(debug.c_str()));
  return Gst::Message::wrap<MessageError>(message, false);
}

void MessageError::parse(Glib::Error& error, std::string& debug) const
{
  GError* c_error = 0;
  gchar* c_debug = 0;
  gst_message_parse_error(const_cast<GstMessage*>(gobj()), &c_error, &c_debug);

  debug = c_debug;
  if(c_debug)
    g_free(c_debug);

  error = Glib::Error(c_error);
}

Glib::Error MessageError::parse() const
{
  GError* c_error = 0;
  gst_message_parse_error(const_cast<GstMessage*>(gobj()), &c_error, 0);

  return Glib::Error(c_error);
}

std::string MessageError::parse_debug() const
{
  gchar* c_debug = 0;
  GError* c_error = 0;

  gst_message_parse_error(const_cast<GstMessage*>(gobj()), &c_error, &c_debug);

  std::string result = c_debug;

  if(c_debug)
    g_free(c_debug);

  if(c_error)
    g_error_free(c_error);

  return result;
}

MessageWarning::MessageWarning(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageWarning>
  MessageWarning::create(const Glib::RefPtr<Gst::Object>& src,
  Glib::Error& error, const std::string& debug)
{
  GstMessage* message = gst_message_new_warning(Glib::unwrap(src),
    error.gobj(), reinterpret_cast<const gchar*>(debug.c_str()));
  return Gst::Message::wrap<MessageWarning>(message, false);
}

void MessageWarning::parse(Glib::Error& error, std::string& debug) const
{
  GError* c_error = 0;
  gchar* c_debug = 0;
  gst_message_parse_warning(const_cast<GstMessage*>(gobj()), &c_error, &c_debug);

  debug = c_debug;
  if(c_debug)
    g_free(c_debug);

  error = Glib::Error(c_error);
}

Glib::Error MessageWarning::parse() const
{
  GError* c_error = 0;
  gst_message_parse_warning(const_cast<GstMessage*>(gobj()), &c_error, 0);

  return Glib::Error(c_error);
}

std::string MessageWarning::parse_debug() const
{
  gchar* c_debug = 0;
  GError* c_error = 0;

  gst_message_parse_warning(const_cast<GstMessage*>(gobj()), &c_error,
    &c_debug);

  std::string result = c_debug;

  if(c_debug)
    g_free(c_debug);

  if(c_error)
    g_error_free(c_error);

  return result;
}

MessageInfo::MessageInfo(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageInfo>
  MessageInfo::create(const Glib::RefPtr<Gst::Object>& src,
  Glib::Error& error, const std::string& debug)
{
  GstMessage* message = gst_message_new_info(Glib::unwrap(src), error.gobj(),
    reinterpret_cast<const gchar*>(debug.c_str()));
  return Gst::Message::wrap<MessageInfo>(message, false);
}


void MessageInfo::parse(Glib::Error& error, std::string& debug) const
{
  GError* c_error = 0;
  gchar* c_debug = 0;
  gst_message_parse_info(const_cast<GstMessage*>(gobj()), &c_error, &c_debug);

  debug = c_debug;
  if(c_debug)
    g_free(c_debug);

  error = Glib::Error(c_error);
}

Glib::Error MessageInfo::parse() const
{
  GError* c_error = 0;
  gst_message_parse_info(const_cast<GstMessage*>(gobj()), &c_error, 0);

  return Glib::Error(c_error);
}

std::string MessageInfo::parse_debug() const
{
  gchar* c_debug = 0;
  GError* c_error = 0;

  gst_message_parse_info(const_cast<GstMessage*>(gobj()), &c_error, &c_debug);

  std::string result = c_debug;

  if(c_debug)
    g_free(c_debug);

  if(c_error)
    g_error_free(c_error);

  return result;
}

MessageTag::MessageTag(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageTag>
  MessageTag::create(const Glib::RefPtr<Gst::Object>& src,
  const Gst::TagList& taglist)
{
  //We create a copy because gst_message_new_tag() takes ownership:
  GstTagList* c_taglist = gst_tag_list_copy(taglist.gobj());
  GstMessage* message = gst_message_new_tag(Glib::unwrap(src), c_taglist);
  return Gst::Message::wrap<MessageTag>(message, false);
}

Glib::RefPtr<Gst::MessageTag>
  MessageTag::create(const Glib::RefPtr<Gst::Object>& src,
  const Glib::RefPtr<Gst::Pad>& pad, const Gst::TagList& taglist)
{
  //We create a copy because gst_message_new_tag() takes ownership:
  GstTagList* c_taglist = gst_tag_list_copy(taglist.gobj());
  GstMessage* message = gst_message_new_tag_full(Glib::unwrap(src),
    Glib::unwrap(pad), c_taglist);
  return Gst::Message::wrap<MessageTag>(message, false);
}

void MessageTag::parse(Glib::RefPtr<Gst::Pad>& pad, Gst::TagList& tag_list)
  const
{
  GstTagList* gst_tag_list = 0;
  GstPad* gst_pad = 0;

  gst_message_parse_tag_full(const_cast<GstMessage*>(gobj()), &gst_pad,
    &gst_tag_list);

  pad = Glib::wrap(gst_pad);

  // Use the Gst::TagList specific Glib::wrap() function:
  tag_list = Glib::wrap_taglist(gst_tag_list);
}

Gst::TagList MessageTag::parse() const
{
  GstTagList* gst_tag_list = 0;
  gst_message_parse_tag(const_cast<GstMessage*>(gobj()), &gst_tag_list);
  return Gst::TagList(gst_tag_list);
}

Glib::RefPtr<Gst::Pad> MessageTag::parse_pad() const
{
  GstPad* gst_pad = 0;
  gst_message_parse_tag_full(const_cast<GstMessage*>(gobj()), &gst_pad, 0);
  return Glib::wrap(gst_pad);
}

MessageBuffering::MessageBuffering(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageBuffering>
  MessageBuffering::create(const Glib::RefPtr<Gst::Object>& src, int percent)
{
  GstMessage* message = gst_message_new_buffering(Glib::unwrap(src), percent);
  return Gst::Message::wrap<MessageBuffering>(message, false);
}

int MessageBuffering::parse() const
{
  int percent = 0;
  gst_message_parse_buffering(const_cast<GstMessage*>(gobj()), &percent);
  return percent;
}

void MessageBuffering::set_stats(BufferingMode mode, int avg_in, int avg_out,
gint64 buffering_left)
{
  gst_message_set_buffering_stats(gobj(), static_cast<GstBufferingMode>(mode),
  avg_in, avg_out, buffering_left);
}

void MessageBuffering::parse_stats(BufferingMode& mode, int& avg_in,
int& avg_out, gint64& buffering_left) const
{
  gst_message_parse_buffering_stats(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstBufferingMode*>(&mode), &avg_in, &avg_out,
    &buffering_left);
}

BufferingMode MessageBuffering::parse_stats_buffering_mode() const
{
  GstBufferingMode mode = GST_BUFFERING_STREAM;

  gst_message_parse_buffering_stats(const_cast<GstMessage*>(gobj()), &mode,
    0, 0, 0);
  return static_cast<BufferingMode>(mode);
}

int MessageBuffering::parse_stats_avg_in() const
{
  int avg_in = 0;

  gst_message_parse_buffering_stats(const_cast<GstMessage*>(gobj()), 0,
    &avg_in, 0, 0);
  return avg_in;
}

int MessageBuffering::parse_stats_avg_out() const
{
  int avg_out = 0;

  gst_message_parse_buffering_stats(const_cast<GstMessage*>(gobj()), 0,
    0, &avg_out, 0);
  return avg_out;
}

gint64 MessageBuffering::parse_stats_buffering_left() const
{
  gint64 buffering_left = 0;

  gst_message_parse_buffering_stats(const_cast<GstMessage*>(gobj()), 0,
    0, 0, &buffering_left);
  return buffering_left;
}

MessageStateChanged::MessageStateChanged(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStateChanged>
  MessageStateChanged::create(const Glib::RefPtr<Gst::Object>& src,
  State oldstate, State newstate, State pending)
{
  GstMessage* message = gst_message_new_state_changed(Glib::unwrap(src),
    static_cast<GstState>(oldstate), static_cast<GstState>(newstate),
    static_cast<GstState>(pending));
  return Gst::Message::wrap<MessageStateChanged>(message, false);
}

void MessageStateChanged::parse(State& oldstate, State& newstate,
State& pending) const
{
  gst_message_parse_state_changed(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstState*>(&oldstate),
    reinterpret_cast<GstState*>(&newstate),
    reinterpret_cast<GstState*>(&pending));
}

State MessageStateChanged::parse() const
{
  GstState new_state = GST_STATE_NULL;

  gst_message_parse_state_changed(const_cast<GstMessage*>(gobj()), 0,
    &new_state, 0);
  return State(new_state);
}

State MessageStateChanged::parse_old() const
{
  GstState old_state = GST_STATE_NULL;

  gst_message_parse_state_changed(const_cast<GstMessage*>(gobj()), &old_state,
    0, 0);
  return State(old_state);
}

State MessageStateChanged::parse_pending() const
{
  GstState pending_state = GST_STATE_NULL;
  gst_message_parse_state_changed(const_cast<GstMessage*>(gobj()), 0,
    0, &pending_state);
  return State(pending_state);
}

MessageStateDirty::MessageStateDirty(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStateDirty>
  MessageStateDirty::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_state_dirty(Glib::unwrap(src));
  return Gst::Message::wrap<MessageStateDirty>(message, false);
}

MessageStepDone::MessageStepDone(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStepDone>
  MessageStepDone::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::Format format, guint64 amount, double rate, bool flush,
  bool intermediate, guint64 duration, bool eos)
{
  GstMessage* message = gst_message_new_step_done(Glib::unwrap(src),
    static_cast<GstFormat>(format), amount, rate, flush, intermediate,
    duration, eos);
  return Gst::Message::wrap<MessageStepDone>(message, false);
}

void MessageStepDone::parse(Gst::Format& format, guint64& amount, double& rate,
  bool& flush, bool& intermediate, guint64& duration, bool& eos) const
{
  gboolean gst_flush = FALSE;
  gboolean gst_intermediate = FALSE;
  gboolean gst_eos = FALSE;

  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), &amount, &rate, &gst_flush,
    &gst_intermediate, &duration, &gst_eos);

  flush = gst_flush;
  intermediate = gst_intermediate;
  eos = gst_eos;
}

guint64 MessageStepDone::parse() const
{
  guint64 duration = 0;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, 0, 0, 0, 0,
    &duration, 0);
  return duration;
}

Gst::Format MessageStepDone::parse_format() const
{
  GstFormat format = GST_FORMAT_UNDEFINED;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), 0, 0, 0, 0, 0, 0);
  return static_cast<Gst::Format>(format);
}

guint64 MessageStepDone::parse_amount() const
{
  guint64 amount = 0;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, &amount, 0,
    0, 0, 0, 0);
  return amount;
}

double MessageStepDone::parse_rate() const
{
  double rate = 0;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, 0, &rate, 0,
    0, 0, 0);
  return rate;
}

bool MessageStepDone::parse_flush() const
{
  gboolean gst_flush = FALSE;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, 0, 0,
    &gst_flush, 0, 0, 0);
  return gst_flush;
}

bool MessageStepDone::parse_intermediate() const
{
  gboolean gst_intermediate = FALSE;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, 0, 0, 0,
    &gst_intermediate, 0, 0);
  return gst_intermediate;
}

bool MessageStepDone::parse_eos() const
{
  gboolean gst_eos = FALSE;
  gst_message_parse_step_done(const_cast<GstMessage*>(gobj()), 0, 0, 0, 0, 0,
    0, &gst_eos);
  return gst_eos;
}


MessageClockProvide::MessageClockProvide(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageClockProvide>
  MessageClockProvide::create(const Glib::RefPtr<Gst::Object>& src,
  const Glib::RefPtr<Gst::Clock>& clock, bool ready)
{
  GstMessage* message = gst_message_new_clock_provide(Glib::unwrap(src),
    Glib::unwrap(clock), ready);
  return Gst::Message::wrap<MessageClockProvide>(message, false);
}

void MessageClockProvide::parse(Glib::RefPtr<Gst::Clock>& clock, bool& ready) const
{
  GstClock* cclock = 0;
  gboolean ready_ = false;
  gst_message_parse_clock_provide(const_cast<GstMessage*>(gobj()), &cclock,
    &ready_);
  clock = Glib::wrap(cclock);
  ready = ready_;
}

Glib::RefPtr<Gst::Clock> MessageClockProvide::parse()
{
  GstClock* cclock = 0;
  gst_message_parse_clock_provide(gobj(), &cclock, 0);
  return Glib::wrap(cclock);
}

Glib::RefPtr<const Gst::Clock> MessageClockProvide::parse() const
{
  return parse();
}

bool MessageClockProvide::parse_ready() const
{
  gboolean ready = FALSE;
  gst_message_parse_clock_provide(const_cast<GstMessage*>(gobj()), 0,
    &ready);
  return ready;
}

MessageClockLost::MessageClockLost(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageClockLost>
  MessageClockLost::create(const Glib::RefPtr<Gst::Object>& src,
  const Glib::RefPtr<Gst::Clock>& clock)
{
  GstMessage* message = gst_message_new_clock_lost(Glib::unwrap(src),
    Glib::unwrap(clock));
  return Gst::Message::wrap<MessageClockLost>(message, false);
}

Glib::RefPtr<Gst::Clock> MessageClockLost::parse()
{
  GstClock* cclock = 0;
  gst_message_parse_clock_lost(gobj(), &cclock);
  return Glib::wrap(cclock, false);
}

Glib::RefPtr<const Gst::Clock> MessageClockLost::parse() const
{
  return parse();
}

MessageNewClock::MessageNewClock(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageNewClock>
  MessageNewClock::create(const Glib::RefPtr<Gst::Object>& src,
  const Glib::RefPtr<Gst::Clock>& clock)
{
  GstMessage* message = gst_message_new_new_clock(Glib::unwrap(src),
    Glib::unwrap(clock));
  return Gst::Message::wrap<MessageNewClock>(message, false);
}

Glib::RefPtr<Gst::Clock> MessageNewClock::parse()
{
  GstClock* cclock = 0;
  gst_message_parse_new_clock(gobj(), &cclock);
  return Glib::wrap(cclock, false);
}

Glib::RefPtr<const Gst::Clock> MessageNewClock::parse() const
{
  return parse();
}

MessageApplication::MessageApplication(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageApplication>
  MessageApplication::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::Structure& structure)
{
  GstStructure* copy_struct = gst_structure_copy(structure.gobj());
  GstMessage* message = gst_message_new_application(Glib::unwrap(src),
    copy_struct);
  return Gst::Message::wrap<MessageApplication>(message, false);
}

Glib::RefPtr<Gst::MessageApplication>
  MessageApplication::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_application(Glib::unwrap(src), 0);
  return Gst::Message::wrap<MessageApplication>(message, false);
}

MessageElement::MessageElement(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageElement>
  MessageElement::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::Structure& structure)
{
  GstStructure* copy_struct = gst_structure_copy(structure.gobj());
  GstMessage* message = gst_message_new_element(Glib::unwrap(src),
    copy_struct);
  return Gst::Message::wrap<MessageElement>(message, false);
}

Glib::RefPtr<Gst::MessageElement>
  MessageElement::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_element(Glib::unwrap(src), 0);
  return Gst::Message::wrap<MessageElement>(message, false);
}

MessageCustom::MessageCustom(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageCustom>
  MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src,
  Gst::Structure& structure)
{
  GstStructure* copy_struct = gst_structure_copy(structure.gobj());
  GstMessage* message = gst_message_new_custom(GstMessageType(type),
    Glib::unwrap(src), copy_struct);
  return Gst::Message::wrap<MessageCustom>(message, false);
}

Glib::RefPtr<Gst::MessageCustom>
  MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_custom(GstMessageType(type),
    Glib::unwrap(src), 0);
  return Gst::Message::wrap<MessageCustom>(message, false);
}

MessageSegmentStart::MessageSegmentStart(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageSegmentStart>
  MessageSegmentStart::create(const Glib::RefPtr<Gst::Object>& src,
  Format format, gint64 position)
{
  GstMessage* message = gst_message_new_segment_start(Glib::unwrap(src),
    static_cast<GstFormat>(format), position);
  return Gst::Message::wrap<MessageSegmentStart>(message, false);
}

void MessageSegmentStart::parse(Format& format, gint64& position) const
{
  gst_message_parse_segment_start(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), &position);
}

gint64 MessageSegmentStart::parse() const
{
  gint64 position = 0;
  gst_message_parse_segment_start(const_cast<GstMessage*>(gobj()), 0,
    &position);
  return position;
}

Format MessageSegmentStart::parse_format() const
{
  Format format = Gst::FORMAT_DEFAULT;
  gst_message_parse_segment_start(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), 0);
  return format;
}

MessageSegmentDone::MessageSegmentDone(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageSegmentDone>
  MessageSegmentDone::create(const Glib::RefPtr<Gst::Object>& src,
  Format format, gint64 position)
{
  GstMessage* message = gst_message_new_segment_done(Glib::unwrap(src),
    static_cast<GstFormat>(format), position);
  return Gst::Message::wrap<MessageSegmentDone>(message, false);
}

void MessageSegmentDone::parse(Format& format, gint64& position) const
{
  gst_message_parse_segment_done(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), &position);
}

gint64 MessageSegmentDone::parse() const
{
  gint64 position = 0;
  gst_message_parse_segment_done(const_cast<GstMessage*>(gobj()), 0,
    &position);
  return position;
}

Format MessageSegmentDone::parse_format() const
{
  Format format = Gst::FORMAT_UNDEFINED;
  gst_message_parse_segment_done(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), 0);
  return format;
}

MessageDuration::MessageDuration(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageDuration>
  MessageDuration::create(const Glib::RefPtr<Gst::Object>& src, Format format,
  gint64 duration)
{
  GstMessage* message = gst_message_new_duration(Glib::unwrap(src),
    static_cast<GstFormat>(format), duration);
  return Gst::Message::wrap<MessageDuration>(message, false);
}

void MessageDuration::parse(Format& format, gint64& duration) const
{
  gst_message_parse_duration(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), &duration);
}

gint64 MessageDuration::parse() const
{
  gint64 duration = 0;
  gst_message_parse_duration(const_cast<GstMessage*>(gobj()), 0, &duration);
  return duration;
}

Format MessageDuration::parse_format() const
{
  Format format = Gst::FORMAT_UNDEFINED;
  gst_message_parse_duration(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstFormat*>(&format), 0);
  return format;
}

MessageLatency::MessageLatency(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageLatency>
  MessageLatency::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_latency(Glib::unwrap(src));
  return Gst::Message::wrap<MessageLatency>(message, false);
}

MessageAsyncStart::MessageAsyncStart(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageAsyncStart>
  MessageAsyncStart::create(const Glib::RefPtr<Gst::Object>& src,
  bool new_base_time)
{
  GstMessage* message = gst_message_new_async_start(Glib::unwrap(src),
    new_base_time);
  return Gst::Message::wrap<MessageAsyncStart>(message, false);
}

bool MessageAsyncStart::parse() const
{
  gboolean new_base_time = FALSE;
  gst_message_parse_async_start(const_cast<GstMessage*>(gobj()),
    &new_base_time);
  return new_base_time;
}

MessageAsyncDone::MessageAsyncDone(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageAsyncDone>
  MessageAsyncDone::create(const Glib::RefPtr<Gst::Object>& src)
{
  GstMessage* message = gst_message_new_async_done(Glib::unwrap(src));
  return Gst::Message::wrap<MessageAsyncDone>(message, false);
}

MessageStepStart::MessageStepStart(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStepStart>
  MessageStepStart::create(const Glib::RefPtr<Gst::Object>& src,
  bool active, Gst::Format format, guint64 amount, double rate, bool flush,
  bool intermediate)
{
  GstMessage* message = gst_message_new_step_start(Glib::unwrap(src),
    active, static_cast<GstFormat>(format), amount, rate, flush, intermediate);
  return Gst::Message::wrap<MessageStepStart>(message, false);
}

void MessageStepStart::parse(bool& active, Gst::Format& format,
  guint64& amount, double& rate, bool& flush, bool& intermediate) const
{
  gboolean gst_active = FALSE;
  gboolean gst_flush = FALSE;
  gboolean gst_intermediate = FALSE;

  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), &gst_active,
    reinterpret_cast<GstFormat*>(&format), &amount, &rate, &gst_flush,
    &gst_intermediate);

  active = gst_active;
  flush = gst_flush;
  intermediate = gst_intermediate;
}

guint64 MessageStepStart::parse() const
{
  guint64 amount = 0;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), 0, 0, &amount,
    0, 0, 0);
  return amount;
}

bool MessageStepStart::parse_active() const
{
  gboolean gst_active = FALSE;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), &gst_active, 0,
    0, 0, 0, 0);
  return gst_active;
}

Gst::Format MessageStepStart::parse_format() const
{
  GstFormat format = GST_FORMAT_UNDEFINED;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), 0,
    reinterpret_cast<GstFormat*>(&format), 0, 0, 0, 0);
  return static_cast<Gst::Format>(format);
}

double MessageStepStart::parse_rate() const
{
  double rate = 0;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), 0, 0, 0, &rate,
    0, 0);
  return rate;
}

bool MessageStepStart::parse_flush() const
{
  gboolean gst_flush = FALSE;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), 0, 0, 0, 0,
    &gst_flush, 0);
  return gst_flush;
}

bool MessageStepStart::parse_intermediate() const
{
  gboolean gst_intermediate = FALSE;
  gst_message_parse_step_start(const_cast<GstMessage*>(gobj()), 0, 0, 0, 0, 0,
    &gst_intermediate);
  return gst_intermediate;
}

MessageStructureChange::MessageStructureChange(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStructureChange>
  MessageStructureChange::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::StructureChangeType type, const Glib::RefPtr<Gst::Element>& owner,
  bool busy)
{
  GstMessage* message = gst_message_new_structure_change(Glib::unwrap(src),
    static_cast<GstStructureChangeType>(type), Glib::unwrap(owner), busy);
  return Gst::Message::wrap<MessageStructureChange>(message, false);
}

void MessageStructureChange::parse(Gst::StructureChangeType& type,
  Glib::RefPtr<Gst::Element>& owner, bool& busy) const
{
  GstElement* gst_element = 0;
  gboolean gst_busy = false;
  gst_message_parse_structure_change(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstStructureChangeType*>(&type), &gst_element, &gst_busy);
  owner = Glib::wrap(gst_element, true);
  busy = gst_busy;
}

Gst::StructureChangeType MessageStructureChange::parse() const
{
  GstStructureChangeType gst_type = GST_STRUCTURE_CHANGE_TYPE_PAD_LINK;
  gst_message_parse_structure_change(const_cast<GstMessage*>(gobj()),
    &gst_type, 0, 0);
  return static_cast<Gst::StructureChangeType>(gst_type);
}

Glib::RefPtr<Gst::Element> MessageStructureChange::parse_owner() const
{
  GstElement* gst_element = 0;
  gst_message_parse_structure_change(const_cast<GstMessage*>(gobj()), 0,
    &gst_element, 0);
  return Glib::wrap(gst_element, true);
}

bool MessageStructureChange::parse_busy() const
{
  gboolean gst_busy = false;
  gst_message_parse_structure_change(const_cast<GstMessage*>(gobj()), 0, 0,
    &gst_busy);
  return gst_busy;
}

MessageRequestState::MessageRequestState(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageRequestState>
  MessageRequestState::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::State state)
{
  GstMessage* message = gst_message_new_request_state(Glib::unwrap(src),
    static_cast<GstState>(state));
  return Gst::Message::wrap<MessageRequestState>(message, false);
}

Gst::State MessageRequestState::parse() const
{
  GstState gst_state = GST_STATE_VOID_PENDING;
  gst_message_parse_request_state(const_cast<GstMessage*>(gobj()),
    &gst_state);
  return static_cast<Gst::State>(gst_state);
}

MessageStreamStatus::MessageStreamStatus(GstMessage* castitem)
: Message(castitem)
{}

Glib::RefPtr<Gst::MessageStreamStatus>
  MessageStreamStatus::create(const Glib::RefPtr<Gst::Object>& src,
  Gst::StreamStatusType type, const Glib::RefPtr<Gst::Element>& owner)
{
  GstMessage* message = gst_message_new_stream_status(Glib::unwrap(src),
    static_cast<GstStreamStatusType>(type), Glib::unwrap(owner));
  return Gst::Message::wrap<MessageStreamStatus>(message, false);
}

void MessageStreamStatus::set_object(const Glib::RefPtr<Gst::Object>& object)
{
  Glib::Value< Glib::RefPtr<Gst::Object> > value;
  value.init(Glib::Value< Glib::RefPtr<Gst::Object> >::value_type());
  value.set(object);

  gst_message_set_stream_status_object(gobj(), value.gobj());
}

Glib::RefPtr<Gst::Object> MessageStreamStatus::get_object() const
{
  const GValue* g_val =
    gst_message_get_stream_status_object(const_cast<GstMessage*>(gobj()));
  GstObject* gst_object = static_cast<GstObject*>(g_value_get_object(g_val));
  return Glib::wrap(gst_object, true);
}

void MessageStreamStatus::parse(Gst::StreamStatusType& type,
  Glib::RefPtr<Gst::Element>& owner) const
{
  GstElement* gst_element;
  gst_message_parse_stream_status(const_cast<GstMessage*>(gobj()),
    reinterpret_cast<GstStreamStatusType*>(&type), &gst_element);
  owner = Glib::wrap(gst_element, true);
}

Gst::StreamStatusType MessageStreamStatus::parse() const
{
  GstStreamStatusType type;
  gst_message_parse_stream_status(const_cast<GstMessage*>(gobj()),
    &type, 0);
  return static_cast<Gst::StreamStatusType>(type);
}

Glib::RefPtr<Gst::Element> MessageStreamStatus::parse_owner() const
{
  GstElement* gst_element;
  gst_message_parse_stream_status(const_cast<GstMessage*>(gobj()), 0,
    &gst_element);
  return Glib::wrap(gst_element, true);
}

Glib::RefPtr<Gst::Message> Message::wrap(GstMessage* message, bool take_copy)
{
  Gst::Message* wrapper = 0;
  Glib::RefPtr<Gst::Message> result;

  if(!message)
    return result;

  GstMixerMessageType const mixer_message_type =
    gst_mixer_message_get_type(message);

  if(mixer_message_type == GST_MIXER_MESSAGE_INVALID)
  {
    switch(GST_MESSAGE_TYPE(message))
    {
      case GST_MESSAGE_EOS:
        wrapper = new Gst::MessageEos(message);
        break;
      case GST_MESSAGE_ERROR:
        wrapper = new Gst::MessageError(message);
        break;
      case GST_MESSAGE_WARNING:
        wrapper = new Gst::MessageWarning(message);
        break;
      case GST_MESSAGE_INFO:
        wrapper = new Gst::MessageInfo(message);
        break;
      case GST_MESSAGE_TAG:
        wrapper = new Gst::MessageTag(message);
        break;
      case GST_MESSAGE_BUFFERING:
        wrapper = new Gst::MessageBuffering(message);
        break;
      case GST_MESSAGE_STATE_CHANGED:
        wrapper = new Gst::MessageStateChanged(message);
        break;
      case GST_MESSAGE_STATE_DIRTY:
        wrapper = new Gst::MessageStateDirty(message);
        break;
      case GST_MESSAGE_STEP_DONE:
        wrapper = new Gst::MessageStepDone(message);
        break;
      case GST_MESSAGE_CLOCK_PROVIDE:
        wrapper = new Gst::MessageClockProvide(message);
        break;
      case GST_MESSAGE_CLOCK_LOST:
        wrapper = new Gst::MessageClockLost(message);
        break;
      case GST_MESSAGE_NEW_CLOCK:
        wrapper = new Gst::MessageNewClock(message);
        break;
      case GST_MESSAGE_APPLICATION:
        wrapper = new Gst::MessageApplication(message);
        break;
      case GST_MESSAGE_ELEMENT:
        wrapper = new Gst::MessageElement(message);
        break;
      case GST_MESSAGE_SEGMENT_START:
        wrapper = new Gst::MessageSegmentStart(message);
        break;
      case GST_MESSAGE_SEGMENT_DONE:
        wrapper = new Gst::MessageSegmentDone(message);
        break;
      case GST_MESSAGE_DURATION:
        wrapper = new Gst::MessageDuration(message);
        break;
      case GST_MESSAGE_LATENCY:
        wrapper = new Gst::MessageLatency(message);
        break;
      case GST_MESSAGE_ASYNC_START:
        wrapper = new Gst::MessageAsyncStart(message);
        break;
      case GST_MESSAGE_ASYNC_DONE:
        wrapper = new Gst::MessageAsyncDone(message);
        break;
      case GST_MESSAGE_STEP_START:
        wrapper = new Gst::MessageStepStart(message);
        break;
      case GST_MESSAGE_STRUCTURE_CHANGE:
        wrapper = new Gst::MessageStructureChange(message);
        break;
      case GST_MESSAGE_REQUEST_STATE:
        wrapper = new Gst::MessageRequestState(message);
        break;
      case GST_MESSAGE_STREAM_STATUS:
        wrapper = new Gst::MessageStreamStatus(message);
        break;
      case GST_MESSAGE_UNKNOWN:
      case GST_MESSAGE_ANY:
        wrapper = new Gst::Message(message);
        break;
        /* The rest of the message types are custom ones */
      default:
        wrapper = new Gst::MessageCustom(message);
    }
  }
  else
  {
    switch(mixer_message_type)
    {
      case GST_MIXER_MESSAGE_MUTE_TOGGLED:
        wrapper = new Gst::MessageMixerMuteToggled(message);
        break;
      case GST_MIXER_MESSAGE_RECORD_TOGGLED:
        wrapper = new Gst::MessageMixerRecordToggled(message);
        break;
      case GST_MIXER_MESSAGE_VOLUME_CHANGED:
        wrapper = new Gst::MessageMixerVolumeChanged(message);
        break;
      case GST_MIXER_MESSAGE_OPTION_CHANGED:
        wrapper = new Gst::MessageMixerOptionChanged(message);
        break;
      case GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED:
        wrapper = new Gst::MessageMixerOptionsListChanged(message);
        break;
      case GST_MIXER_MESSAGE_MIXER_CHANGED:
        wrapper = new Gst::MessageMixerChanged(message);
        break;
      default:
        wrapper = new Gst::MessageCustom(message);
    }
  }

  result = Glib::RefPtr<Gst::Message>(wrapper);

  // Ensure that the wrapper is freed when the message (mini object) is freed.
  gst_mini_object_weak_ref(GST_MINI_OBJECT(message),
    &Message_gstreamermm_callback_destroy, wrapper);

  if(take_copy)
    result->reference();

  return result;
}

Gst::MiniObject* Message_Class::wrap_new(GstMiniObject* object)
{
  // Use the Gst::Message wrap() method to get the right type of Message class
  // and return the underlying object in the refptr.  The extra reference is
  // needed so that the object does not loose a reference when the local
  // refptr is destroyed.
  return Gst::Message::wrap((GstMessage*)object, true).operator->();
}

GstMiniObject* Message_Class::copy_vfunc_callback(const GstMiniObject* self)
{
  BaseClassType *const base = static_cast<BaseClassType*>(
      g_type_class_peek_parent(GST_MINI_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The original underlying C class).
  );

  // Call the original underlying C function:
  if(base && GST_MINI_OBJECT_CLASS(base)->copy)
    return (*GST_MINI_OBJECT_CLASS(base)->copy)(self);

  return 0;
}
Glib::RefPtr<Gst::MiniObject> Message::copy_vfunc() const
{
  BaseClassType *const base = static_cast<BaseClassType*>(
      g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobj())) // Get the parent class of the object class (The original underlying C class).
  );

  if(base && GST_MINI_OBJECT_CLASS(base)->copy)
  {
    return Gst::Message::wrap(
      GST_MESSAGE((*GST_MINI_OBJECT_CLASS(base)->copy)(
        GST_MINI_OBJECT(gobj()))));
  }

  return Glib::RefPtr<Gst::MiniObject>(0);
}
void Message_Class::finalize_vfunc_callback(GstMiniObject* self)
{
  BaseClassType *const base = static_cast<BaseClassType*>(
      g_type_class_peek_parent(GST_MINI_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The original underlying C class).
  );

  // Call the original underlying C function:
  if(base && GST_MINI_OBJECT_CLASS(base)->finalize)
    (*GST_MINI_OBJECT_CLASS(base)->finalize)(self);
}
void Message::finalize_vfunc()
{
  BaseClassType *const base = static_cast<BaseClassType*>(
      g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobj())) // Get the parent class of the object class (The original underlying C class).
  );

  if(base && GST_MINI_OBJECT_CLASS(base)->finalize)
    (*GST_MINI_OBJECT_CLASS(base)->finalize)(GST_MINI_OBJECT(gobj()));
}

} //namespace Gst

namespace
{
} // anonymous namespace

// static
GType Glib::Value<Gst::MessageType>::value_type()
{
  return gst_message_type_get_type();
}

// static
GType Glib::Value<Gst::StructureChangeType>::value_type()
{
  return gst_structure_change_type_get_type();
}

// static
GType Glib::Value<Gst::StreamStatusType>::value_type()
{
  return gst_stream_status_type_get_type();
}


namespace Gst
{

Glib::RefPtr<Gst::Message> wrap(GstMessage* object, bool take_copy)
{
  //Note that we use Gst::wrap() instead of Glib::wrap() 
  //because we are dealing with a GstMiniObject, not a GObject:
  return Glib::RefPtr<Gst::Message>( dynamic_cast<Gst::Message*> (Gst::wrap_auto ((GstMiniObject*)(object), take_copy)) );
  //We use dynamic_cast<> in case of multiple inheritance.
}

} /* namespace Gst */


namespace Gst
{


/* The *_Class implementation: */

const Glib::Class& Message_Class::init()
{
  if(!gtype_) // create the GType if necessary
  {
    // Glib::Class has to know the class init function to clone custom types.
    class_init_func_ = &Message_Class::class_init_function;

    // This is actually just optimized away, apparently with no harm.
    // Make sure that the parent type has been created.
    //CppClassParent::CppObjectType::get_type();

    // Create the wrapper type, with the same class/instance size as the base type.
    register_derived_type(gst_message_get_type());

    // Add derived versions of interfaces, if the C type implements any interfaces:

  }

  return *this;
}


void Message_Class::class_init_function(void* g_class, void* class_data)
{
  BaseClassType *const klass = static_cast<BaseClassType*>(g_class);
  CppClassParent::class_init_function(klass, class_data);

  GST_MINI_OBJECT_CLASS(klass)->copy = &copy_vfunc_callback;
  GST_MINI_OBJECT_CLASS(klass)->finalize = &finalize_vfunc_callback;
  
}


/* The implementation: */

GstMessage* Message::gobj_copy()
{
  // Use the mini object copying function to get a copy of the underlying
  // gobject instead of referencing and returning the underlying gobject as
  // would be done normally:
  return reinterpret_cast<GstMessage*>(gst_mini_object_copy(reinterpret_cast<GstMiniObject*>(gobj())));
}


Message::Message(GstMessage* castitem)
:
  Gst::MiniObject((GstMiniObject*)(castitem))
{}

Message::~Message()
{}


Message::CppClassType Message::message_class_; // initialize static member

GType Message::get_type()
{
  return message_class_.init().get_type();
}


GType Message::get_base_type()
{
  return gst_message_get_type();
}


Gst::Structure Message::get_structure() const
{
  return Glib::wrap(const_cast<GstStructure*>(gst_message_get_structure(const_cast<GstMessage*>(gobj()))), true);
}

guint32 Message::get_seqnum() const
{
  return gst_message_get_seqnum(const_cast<GstMessage*>(gobj()));
}

void Message::set_seqnum(guint32 seqnum)
{
  gst_message_set_seqnum(gobj(), seqnum);
}

 MessageType Message::get_message_type() const
{
  return ((MessageType)(gobj()->type));
}
 
 ClockTime Message::get_timestamp() const
{
  return (ClockTime)(gobj()->timestamp);
}
 
 Glib::RefPtr<Gst::Object> Message::get_source()
{
  Glib::RefPtr<Gst::Object> ref_ptr(Glib::wrap(gobj()->src));

  if(ref_ptr)
    ref_ptr->reference();

  return ref_ptr;
}

Glib::RefPtr<const Gst::Object> Message::get_source() const
{
  Glib::RefPtr<const Gst::Object> ref_ptr(Glib::wrap(gobj()->src));

  if(ref_ptr)
    ref_ptr->reference();

  return ref_ptr;
}
 

} // namespace Gst


