/*
 * 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 Neil Jagdish Patel <neil.patel@canonical.com>
 *
 */

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

static void test_animation (void);
static void test_signals (void);

void
test_effect_animation_create_suite (void)
{
#define DOMAIN "/Effect/Animation"

  g_test_add_func (DOMAIN"/Animation", test_animation);
  g_test_add_func (DOMAIN"/Signals", test_signals);
}

static void
test_animation (void)
{
  ClutterActor *stage;
  CtkActor     *actor;
  CtkEffect    *effect;
  gchar        *filename;

  filename = g_build_filename (TESTDIR, "ubuntu.svg", NULL);

  stage = clutter_stage_get_default ();
  clutter_actor_set_size (stage, 500, 500);

  actor = (CtkActor *)ctk_image_new_from_filename (400, filename);
  clutter_container_add_actor (CLUTTER_CONTAINER (stage),
                               CLUTTER_ACTOR (actor));
  clutter_actor_set_position (CLUTTER_ACTOR (actor), 25, 25);

  effect = ctk_effect_blur_new ();
  ctk_effect_blur_set_factor (CTK_EFFECT_BLUR (effect), 0.1f); 
  ctk_actor_add_effect (actor, effect);

  ctk_effect_animate (effect, CLUTTER_EASE_IN_SINE, 2000,
                      "factor", 9.0f,
                      "signal::completed", G_CALLBACK (clutter_main_quit), NULL,
                      NULL);
 
  clutter_actor_show_all (stage);

  clutter_main ();

  g_assert (ctk_effect_blur_get_factor (CTK_EFFECT_BLUR (effect)) == 9.0f);

  clutter_container_remove_actor (CLUTTER_CONTAINER (stage),
                                  CLUTTER_ACTOR (actor));
  
  g_free (filename);
}

typedef struct 
{
  gboolean signal;
  gboolean signal_swapped;
  gboolean signal_after;
  gboolean signal_swapped_after;

} SignalTest;

static void
on_completed (ClutterAnimation *anim, SignalTest *test)
{
  g_return_if_fail (CLUTTER_IS_ANIMATION (anim));
  g_return_if_fail (test);
  g_return_if_fail (test->signal == FALSE);

  test->signal = TRUE;
}

static void
on_swapped (SignalTest *test, ClutterAnimation *anim)
{
  g_return_if_fail (test);
  g_return_if_fail (CLUTTER_IS_ANIMATION (anim));
  g_return_if_fail (test->signal_swapped == FALSE);

  test->signal_swapped = TRUE;
}

static void
on_after (ClutterAnimation *anim, SignalTest *test)
{
  g_return_if_fail (CLUTTER_IS_ANIMATION (anim));
  g_return_if_fail (test);
  g_return_if_fail (test->signal_after == FALSE);

  test->signal_after = TRUE;
}

static void
on_swapped_after (SignalTest *test, ClutterAnimation *anim)
{
  g_return_if_fail (test);
  g_return_if_fail (CLUTTER_IS_ANIMATION (anim));
  g_return_if_fail (test->signal_swapped_after == FALSE);

  test->signal_swapped_after = TRUE;
}

static void
test_signals (void)
{
  ClutterActor     *stage;
  CtkActor         *actor;
  CtkEffect        *effect;
  gchar            *filename;
  ClutterColor      c = { 0xff, 0x00, 0x00, 0xff };
  ClutterAnimation *animation;
  SignalTest        test = { 0 };

  filename = g_build_filename (TESTDIR, "ubuntu.svg", NULL);

  stage = clutter_stage_get_default ();
  clutter_actor_set_size (stage, 500, 500);

  actor = (CtkActor *)ctk_image_new_from_filename (400, filename);
  clutter_container_add_actor (CLUTTER_CONTAINER (stage),
                               CLUTTER_ACTOR (actor));
  clutter_actor_set_position (CLUTTER_ACTOR (actor), 25, 25);

  effect = ctk_effect_glow_new ();
  ctk_effect_glow_set_factor (CTK_EFFECT_GLOW (effect), 0.0f);
  ctk_effect_glow_set_color (CTK_EFFECT_GLOW (effect), &c);
  ctk_actor_add_effect (actor, effect);

  c.green = 0xff;

  animation = ctk_effect_animate (effect, CLUTTER_EASE_IN_SINE, 1000,
    "factor", 1.0f,
    "color", &c,
    "signal::completed", G_CALLBACK (on_completed), &test,
    "signal-swapped::completed", G_CALLBACK (on_swapped), &test,
    "signal-after::completed", G_CALLBACK (on_after), &test,
    "signal-swapped-after::completed", G_CALLBACK (on_swapped_after), &test,
    "signal-after::completed", G_CALLBACK (clutter_main_quit), NULL,
    NULL);

  g_assert (ctk_effect_get_animation (effect) == animation);
 
  clutter_actor_show_all (stage);
  clutter_main ();

  /* make sure all the callbacks were called */
  g_assert (test.signal == TRUE);
  g_assert (test.signal_swapped == TRUE);
  g_assert (test.signal_after == TRUE);
  g_assert (test.signal_swapped_after == TRUE);
  
  g_assert (CLUTTER_IS_ANIMATION (animation) == FALSE);

  clutter_container_remove_actor (CLUTTER_CONTAINER (stage),
                                  CLUTTER_ACTOR (actor));

  g_free (filename);
}
