/* Copyright (C) 2019 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 <gtkmm/constrainttarget.h>
#include <gtk/gtk.h>

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

namespace Gtk
{

/** The description of a constraint.
 *
 * %Gtk::Constraint describes a constraint between an attribute on a widget
 * and another attribute on another widget, expressed as a linear equation like:
 *
 *   target.attr1 = source.attr2 × multiplier + constant
 *
 * Each %Constraint is part of a system that will be solved by a
 * Gtk::ConstraintLayout in order to allocate and position each child widget.
 *
 * A %Constraint is immutable once it's created.
 *
 * @newin{3,96}
 */
class GTKMM_API Constraint : public Glib::Object
{
  _CLASS_GOBJECT(Constraint, GtkConstraint, GTK_CONSTRAINT, Glib::Object, GObject, , , GTKMM_API)
  _DO_NOT_DERIVE_GTYPE dnl// GtkConstraint is a final type
  _ABI_AS_WITH_DERIVED_GTYPE dnl// Remove when we can break ABI
  _STRUCT_NOT_HIDDEN

public:
  _WRAP_ENUM(Attribute, GtkConstraintAttribute, decl_prefix GTKMM_API)
  _WRAP_ENUM(Relation, GtkConstraintRelation, decl_prefix GTKMM_API)
  _WRAP_ENUM(Strength, GtkConstraintStrength, CONV_TO_INT, decl_prefix GTKMM_API)

protected:
  _WRAP_CTOR(Constraint(const Glib::RefPtr<ConstraintTarget>& target,
             Attribute target_attribute, Relation relation,
             const Glib::RefPtr<ConstraintTarget>& source, Attribute  source_attribute,
             double multiplier, double constant, int strength), gtk_constraint_new)
  _WRAP_CTOR(Constraint(const Glib::RefPtr<ConstraintTarget>& target,
             Attribute target_attribute, Relation relation,
             double constant, int strength), gtk_constraint_new_constant)

public:
  /** Creates a new %Gtk::Constraint representing a relation between a layout
   * attribute on a source and a layout attribute on a target.
   *
   * @param target A Gtk::ConstraintTarget or an empty Glib::RefPtr.
   * @param target_attribute The attribute of @a target to be set.
   * @param relation The relation equivalence between @a target_attribute and @a source_attribute.
   * @param source A Gtk::ConstraintTarget or an empty Glib::RefPtr.
   * @param source_attribute The attribute of @a source to be read.
   * @param multiplier A multiplication factor to be applied to @a source_attribute.
   * @param constant A constant to be added to @a source_attribute.
   * @param strength The strength of the constraint.
   * @return The newly created %Gtk::Constraint.
   */
  _WRAP_CREATE(const Glib::RefPtr<ConstraintTarget>& target, Attribute target_attribute,
               Relation relation, const Glib::RefPtr<ConstraintTarget>& source,
               Attribute source_attribute, double multiplier, double constant, int strength)

  /** Creates a new %Gtk::Constraint representing a relation between a layout
   * attribute on a target and a constant value.
   *
   * @param target A Gtk::ConstraintTarget or an empty Glib::RefPtr.
   * @param target_attribute The attribute of @a target to be set.
   * @param relation The relation equivalence between @a target_attribute and @a constant.
   * @param constant A constant to be set on @a target_attribute.
   * @param strength The strength of the constraint.
   * @return The newly created %Gtk::Constraint.
   */
  _WRAP_CREATE(const Glib::RefPtr<ConstraintTarget>& target, Attribute target_attribute,
               Relation relation, double constant, int strength)

  _WRAP_METHOD(Glib::RefPtr<ConstraintTarget> get_target(), gtk_constraint_get_target, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const ConstraintTarget> get_target() const, gtk_constraint_get_target, refreturn, constversion)
  _WRAP_METHOD(Attribute get_target_attribute() const, gtk_constraint_get_target_attribute)
  _WRAP_METHOD(Glib::RefPtr<ConstraintTarget> get_source(), gtk_constraint_get_source, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const ConstraintTarget> get_source() const, gtk_constraint_get_source, refreturn, constversion)
  _WRAP_METHOD(Attribute get_source_attribute() const, gtk_constraint_get_source_attribute)
  _WRAP_METHOD(Relation get_relation() const, gtk_constraint_get_relation)
  _WRAP_METHOD(double get_multiplier() const, gtk_constraint_get_multiplier)
  _WRAP_METHOD(double get_constant() const, gtk_constraint_get_constant)
  _WRAP_METHOD(int get_strength() const, gtk_constraint_get_strength)
  _WRAP_METHOD(bool is_required() const, gtk_constraint_is_required)
  _WRAP_METHOD(bool is_attached() const, gtk_constraint_is_attached)
  _WRAP_METHOD(bool is_constant() const, gtk_constraint_is_constant)

  _WRAP_PROPERTY("target", Glib::RefPtr<ConstraintTarget>)
  _WRAP_PROPERTY("target-attribute", Attribute)
  _WRAP_PROPERTY("relation", Relation)
  _WRAP_PROPERTY("source", Glib::RefPtr<ConstraintTarget>)
  _WRAP_PROPERTY("source-attribute", Attribute)
  _WRAP_PROPERTY("multiplier", double)
  _WRAP_PROPERTY("constant", double)
  _WRAP_PROPERTY("strength", int)
};

} // namespace Gtk
