#include "zf.h"

/*
  Add an item to a list.

*/
GList*
zf_list_add_data(GList* list,
		 void* data,
		 ZfSmartPointer* smart_pointer)
{
    list = g_list_prepend(list, data);
    //  printf("adding %p to list \n", data);
    smart_pointer->reference(data);

    return list;
}

/*
  Perform a function for every valid item object

*/
void
zf_list_foreach_valid(GList* list,
		      ZfSmartPointer* smart_pointer,
		      void (* func)(void* data))
{
    GList* li;
    
    for (li = list; li; li = li->next)
	if(li->data)   /* is this necessary? something else is wrong */
	{
	    if (smart_pointer->is_valid(li->data))
		func(li->data);
	}
	else
	{
	    printf("what the heck is happening? foreach valid \n");
	    fflush(stdout);
	}
}

/*
  Perform a function for every valid pair of item objects

*/
void
zf_list_foreach_valid_pair(GList* list,
			   ZfSmartPointer* smart_pointer,
			   void (* func)(void* data0, void* data1))
{
    GList* li;

    for (li = list; li; li = li->next)
    {
	if(li->data)   /* is this necessary? something else is wrong */
	{
	    if (smart_pointer->is_valid(li->data))
	    {
		GList* lj;
		
		for (lj = li->next; lj; lj = lj->next)
		{
		    if(lj->data)   /* is this necessary? something else is wrong */
			if (smart_pointer->is_valid(lj->data))
			    func(li->data, lj->data);
		}
	    }
	}
	else
	{
	    printf("what the heck is happening? valid pair\n");
	    fflush(stdout);
	}
    }
}
/*
  Perform a function for every valid pair of item objects in TWO LISTS
  (OMG!)

*/
void
zf_list_foreach_valid_twisted_pair(GList* list0,
				   ZfSmartPointer* smart_pointer0,
				   GList* list1,
				   ZfSmartPointer* smart_pointer1,
				   void (* func)(void* data0, void* data1))
{
    GList* li;

    for (li = list0; li; li = li->next)
    {
	if(li->data)   /* is this necessary? something else is wrong */
	{	
	    if (smart_pointer0->is_valid(li->data))
	    {
		GList* lj;
		
		for (lj = list1; lj; lj = lj->next)
		{
		    if(lj->data)   /* is this necessary? something else is wrong */
			if (smart_pointer1->is_valid(lj->data))
			    func(li->data, lj->data);
		}
	    }
	}
    	else
	{
	    printf("what the heck is happening? twisted pair\n");
	    fflush(stdout);
	}
    }
}


/*
  Remove invalid items from a list.

*/
GList*
zf_list_remove_invalids(GList* list,
			ZfSmartPointer* smart_pointer)
{
    GList* li;

    li = list;
    
    while(li)
    {
	if(li->data)   /* is this necessary? something else is wrong */
	{
	    if (smart_pointer->is_valid(li->data))
	    {
		li = li->next;
	    }
	    
	    else
	    {
		GList* li_next;
		
		li_next = li->next;
		
		list = g_list_remove_link(list, li);
		
		smart_pointer->release(li->data);
		
		li = li_next;
	    }
	}
	else 
	{
	    GList* li_next;
	    
	    li_next = li->next;
	    
	    list = g_list_remove_link(list, li);
		
	    li = li_next;

	    printf("what the heck is happening - remove invalids?\n");
	    fflush(stdout);
	}
    }

    return list;  
}

/*
  Destroy list

*/
void
zf_list_destroy(GList* list,
		ZfSmartPointer* smart_pointer)
{
    
    g_list_foreach(list, (GFunc)smart_pointer->release, 0);
    g_list_free(list);
}
