/**
 * clutter_align_constraint_get_source:
 * @align: a #ClutterAlignConstraint
 *
 * Retrieves the source of the alignment
 *
 * Return value: (transfer none): the #ClutterActor used as the source
 *   of the alignment
 *
 * Since: 1.4
 */
ClutterActor *
clutter_align_constraint_get_source (ClutterAlignConstraint *align)
{
  g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), NULL);

  return align->source;
}
/**
 * clutter_align_constraint_get_factor:
 * @align: a #ClutterAlignConstraint
 *
 * Retrieves the factor set using clutter_align_constraint_set_factor()
 *
 * Return value: the alignment factor
 *
 * Since: 1.4
 */
gfloat
clutter_align_constraint_get_factor (ClutterAlignConstraint *align)
{
  g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), 0.0);

  return align->factor;
}
/**
 * clutter_align_constraint_get_align_axis:
 * @align: a #ClutterAlignConstraint
 *
 * Retrieves the value set using clutter_align_constraint_set_align_axis()
 *
 * Return value: the alignment axis
 *
 * Since: 1.4
 */
ClutterAlignAxis
clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
{
  g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align),
                        CLUTTER_ALIGN_X_AXIS);

  return align->align_axis;
}
/**
 * clutter_align_constraint_set_source:
 * @align: a #ClutterAlignConstraint
 * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
 *
 * Sets the source of the alignment constraint
 *
 * Since: 1.4
 */
void
clutter_align_constraint_set_source (ClutterAlignConstraint *align,
                                     ClutterActor           *source)
{
  ClutterActor *old_source, *actor;
  ClutterActorMeta *meta;

  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
  g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));

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

  meta = CLUTTER_ACTOR_META (align);
  actor = clutter_actor_meta_get_actor (meta);
  if (actor != NULL && source != 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 = align->source;
  if (old_source != NULL)
    {
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_destroyed),
                                            align);
      g_signal_handlers_disconnect_by_func (old_source,
                                            G_CALLBACK (source_position_changed),
                                            align);
    }

  align->source = source;
  if (align->source != NULL)
    {
      g_signal_connect (align->source, "allocation-changed",
                        G_CALLBACK (source_position_changed),
                        align);
      g_signal_connect (align->source, "destroy",
                        G_CALLBACK (source_destroyed),
                        align);

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

  g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]);
}
/**
 * clutter_align_constraint_set_factor:
 * @align: a #ClutterAlignConstraint
 * @factor: the alignment factor, between 0.0 and 1.0
 *
 * Sets the alignment factor of the constraint
 *
 * The factor depends on the #ClutterAlignConstraint:align-axis property
 * and it is a value between 0.0 (meaning left, when
 * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or
 * meaning top, when #ClutterAlignConstraint:align-axis is set to
 * %CLUTTER_ALIGN_Y_AXIS) and 1.0 (meaning right, when
 * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or
 * meaning bottom, when #ClutterAlignConstraint:align-axis is set to
 * %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either
 * cases
 *
 * Since: 1.4
 */
void
clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
                                     gfloat                  factor)
{
  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));

  align->factor = CLAMP (factor, 0.0, 1.0);

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

  _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_FACTOR]);
}
/**
 * clutter_align_constraint_set_align_axis:
 * @align: a #ClutterAlignConstraint
 * @axis: the axis to which the alignment refers to
 *
 * Sets the axis to which the alignment refers to
 *
 * Since: 1.4
 */
void
clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
                                         ClutterAlignAxis        axis)
{
  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));

  if (align->align_axis == axis)
    return;

  align->align_axis = axis;

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

  _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_ALIGN_AXIS]);
}
/**
 * clutter_align_constraint_set_source:
 * @align: a #ClutterAlignConstraint
 * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
 *
 * Sets the source of the alignment constraint
 *
 * Since: 1.4
 */
void
clutter_align_constraint_set_source (ClutterAlignConstraint *align,
                                     ClutterActor           *source)
{
  ClutterActor *old_source;

  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
  g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));

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

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

  align->source = source;
  if (align->source != NULL)
    {
      g_signal_connect (align->source, "allocation-changed",
                        G_CALLBACK (source_position_changed),
                        align);
      g_signal_connect (align->source, "destroy",
                        G_CALLBACK (source_destroyed),
                        align);

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

  _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]);
}