/**
 * clutter_bind_constraint_get_source:
 * @constraint: a #ClutterBindConstraint
 *
 * Retrieves the #ClutterActor set using clutter_bind_constraint_set_source()
 *
 * Return value: (transfer none): a pointer to the source actor
 *
 * Since: 1.4
 */
ClutterActor *
clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
{
  g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), NULL);

  return constraint->source;
}
/**
 * clutter_bind_constraint_get_offset:
 * @constraint: a #ClutterBindConstraint
 *
 * Retrieves the offset set using clutter_bind_constraint_set_offset()
 *
 * Return value: the offset, in pixels
 *
 * Since: 1.4
 */
gfloat
clutter_bind_constraint_get_offset (ClutterBindConstraint *bind)
{
  g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (bind), 0.0);

  return bind->offset;
}
/**
 * clutter_bind_constraint_get_coordinate:
 * @constraint: a #ClutterBindConstraint
 *
 * Retrieves the bound coordinate of the constraint
 *
 * Return value: the bound coordinate
 *
 * Since: 1.4
 */
ClutterBindCoordinate
clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
{
  g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint),
                        CLUTTER_BIND_X);

  return constraint->coordinate;
}
/**
 * clutter_bind_constraint_set_source:
 * @constraint: a #ClutterBindConstraint
 * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
 *
 * Sets the source #ClutterActor for the constraint
 *
 * Since: 1.4
 */
void
clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
                                    ClutterActor          *source)
{
  ClutterActor *old_source, *actor;
  ClutterActorMeta *meta;

  g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));
  g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));

  if (constraint->source == source)
    return;

  meta = CLUTTER_ACTOR_META (constraint);
  actor = clutter_actor_meta_get_actor (meta);
  if (source != NULL && actor != NULL)
    {
      if (clutter_actor_contains (actor, source))
        {
          g_warning (G_STRLOC ": The source actor '%s' is contained "
                     "by the actor '%s' associated to the constraint "
                     "'%s'",
                     _clutter_actor_get_debug_name (source),
                     _clutter_actor_get_debug_name (actor),
                     _clutter_actor_meta_get_debug_name (meta));
          return;
        }
    }

  old_source = constraint->source;
  if (old_source != NULL)
    {
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_destroyed),
                                            constraint);
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_queue_relayout),
                                            constraint);
    }

  constraint->source = source;
  if (constraint->source != NULL)
    {
      g_signal_connect (constraint->source, "queue-relayout",
                        G_CALLBACK (source_queue_relayout),
                        constraint);
      g_signal_connect (constraint->source, "destroy",
                        G_CALLBACK (source_destroyed),
                        constraint);

      if (constraint->actor != NULL)
        clutter_actor_queue_relayout (constraint->actor);
    }

  g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]);
}
/**
 * clutter_bind_constraint_set_offset:
 * @constraint: a #ClutterBindConstraint
 * @offset: the offset to apply, in pixels
 *
 * Sets the offset to be applied to the constraint
 *
 * Since: 1.4
 */
void
clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
                                    gfloat                 offset)
{
  g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));

  if (fabs (constraint->offset - offset) < 0.00001f)
    return;

  constraint->offset = offset;

  if (constraint->actor != NULL)
    clutter_actor_queue_relayout (constraint->actor);

  g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]);
}
/**
 * clutter_bind_constraint_set_coordinate:
 * @constraint: a #ClutterBindConstraint
 * @coordinate: the coordinate to bind
 *
 * Sets the coordinate to bind in the constraint
 *
 * Since: 1.4
 */
void
clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
                                        ClutterBindCoordinate  coordinate)
{
  g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));

  if (constraint->coordinate == coordinate)
    return;

  constraint->coordinate = coordinate;

  if (constraint->actor != NULL)
    clutter_actor_queue_relayout (constraint->actor);

  g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_COORDINATE]);
}
/**
 * clutter_bind_constraint_set_source:
 * @constraint: a #ClutterBindConstraint
 * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
 *
 * Sets the source #ClutterActor for the constraint
 *
 * Since: 1.4
 */
void
clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
                                    ClutterActor          *source)
{
  ClutterActor *old_source;

  g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));
  g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));

  if (constraint->source == source)
    return;

  old_source = constraint->source;
  if (old_source != NULL)
    {
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_destroyed),
                                            constraint);
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_queue_relayout),
                                            constraint);
    }

  constraint->source = source;
  if (constraint->source != NULL)
    {
      g_signal_connect (constraint->source, "queue-relayout",
                        G_CALLBACK (source_queue_relayout),
                        constraint);
      g_signal_connect (constraint->source, "destroy",
                        G_CALLBACK (source_destroyed),
                        constraint);

      if (constraint->actor != NULL)
        clutter_actor_queue_relayout (constraint->actor);
    }

  g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]);
}