/*
 * Copyright (C) 2009 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as 
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by Mirco Müller <mirco.mueller@canonical.com>
 *
 */

#include <glib.h>
#include <stdlib.h>
#include <clutk/clutk.h>

static void test_allocation (void);
static void test_properties (void);
static void test_paint      (void);

void
test_effect_drop_shadow_create_suite (void)
{
#define DOMAIN "/EffectDropShadow"

  g_test_add_func (DOMAIN"/Allocation", test_allocation);
  g_test_add_func (DOMAIN"/Properties", test_properties);
  g_test_add_func (DOMAIN"/Paint", test_paint);
}

static void
test_allocation (void)
{
  CtkEffectDropShadow* drop_shadow;

  /* Check it allocates */
  drop_shadow = ctk_effect_drop_shadow_new (1, 0, 0);

  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow));

  /* Check default actor == NULL */
  g_assert (ctk_effect_get_actor (CTK_EFFECT (drop_shadow)) == NULL);

  /* clean up */
  g_object_unref (drop_shadow);
  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow) == FALSE);
}

static void
test_properties (void)
{
  CtkEffectDropShadow* drop_shadow;

  drop_shadow = ctk_effect_drop_shadow_new (4, 2, 3);
  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow));

  /* verify initially set property values */
  g_assert_cmpuint (ctk_effect_drop_shadow_get_blur_factor (drop_shadow), ==, 4);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_x (drop_shadow), ==, 2);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_y (drop_shadow), ==, 3);

  /* Check set/get for size */
  ctk_effect_drop_shadow_set_blur_factor (drop_shadow, 1);
  g_assert_cmpuint (ctk_effect_drop_shadow_get_blur_factor (drop_shadow), ==, 1);

  /* Check set/get for offset-x */
  ctk_effect_drop_shadow_set_offset_x (drop_shadow, -12);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_x (drop_shadow), ==, -12);

  /* Check set/get for offset-y */
  ctk_effect_drop_shadow_set_offset_y (drop_shadow, 42);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_y (drop_shadow), ==, 42);

  /* Feed out-of-bounds values to size setter */
  ctk_effect_drop_shadow_set_blur_factor (drop_shadow, CTK_EFFECT_DROP_SHADOW_MAX_SIZE + 1);
  g_assert_cmpuint (ctk_effect_drop_shadow_get_blur_factor (drop_shadow), ==, 1);
  ctk_effect_drop_shadow_set_blur_factor (drop_shadow, CTK_EFFECT_DROP_SHADOW_MIN_SIZE - 1);
  g_assert_cmpuint (ctk_effect_drop_shadow_get_blur_factor (drop_shadow), ==, 1);

  /* Feed out-of-bounds values to offset-x setter */
  ctk_effect_drop_shadow_set_offset_x (drop_shadow, CTK_EFFECT_DROP_SHADOW_MAX_OFFSET_X + 1);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_x (drop_shadow), ==, -12);
  ctk_effect_drop_shadow_set_offset_x (drop_shadow, CTK_EFFECT_DROP_SHADOW_MIN_OFFSET_X - 1);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_x (drop_shadow), ==, -12);

  /* Feed out-of-bounds values to offset-y setter */
  ctk_effect_drop_shadow_set_offset_y (drop_shadow, CTK_EFFECT_DROP_SHADOW_MAX_OFFSET_Y + 1);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_y (drop_shadow), ==, 42);
  ctk_effect_drop_shadow_set_offset_y (drop_shadow, CTK_EFFECT_DROP_SHADOW_MIN_OFFSET_Y - 1);
  g_assert_cmpint (ctk_effect_drop_shadow_get_offset_y (drop_shadow), ==, 42);

  /* clean up */
  g_object_unref (drop_shadow);
  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow) == FALSE);
}

static void
test_paint (void)
{
  CtkEffectDropShadow* drop_shadow;

  drop_shadow = ctk_effect_drop_shadow_new (4, 2, 3);
  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow));

  /* Make sure our test paint function is called (will warn if actor == NULL) */
  if (g_test_trap_fork (0,
                         G_TEST_TRAP_SILENCE_STDOUT|G_TEST_TRAP_SILENCE_STDERR))
  ctk_effect_paint (CTK_EFFECT (drop_shadow), clutter_actor_paint, TRUE);
  g_test_trap_assert_failed ();

  /* clean up */
  g_object_unref (drop_shadow);
  g_assert (CTK_IS_EFFECT_DROP_SHADOW (drop_shadow) == FALSE);
}
