/* Copyright (C) 2023 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/enums.h>
#include <cairomm/region.h>

_DEFS(gdkmm,gdk)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gdk
{
class GDKMM_API ColorState;
class GDKMM_API GLContext;
class GDKMM_API Texture;

/** %Gdk::GLTextureBuilder is a buider used to construct Gdk::Texture objects
 * from GL textures.
 *
 * The operation is quite simple: Create a texture builder, set all the necessary
 * properties - keep in mind that property_context(), property_id(),
 * property_width(), and property_height() are mandatory - and then call
 * build() to create the new texture.
 *
 * %Gdk::GLTextureBuilder can be used for quick one-shot construction of
 * textures as well as kept around and reused to construct multiple textures.
 *
 * @newin{4,12}
 */
class GDKMM_API GLTextureBuilder : public Glib::Object
{
  _CLASS_GOBJECT(GLTextureBuilder, GdkGLTextureBuilder, GDK_GL_TEXTURE_BUILDER, Glib::Object, GObject, , , GDKMM_API)
  _DO_NOT_DERIVE_GTYPE dnl// GdkGLTextureBuilder is an internal type

protected:
  _CTOR_DEFAULT()

public:
  _WRAP_CREATE()

  _WRAP_METHOD(Glib::RefPtr<GLContext> get_context(), gdk_gl_texture_builder_get_context, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const GLContext> get_context() const, gdk_gl_texture_builder_get_context, refreturn, constversion)
  _WRAP_METHOD(void set_context(const Glib::RefPtr<GLContext>& context), gdk_gl_texture_builder_set_context)

  _WRAP_METHOD(guint get_id() const, gdk_gl_texture_builder_get_id)
  _WRAP_METHOD(void set_id(guint id), gdk_gl_texture_builder_set_id)

  _WRAP_METHOD(int get_width() const, gdk_gl_texture_builder_get_width)
  _WRAP_METHOD(void set_width(int width), gdk_gl_texture_builder_set_width)

  _WRAP_METHOD(int get_height() const, gdk_gl_texture_builder_get_height)
  _WRAP_METHOD(void set_height(int height), gdk_gl_texture_builder_set_height)

  _WRAP_METHOD(MemoryFormat get_format() const, gdk_gl_texture_builder_get_format)
  _WRAP_METHOD(void set_format(MemoryFormat format), gdk_gl_texture_builder_set_format)

  _WRAP_METHOD(bool get_has_mipmap() const, gdk_gl_texture_builder_get_has_mipmap)
  _WRAP_METHOD(void set_has_mipmap(bool has_mipmap = true), gdk_gl_texture_builder_set_has_mipmap)

  _WRAP_METHOD(void* get_sync() const, gdk_gl_texture_builder_get_sync)
  _WRAP_METHOD(void set_sync(void* sync), gdk_gl_texture_builder_set_sync)

  // ColorState is immutable. No need for a non-const get-method.
  _WRAP_METHOD(Glib::RefPtr<ColorState> get_color_state() const, gdk_gl_texture_builder_get_color_state, refreturn)
  _WRAP_METHOD(void set_color_state(const Glib::RefPtr<const ColorState>& color_state), gdk_gl_texture_builder_set_color_state)

  _WRAP_METHOD(Glib::RefPtr<Texture> get_update_texture(), gdk_gl_texture_builder_get_update_texture, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Texture> get_update_texture() const, gdk_gl_texture_builder_get_update_texture, refreturn, constversion)
  _WRAP_METHOD(void set_update_texture(const Glib::RefPtr<Texture>& texture), gdk_gl_texture_builder_set_update_texture)

  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Region> get_update_region(), gdk_gl_texture_builder_get_update_region, refreturn)
  _WRAP_METHOD(::Cairo::RefPtr<const ::Cairo::Region> get_update_region() const, gdk_gl_texture_builder_get_update_region, refreturn, constversion)
  _WRAP_METHOD(void set_update_region(const ::Cairo::RefPtr< ::Cairo::Region>& region), gdk_gl_texture_builder_set_update_region)

  /** For instance,
   * void on_gl_texture_released();
   */
  using SlotGLTextureReleased = sigc::slot<void()>;

  _WRAP_METHOD(Glib::RefPtr<Texture> build(const SlotGLTextureReleased& slot{destroy} = {}),
    gdk_gl_texture_builder_build, slot_name slot, slot_callback GLTextureBuilder_destroy_callback)

  _WRAP_PROPERTY("context", Glib::RefPtr<GLContext>)
  _WRAP_PROPERTY("format", MemoryFormat)
  _WRAP_PROPERTY("has-mipmap", bool)
  _WRAP_PROPERTY("height", int)
  _WRAP_PROPERTY("id", guint)
  //TODO: Is there a better data type than void* in property_sync()?
  //_WRAP_PROPERTY("sync", void*)
  _WRAP_PROPERTY("color-state", Glib::RefPtr<ColorState>)
  _WRAP_PROPERTY("update-region", ::Cairo::RefPtr< ::Cairo::Region>)
  _WRAP_PROPERTY("update-texture", Glib::RefPtr<Texture>)
  _WRAP_PROPERTY("width", int)

  // There are no signals or public vfuncs.
};

} // namespace Gdk
