/* 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/interfaces/mixeroptions.h>
#include <gstreamermm/mixertrack.h>
#include <glibmm/interface.h>

_DEFS(gstreamermm,gst)

namespace Gst
{

_WRAP_ENUM(MixerType, GstMixerType)
_WRAP_ENUM(MixerFlags, GstMixerFlags)
_WRAP_ENUM(MixerMessageType, GstMixerMessageType)

class MixerOptions;
class MixerTrack;

/** Gst::Mixer - Interface for elements that provide mixer operations.
 * @ingroup GstInterfaces
 */
class Mixer : public Glib::Interface
{
  _CLASS_INTERFACE(Mixer, GstMixer, GST_MIXER, GstMixerClass)

public:
#m4 _CONVERSION(`const GList*', `Glib::ListHandle< Glib::RefPtr<Gst::MixerTrack> >', `$2(const_cast<GList*>($3), Glib::OWNERSHIP_NONE)')
  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Gst::MixerTrack> > list_tracks(), gst_mixer_list_tracks)

#m4 _CONVERSION(`const GList*', `Glib::ListHandle< Glib::RefPtr<const Gst::MixerTrack> >', `$2(const_cast<GList*>($3), Glib::OWNERSHIP_NONE)')
  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<const Gst::MixerTrack> > list_tracks() const, gst_mixer_list_tracks)

  /** Get the current volume(s) on the given track.
   *
   * @param track the Gst::MixerTrack to get the volume from.
   * @return an array of integers (of size track->num_channels) to with the
   * current volume of each channel in the given track. 
   */
  Glib::ArrayHandle<int> get_volume(const Glib::RefPtr<const Gst::MixerTrack>& track) const;
  _IGNORE(gst_mixer_get_volume)

#m4 _CONVERSION(`const Glib::ArrayHandle<int>&', `gint*', `const_cast<int*>(($3).data())')
  _WRAP_METHOD(void set_volume(const Glib::RefPtr<Gst::MixerTrack>& track, const Glib::ArrayHandle<int>& volumes), gst_mixer_set_volume)

  _WRAP_METHOD(void set_mute(const Glib::RefPtr<Gst::MixerTrack>& track, bool mute), gst_mixer_set_mute)
  _WRAP_METHOD(void set_record(const Glib::RefPtr<Gst::MixerTrack>& track, bool record), gst_mixer_set_record)
  _WRAP_METHOD(void set_option(const Glib::RefPtr<Gst::MixerOptions>& opts, const Glib::ustring& value), gst_mixer_set_option)
  _WRAP_METHOD(void mute_toggled(const Glib::RefPtr<Gst::MixerTrack>& track, bool mute), gst_mixer_mute_toggled)
  _WRAP_METHOD(void record_toggled(const Glib::RefPtr<Gst::MixerTrack>& track, bool record), gst_mixer_record_toggled)
  _WRAP_METHOD(void volume_changed(const Glib::RefPtr<Gst::MixerTrack>& track, const Glib::ArrayHandle<int>& volumes), gst_mixer_volume_changed)
  _WRAP_METHOD(void option_changed(const Glib::RefPtr<Gst::MixerOptions>& opts, const Glib::ustring& value), gst_mixer_option_changed)
  _WRAP_METHOD(void options_list_changed(const Glib::RefPtr<Gst::MixerOptions>& opts), gst_mixer_options_list_changed)
  _WRAP_METHOD(Glib::ustring get_option(const Glib::RefPtr<const Gst::MixerOptions>& opts) const, gst_mixer_get_option)
  _WRAP_METHOD(void mixer_changed(), gst_mixer_mixer_changed)
  _WRAP_METHOD(Gst::MixerFlags get_mixer_flags() const, gst_mixer_get_mixer_flags)

  /* TODO:
  _WRAP_METHOD(satic Gst::MixerMessageType message_get_type(GstMessage *message), gst_mixer_message_get_type)
  _WRAP_METHOD(static void message_parse_mute_toggled(GstMessage *message, GstMixerTrack **track, gboolean *mute), gst_mixer_message_parse_mute_toggled)
  _WRAP_METHOD(static void message_parse_option_changed(GstMessage *message, GstMixerOptions **options, const gchar **value), gst_mixer_message_parse_option_changed)
  _WRAP_METHOD(static void message_parse_record_toggled(GstMessage *message, GstMixerTrack **track, gboolean *record), gst_mixer_message_parse_record_toggled)
  _WRAP_METHOD(static void message_parse_volume_changed(GstMessage *message, GstMixerTrack **track, gint **volumes, gint *num_channels), gst_mixer_message_parse_volume_changed)
  _WRAP_METHOD(static void message_parse_options_list_changed(GstMessage *message, GstMixerOptions **options), gst_mixer_message_parse_options_list_changed)
  */

//TODO:
//#m4 _CONVERSION(`Glib::ListHandle< Glib::RefPtr<Gst::MixerTrack> >', `const GList*', `($3).data()')
  //_WRAP_VFUNC(Glib::ListHandle< Glib::RefPtr<Gst::MixerTrack> > list_tracks() const, "list_tracks")

#ifdef GLIBMM_VFUNCS_ENABLED
// This vfunc is handcoded because we want to have it return the result instead
// of requiring a pointer parameter in which to put it like the C API does.
  virtual Glib::ArrayHandle<int> get_volume_vfunc(const Glib::RefPtr<const Gst::MixerTrack>& track) const;
#endif //GLIBMM_VFUNCS_ENABLED

#m4 _CONVERSION(`GstMixerTrack*',`const Glib::RefPtr<Gst::MixerTrack>&', `Glib::wrap(($3), true)')

//TODO:
  //_WRAP_VFUNC(void set_volume(const Glib::RefPtr<Gst::MixerTrack>& track, const Glib::ArrayHandle<int>& volumes), "set_volume")

  _WRAP_VFUNC(void set_mute(const Glib::RefPtr<Gst::MixerTrack>& track, bool mute), "set_mute")
  _WRAP_VFUNC(void set_record(const Glib::RefPtr<Gst::MixerTrack>& track, bool record), "set_record")

#m4 _CONVERSION(`GstMixerOptions*',`const Glib::RefPtr<Gst::MixerOptions>&', `Glib::wrap(($3), true)')
  _WRAP_VFUNC(void set_option(const Glib::RefPtr<Gst::MixerOptions>& opts, const Glib::ustring& value), "set_option")

  //TODO:
  //_WRAP_VFUNC(Glib::ustring get_option(const Glib::RefPtr<const Gst::MixerOptions>& opts) const, "get_option")

protected:
#m4begin
dnl// This vfunc callback is handcoded because we want to have the C++ vfunc
dnl// return the result instead of passing in a pointer in which to store it.
  _PUSH(SECTION_PCC_CLASS_INIT_VFUNCS)
    klass->get_volume = &get_volume_vfunc_callback;
  _SECTION(SECTION_PH_VFUNCS)
    static void get_volume_vfunc_callback(GstMixer* self, GstMixerTrack* track, gint* volumes);
  _POP()
#m4end
};

} // namespace Gst
