/* Copyright (C) 2025 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/>.
 */

using Category = Gsk::Transform::Category;

namespace Gsk
{
// static
Glib::RefPtr<Transform> Transform::create(const Glib::ustring& string)
{
  GskTransform* out_transform = nullptr;
  (void)gsk_transform_parse(string.c_str(), &out_transform);
  return Glib::wrap(out_transform);
}

Glib::RefPtr<Transform> Transform::transform(const Glib::RefPtr<const Transform>& other) const
{
  reference(); // gsk_transform_transform() consumes a reference.
  return Glib::wrap(gsk_transform_transform(const_cast<GskTransform*>(gobj()), const_cast<GskTransform*>(Glib::unwrap(other))));
}
Glib::RefPtr<Transform> Transform::invert() const
{
  reference(); // gsk_transform_invert() consumes a reference.
  return Glib::wrap(gsk_transform_invert(const_cast<GskTransform*>(gobj())));
}

Glib::RefPtr<Transform> Transform::matrix_2d(float xx, float yx, float xy, float yy, float dx, float dy) const
{
  reference(); // gsk_transform_matrix_2d() consumes a reference.
  return Glib::wrap(gsk_transform_matrix_2d(const_cast<GskTransform*>(gobj()), xx, yx, xy, yy, dx, dy));
}

Glib::RefPtr<Transform> Transform::translate(const Gdk::Graphene::Point& point) const
{
  reference(); // gsk_transform_translate() consumes a reference.
  return Glib::wrap(gsk_transform_translate(const_cast<GskTransform*>(gobj()), (point).gobj()));
}

Glib::RefPtr<Transform> Transform::skew(float skew_x, float skew_y) const
{
  reference(); // gsk_transform_skew() consumes a reference.
  return Glib::wrap(gsk_transform_skew(const_cast<GskTransform*>(gobj()), skew_x, skew_y));
}

Glib::RefPtr<Transform> Transform::rotate(float angle) const
{
  reference(); // gsk_transform_rotate() consumes a reference.
  return Glib::wrap(gsk_transform_rotate(const_cast<GskTransform*>(gobj()), angle));
}

Glib::RefPtr<Transform> Transform::scale(float factor_x, float factor_y) const
{
  reference(); // gsk_transform_scale() consumes a reference.
  return Glib::wrap(gsk_transform_scale(const_cast<GskTransform*>(gobj()), factor_x, factor_y));
}

Glib::RefPtr<Transform> Transform::scale_3d(float factor_x, float factor_y, float factor_z) const
{
  reference(); // gsk_transform_scale_3d() consumes a reference.
  return Glib::wrap(gsk_transform_scale_3d(const_cast<GskTransform*>(gobj()), factor_x, factor_y, factor_z));
}

Glib::RefPtr<Transform> Transform::perspective(float depth) const
{
  reference(); // gsk_transform_perspective() consumes a reference.
  return Glib::wrap(gsk_transform_perspective(const_cast<GskTransform*>(gobj()), depth));
}

Gdk::Graphene::Rect Transform::transform_bounds(const Gdk::Graphene::Rect& rect) const
{
  graphene_rect_t* g_out_rect = graphene_rect_alloc();
  gsk_transform_transform_bounds(const_cast<GskTransform*>(gobj()), (rect).gobj(), g_out_rect);
  return Glib::wrap(g_out_rect);
}

Gdk::Graphene::Point Transform::transform_point(const Gdk::Graphene::Point& point) const
{
  graphene_point_t* g_out_point = graphene_point_alloc();
  gsk_transform_transform_point(const_cast<GskTransform*>(gobj()), (point).gobj(), g_out_point);
  return Glib::wrap(g_out_point);
}
} // namespace Gsk
