/* libgeglmm - a C++ wrapper for libgegl
 *
 * (c) 2008 Hubert Figuiere
 *
 * 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 3 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 GEGL; if not, see <http://www.gnu.org/licenses/>.
 */


#include <babl/babl.h>
#include <gegl.h>
#include <glibmm/refptr.h>
#include <geglmm/rectangle.h>

_DEFS(geglmm,gegl)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gegl
{

_WRAP_ENUM(Interpolation, GeglInterpolation, NO_GTYPE)

class Buffer
	: public Glib::Object
{
	_CLASS_GOBJECT(Buffer, GeglBuffer, GEGL_BUFFER, Glib::Object, GObject)
protected:
    Buffer(const Rectangle & extent, const Babl * format);
    //	_WRAP_CTOR(Buffer(const Rectangle & extent, const Babl *format), gegl_buffer_new) //TODO: Add an overload if format can be NULL, and use a const & for this one.

public:
	_WRAP_CREATE(const Rectangle & extent, const Babl *format) //TODO: Add an overload if format can be NULL, and use a const & for this one.
    _WRAP_METHOD(static Glib::RefPtr<Buffer> create_from_file(const Glib::ustring&), gegl_buffer_open)

	_WRAP_METHOD(Glib::RefPtr<Buffer> create_sub_buffer(const Rectangle & extent), gegl_buffer_create_sub_buffer) //TODO: Should this be const?
	_WRAP_METHOD(void destroy(), gegl_buffer_destroy)
	_WRAP_METHOD(Rectangle get_extent() const, gegl_buffer_get_extent)
	_WRAP_METHOD(void set_extent(const Rectangle &), gegl_buffer_set_extent)


    _WRAP_METHOD(void save(const Glib::ustring &, const Rectangle &) const, gegl_buffer_save)
    void save(const Glib::ustring &) const;
    _WRAP_METHOD(void flush(), gegl_buffer_flush)

    _WRAP_METHOD(void clear(const Rectangle &), gegl_buffer_clear)
    _WRAP_METHOD(const Babl* get_format(), gegl_buffer_get_format)

	// TODO macros
	//x
	//y
	//width
	//height
	//pixel_count

	//TODO: Add an overload if format can be NULL, and use a const & for this one.
	_WRAP_METHOD(void get(double scale, const Rectangle & rect, const Babl *format, void * dest, int rowstride) const, gegl_buffer_get)

	//TODO: Add an overload if format can be NULL, and use a const & for this one.
	_WRAP_METHOD(void set(const Rectangle & rect, const Babl *format, void *src, int rowstride), gegl_buffer_set)
	_WRAP_METHOD(void copy(const Rectangle & src_rect, const Glib::RefPtr<Buffer> & dest, const Rectangle & dest_rect), gegl_buffer_copy)
	_WRAP_METHOD(Glib::RefPtr<Buffer> dup() const, gegl_buffer_dup)

	//TODO: Add an overload if format can be NULL, and use a const & for this one.
	_WRAP_METHOD(void sample(double x, double y, double scale, void *dest, const Babl* format, Interpolation interpolation), gegl_buffer_sample)
	_WRAP_METHOD(void sample_cleanup(), gegl_buffer_sample_cleanup)
	_WRAP_METHOD(static Interpolation interpolation_from_string(const Glib::ustring & string), gegl_buffer_interpolation_from_string)

#m4 _CONVERSION(`GeglRectangle*',`const Rectangle&',`Glib::wrap($3)')
#m4 _CONVERSION(`const GeglRectangle*',`const Rectangle&',`Glib::wrap($3)')
	_WRAP_SIGNAL(void changed(const Rectangle &r), "changed", no_default_handler)

    _WRAP_METHOD(gpointer* linear_open(const Rectangle &r, gint & rowstride, const Babl *format), gegl_buffer_linear_open)
    _WRAP_METHOD(void linear_close(gpointer linear), gegl_buffer_linear_close)

    _WRAP_METHOD(const Rectangle& abyss(), gegl_buffer_get_abyss)

	// Properties
	_WRAP_PROPERTY("px-size", int)
	_WRAP_PROPERTY("pixels", int)
	_WRAP_PROPERTY("width", int)
	_WRAP_PROPERTY("height", int)
	_WRAP_PROPERTY("x", int)
	_WRAP_PROPERTY("y", int)
	_WRAP_PROPERTY("abyss-width", int)
	_WRAP_PROPERTY("abyss-height", int)
	_WRAP_PROPERTY("abyss-x", int)
	_WRAP_PROPERTY("abyss-y", int)
	_WRAP_PROPERTY("shift-x", int)
	_WRAP_PROPERTY("shift-y", int)
	_WRAP_PROPERTY("format", Babl*)
	_WRAP_PROPERTY("source", Glib::Object)
	_WRAP_PROPERTY("tile_width", int)
	_WRAP_PROPERTY("tile_height", int)
	_WRAP_PROPERTY("path", Glib::ustring)
	_WRAP_PROPERTY("backend", gpointer)
};


}
