#include <ubixos/lists.h>
#include <lib/kmalloc.h>
#include <assert.h>

#define NULL 0x0

/* checked */
List_t * 
InitializeList()
{
	List_t *	TList;

	TList		= (List_t *)kmalloc( sizeof (List_t) );
	TList->First	= NULL;
	TList->Last	= NULL;
	return TList;
}

/* checked */
Item_t *
CreateItem()
{
	Item_t * p;
	p = (Item_t *)kmalloc(sizeof (Item_t));
	p->Next = NULL;
	p->Previous = NULL;
	p->data = (void *)kmalloc(sizeof (p->data));
	return p;
}


/* checked */
int
InsertItemAtFront(	IN List_t *TList,
			IN Item_t *kItem)
{
	if(TList->First == NULL)
	{
		TList->First		= (Item_t *)kItem;
		TList->Last	 	= (Item_t *)kItem;
		kItem->Previous 	= NULL;
		kItem->Next 		= NULL;
	}
	else
	{
		Item_t 			*FirstItem;
		FirstItem 		= (Item_t *)TList->First;
		kItem->Next		= (Item_t *)FirstItem;
		TList->First		= (Item_t *)kItem;
		FirstItem->Previous 	= (Item_t *)kItem;
	}
	return STATUS_SUCCESS;
}



 
/* checked */
int
InsertItemBetweenItems(	IN List_t * TList,
				IN Item_t * Previous,
				IN Item_t * Next,
				IN Item_t * Insert)
{
 
	if(Previous == NULL || Next == NULL)
		return STATUS_FAILURE;
	else
	{ 
		Previous->Next = Insert;
		Next->Previous = Insert;
		Insert->Previous = Previous;
		Insert->Next = Next;

	}
 
	return STATUS_SUCCESS;
}
 
 
/* checked */ 
int
RemoveItem(	IN List_t * 	TList,
		IN Item_t * 	kItem)
{
	kItem->Previous->Next = kItem->Next;
	kItem->Next->Previous = kItem->Previous;
	kItem->Previous = NULL;
	kItem->Next = NULL;
	return STATUS_SUCCESS;
}

/* checked */
int
DestroyItemsInList(IN List_t * ItemList)
{
	Item_t * z, *tmp;

	z = ItemList->Last;
	while(z != NULL)
	{
		tmp = z->Previous;
		kfree(z);
		z = tmp;
	}
	ItemList->First = NULL;
	ItemList->Last = NULL;

	return STATUS_SUCCESS;
}



int
DestroyItemList(IN List_t * ItemList)
{
	kfree(ItemList);
	return STATUS_SUCCESS;
}

/* checked */
Item_t *
GetFirstItem(IN List_t * kItem)
{
	return kItem->First;
}
 
/* checked */
Item_t *
GetLastItem(IN List_t * kItem)
{
	return kItem->Last;
}

/* checked */
List_t *
RemoveItemListBetweenItems(	IN Item_t *	Previous,
					IN Item_t *	Next)
{
	List_t * NewList;

	NewList = InitializeList();

	NewList->First = Previous->Next;
	NewList->Last = Next->Previous;

	NewList->First->Previous = NULL;
	NewList->Last->Next = NULL;

 	Previous->Next = Next;
	Next->Previous = Previous;

	return NewList;
}


/* checked */
void
InsertItemListBetweenItems(	IN Item_t *	Previous,
					IN Item_t *	Next,
					IN List_t *	Insert)
{
	assert(Previous != NULL);
	assert(Next != NULL);
 
	Previous->Next = Insert->First;
	Next->Previous = Insert->Last;
	Insert->First->Previous = Previous;
	Insert->Last->Next	= Next;
	return;
}



/*
	e = CreateItem();

	InsertItemAtFront(High, a);
	InsertItemAtFront(High, b);
	InsertItemAtFront(High, c);
	InsertItemAtFront(High, d);
	InsertItemAtFront(High, e);


	z = High->Last;
	while(z != NULL)
	{
		printf("Priority! equals %d\n", z->Priority);
		z = z->Previous;
	}





	return 0;
}
*/
