/*
 * Unit tests for DiaCanvasItem.
 */

#include "unit-test.h"
#include "test-item.c"
#include <diacanvas/dia-canvas.h>
#include <diacanvas/dia-canvas-group.h>

DiaCanvas *canvas;
DiaCanvasItem *item;

#define DIA_FLAGS(i) (((DiaCanvasItem*) (i))->flags)

void
test_dia_canvas_item_setup (void)
{
	canvas = dia_canvas_new ();
	item = dia_canvas_item_create (TYPE_TEST_ITEM,
				       "parent", canvas->root, NULL);
	//g_object_ref (item);

	TEST (item != NULL);
	TEST (DIA_IS_CANVAS_ITEM (item));
	TEST ((DIA_FLAGS (item) & DIA_NEED_UPDATE) != 0);
	TEST (item->canvas == canvas);
	TEST (item->parent == canvas->root);
	TEST (item->bounds.left == 0.0);
	TEST (item->bounds.right == 0.0);
	TEST (item->bounds.top == 0.0);
	TEST (item->bounds.bottom == 0.0);
	TEST (item->handles == NULL);
}

void
test_dia_canvas_item_teardown (void)
{
	TEST (G_OBJECT (item)->ref_count == 2);
	if (canvas)
		g_object_unref (canvas);
	canvas = NULL;
	TEST (G_OBJECT (item)->ref_count == 1);
	if (item)
		g_object_unref (item);
	item = NULL;
}

TEST_BEGIN (DiaCanvasItem, test_dia_canvas_item_setup, test_dia_canvas_item_teardown)


TEST_NEW (dia_canvas_item_create)
{
	DiaCanvasItem *ti1 = NULL;
	DiaCanvasItem *ti2 = NULL;

	ti1 = dia_canvas_item_create (TYPE_TEST_ITEM, NULL);
	TEST (ti1->parent == NULL);
	TEST (ti1->canvas == NULL);
	TEST (G_OBJECT (ti1)->ref_count == 1);
	
	ti2 = dia_canvas_item_create (TYPE_TEST_ITEM, "parent", ti1, NULL);
	TEST (ti2->parent == ti1);
	TEST (TEST_ITEM (ti1)->children->data == (gpointer) ti2);

	TEST (G_OBJECT (ti1)->ref_count == 1);
	TEST (G_OBJECT (ti2)->ref_count == 2);

	g_object_unref (ti1);
}

TEST_NEW (notify::parent)
{
	DiaCanvasItem *ti1 = NULL;
	DiaCanvasItem *ti2 = NULL;

	ti1 = dia_canvas_item_create (TYPE_TEST_ITEM, NULL);
	ti2 = dia_canvas_item_create (TYPE_TEST_ITEM, "parent", ti1, NULL);

	g_object_set (ti1, "parent", canvas->root, NULL);
	TEST (DIA_CANVAS_ITEM (ti1)->parent == canvas->root);
	TEST (DIA_CANVAS_ITEM (ti2)->parent == ti1);
	TEST (DIA_CANVAS_ITEM (ti1)->canvas == canvas);
	g_message("%p %p %p", canvas, DIA_CANVAS_ITEM (ti1)->canvas, DIA_CANVAS_ITEM (ti2)->canvas);
	TEST (DIA_CANVAS_ITEM (ti2)->canvas == canvas);
}

TEST_NEW (dia_canvas_item_update_now)
{
	dia_canvas_item_update_now (item);
	TEST ((DIA_FLAGS (item) & DIA_NEED_UPDATE) == 0);
	TEST ((DIA_FLAGS ((DiaCanvasItem*) item->parent) & DIA_NEED_UPDATE) != 0);
	dia_canvas_item_update_now (canvas->root);
	TEST ((DIA_FLAGS ((DiaCanvasItem*) item->parent) & DIA_NEED_UPDATE) == 0);
}

TEST_NEW (dia_canvas_item_request_update)
{
	dia_canvas_item_update_now (canvas->root);
	TEST ((DIA_CANVAS_ITEM_FLAGS (canvas->root) & DIA_NEED_UPDATE) == 0);
	TEST ((DIA_CANVAS_ITEM_FLAGS (item) & DIA_NEED_UPDATE) == 0);
	TEST ((DIA_CANVAS_ITEM_FLAGS (item->parent) & DIA_NEED_UPDATE) == 0);

	dia_canvas_item_request_update (item);
	TEST ((DIA_CANVAS_ITEM_FLAGS (canvas->root) & DIA_NEED_UPDATE) != 0);
	TEST ((DIA_CANVAS_ITEM_FLAGS (item) & DIA_NEED_UPDATE) != 0);
	TEST ((DIA_CANVAS_ITEM_FLAGS (item->parent) & DIA_NEED_UPDATE) != 0);
}

TEST_NEW (DIA_COMPOSITE)
{
	DiaCanvasItem *ti1 = NULL, *ti2 = NULL;

	ti1 = dia_canvas_item_create (TYPE_TEST_ITEM, "parent", canvas->root, NULL);
	ti2 = dia_canvas_item_create (TYPE_TEST_ITEM, "parent", ti1, NULL);
	DIA_CANVAS_ITEM_FLAGS(ti2) |= DIA_COMPOSITE;

	
}

TEST_NEW (set_property)
{
	gboolean n;
	DiaCanvasItem *ti1;

	ti1 = dia_canvas_item_create (TYPE_TEST_ITEM, NULL);

	TEST_PROPERTY_NOTIFY (ti1, "parent", n);
	TEST_PROPERTY_NOTIFY (ti1, "visible", n);

	g_object_set (ti1, "parent", canvas->root, NULL);
	TEST (n == TRUE);

	n = FALSE;
	g_object_set (ti1, "visible", FALSE, NULL);
	TEST (n == TRUE);

	n = FALSE;
	g_object_set (ti1, "parent", NULL, NULL);
	TEST (n == TRUE);

	g_object_unref (ti1);
}

TEST_NEW(groupable_add/remove)
{
	DiaCanvasItem *ti1 = item;
	DiaCanvasItem *ti2 = dia_canvas_item_create (TYPE_TEST_ITEM,
						     "parent", canvas->root,
						     NULL);
	DiaCanvasItem *ti3 = dia_canvas_item_create (TYPE_TEST_ITEM,
						     "parent", canvas->root,
						     NULL);

	TEST (g_list_length (DIA_CANVAS_GROUP(canvas->root)->children) == 3);

	g_object_set (canvas, "allow_undo", TRUE, NULL);
	TEST (G_OBJECT (ti1)->ref_count == 2);
	TEST (G_OBJECT (ti2)->ref_count == 2);
	TEST (G_OBJECT (ti3)->ref_count == 2);

	dia_canvas_groupable_remove (DIA_CANVAS_GROUPABLE (canvas->root), ti1);
	/* One for ti1, one for the undo stack */
	TEST (G_OBJECT (ti1)->ref_count == 2); 

	dia_canvas_groupable_remove (DIA_CANVAS_GROUPABLE (canvas->root), ti2);
	TEST (G_OBJECT (ti2)->ref_count == 2); 
	dia_canvas_groupable_remove (DIA_CANVAS_GROUPABLE (canvas->root), ti3);
	TEST (G_OBJECT (ti3)->ref_count == 2); 

	TEST (g_list_length (DIA_CANVAS_GROUP(canvas->root)->children) == 0);

	/* Now add them in reverse order: */
	dia_canvas_groupable_add (DIA_CANVAS_GROUPABLE (canvas->root), ti3);
	dia_canvas_groupable_add (DIA_CANVAS_GROUPABLE (canvas->root), ti2);
	dia_canvas_groupable_add (DIA_CANVAS_GROUPABLE (canvas->root), ti1);

	TEST (DIA_CANVAS_GROUP(canvas->root)->children->data == ti3);
	TEST (DIA_CANVAS_GROUP(canvas->root)->children->next->data == ti2);
	TEST (DIA_CANVAS_GROUP(canvas->root)->children->next->next->data == ti1);

	g_object_set (canvas, "allow_undo", FALSE, NULL);
	dia_canvas_clear_undo (canvas);
	dia_canvas_clear_redo (canvas);
	g_object_unref (ti2);
	g_object_unref (ti3);
}

TEST_END ();
