#define	DEBUG_TREE_DEPTH

#include <v_lib.h>

typedef struct tnode_s
{
	int data;
	DEFINE_TREE_LINK(struct tnode_s)
} tnode_t, *tnode_p;

tnode_p add_node(int data,tnode_p parent)
{
	tnode_p self = (tnode_p)memAllocZ(sizeof(*self));
	LINK_TREE_NODE(self,parent);
	self->data = data;
	return self;
}

void traverse_from_root(tnode_p root,void (*proc)(tnode_p))
{
	TREE_ITERATOR;
	proc(root);
	TREE_FOR_EACH_CHILD_BACKWARD(root)
	{
		tnode_p ptr = TREE_NODE(tnode_t);
		traverse_from_root(ptr,proc);
	}
}

void traverse_from_children(tnode_p root,void (*proc)(tnode_p))
{
	TREE_ITERATOR;
	TREE_FOR_EACH_CHILD_BACKWARD(root)
	{
		tnode_p ptr = TREE_NODE(tnode_t);
		traverse_from_children(ptr,proc);
	}
	proc(root);
}

void remove_subtree(tnode_p subtree_root)
{
	TREE_ITERATOR;
	TREE_FOR_EACH_CHILD(subtree_root)
		remove_subtree(TREE_NODE(tnode_t));
	UNLINK_TREE_NODE(subtree_root);
	memFree(subtree_root);
}

void proc(tnode_p n)
{
	printf("depth: %d; data: %d\n",TREE_DEPTH(n),n->data);
}

#define	NUM_CHILD	2

tnode_p root[1];
tnode_p level1[NUM_CHILD];
tnode_p level2[NUM_CHILD][NUM_CHILD];
tnode_p level3[NUM_CHILD][NUM_CHILD][NUM_CHILD];

int main()
{
	int i,j,k;

	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	
	root[0] = add_node(0,NULL);
	for(i=0;i<NUM_CHILD;i++)
		level1[i] = add_node(10 + (i+1),root[0]);

	puts("Created levels 0 & 1:");
	traverse_from_root(root[0],proc);

	for(i=0;i<NUM_CHILD;i++)
		for(j=0;j<NUM_CHILD;j++)
			level2[i][j] = add_node(100 + 10 * (i+1) + (j+1),level1[i]);

	for(i=0;i<NUM_CHILD;i++)
		for(j=0;j<NUM_CHILD;j++)
			for(k=0;k<NUM_CHILD;k++)
				level3[i][j][k] = add_node(1000 + 100 * (i+1) + 10 * (j+1) + (k+1),level2[i][j]);

	puts("Created levels 0 & 1 & 2 & 3:");
	traverse_from_root(root[0],proc);

	remove_subtree(root[0]);

	memPrintStats();
	return 0;
}
