/* Copyright (C) 2018 The gtkmm 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, see <http://www.gnu.org/licenses/>.
 */

#include <glibmm/object.h>
#include <gdkmm/paintable.h>
#include <gdkmm/surface.h>

_DEFS(gtkmm,gtk)
_PINCLUDE(glibmm/private/object_p.h)

namespace Glib
{
class Error;
}

namespace Gtk
{

/** Display media in GTK.
 *
 * %MediaStream is the integration point for media playback inside GTK.
 *
 * Apart from application-facing API for stream playback, %MediaStream
 * has a number of APIs that are only useful for implementations and should
 * not be used in applications:
 *  prepared(),
 *  unprepared(),
 *  update(),
 *  ended(),
 *  seek_success(),
 *  seek_failed(),
 *  set_error().
 *
 * @see Gdk::Paintable
 *
 * @newin{3,94}
 */
class MediaStream : public Glib::Object, public Gdk::Paintable
{
  _CLASS_GOBJECT(MediaStream, GtkMediaStream, GTK_MEDIA_STREAM, Glib::Object, GObject)
  _IMPLEMENTS_INTERFACE(Gdk::Paintable)

public:
  _WRAP_METHOD(bool is_prepared() const, gtk_media_stream_is_prepared)
#m4 _CONVERSION(`const GError*',`Glib::Error',`Glib::Error(const_cast<GError*>($3), true)')
  _WRAP_METHOD(Glib::Error get_error() const, gtk_media_stream_get_error)
  _WRAP_METHOD(bool has_audio() const, gtk_media_stream_has_audio)
  _WRAP_METHOD(bool has_video() const, gtk_media_stream_has_video)
  _WRAP_METHOD(void play(), gtk_media_stream_play)
  _WRAP_METHOD(void pause(), gtk_media_stream_pause)
  _WRAP_METHOD(bool get_playing() const, gtk_media_stream_get_playing)
  _WRAP_METHOD(void set_playing(bool playing = true), gtk_media_stream_set_playing)
  _WRAP_METHOD(bool get_ended() const, gtk_media_stream_get_ended)
  _WRAP_METHOD(gint64 get_timestamp() const, gtk_media_stream_get_timestamp)
  _WRAP_METHOD(gint64 get_duration() const, gtk_media_stream_get_duration)
  _WRAP_METHOD(bool is_seekable() const, gtk_media_stream_is_seekable)
  _WRAP_METHOD(bool is_seeking() const, gtk_media_stream_is_seeking)
  _WRAP_METHOD(void seek(gint64 timestamp), gtk_media_stream_seek)
  _WRAP_METHOD(bool get_loop() const, gtk_media_stream_get_loop)
  _WRAP_METHOD(void set_loop(bool loop = true), gtk_media_stream_set_loop)
  _WRAP_METHOD(bool get_muted() const, gtk_media_stream_get_muted)
  _WRAP_METHOD(void set_muted(bool muted = true), gtk_media_stream_set_muted)
  _WRAP_METHOD(double get_volume() const, gtk_media_stream_get_volume)
  _WRAP_METHOD(void set_volume(double volume), gtk_media_stream_set_volume)
  _WRAP_METHOD(void realize(const Glib::RefPtr<Gdk::Surface>& surface), gtk_media_stream_realize)
  _WRAP_METHOD(void unrealize(const Glib::RefPtr<Gdk::Surface>& surface), gtk_media_stream_unrealize)

  // For implementations only
  _WRAP_METHOD(void prepared(bool has_audio, bool has_video, bool seekable, gint64 duration), gtk_media_stream_prepared)
  _WRAP_METHOD(void unprepared(), gtk_media_stream_unprepared)
  _WRAP_METHOD(void update(gint64 timestamp), gtk_media_stream_update)
  _WRAP_METHOD(void ended(), gtk_media_stream_ended)
  _WRAP_METHOD(void seek_success(), gtk_media_stream_seek_success)
  _WRAP_METHOD(void seek_failed(), gtk_media_stream_seek_failed)
#m4 _CONVERSION(`const Glib::Error&',`GError*',`g_error_copy(($3).gobj())')
  _WRAP_METHOD(void set_error(const Glib::Error& error), gtk_media_stream_gerror)
  _IGNORE(gtk_media_stream_error, gtk_media_stream_error_valist)

  _WRAP_PROPERTY("prepared", bool)
  _WRAP_PROPERTY("error", Glib::Error)
  _WRAP_PROPERTY("has-audio", bool)
  _WRAP_PROPERTY("has-video", bool)
  _WRAP_PROPERTY("playing", bool)
  _WRAP_PROPERTY("ended", bool)
  _WRAP_PROPERTY("timestamp", gint64)
  _WRAP_PROPERTY("duration", gint64)
  _WRAP_PROPERTY("seekable", bool)
  _WRAP_PROPERTY("seeking", bool)
  _WRAP_PROPERTY("loop", bool)
  _WRAP_PROPERTY("muted", bool)
  //TODO: Wrap property_volume() when gtkmediastream.c has been corrected.
  // g_param_spec_boolean() is used for PROP_VOLUME there.
  //_WRAP_PROPERTY("volume", double)

protected:
  _WRAP_VFUNC(bool play(), play)
  _WRAP_VFUNC(void pause(), pause)
  _WRAP_VFUNC(void seek(gint64 timestamp), seek)
  _WRAP_VFUNC(void update_audio(bool muted, double volume), update_audio)
#m4 _CONVERSION(`GdkSurface*',`const Glib::RefPtr<Gdk::Surface>&',`Glib::wrap($3, true)')
  _WRAP_VFUNC(void realize(const Glib::RefPtr<Gdk::Surface>& surface), realize)
  _WRAP_VFUNC(void unrealize(const Glib::RefPtr<Gdk::Surface>& surface), unrealize)

  // There are no signals.
};

} // namespace Gtk
