#include <stdio.h>
#include <stdlib.h>

#define IN
#define STATUS_FAILURE -1
#define STATUS_SUCCESS 0

typedef struct _item_t Item_t;
typedef struct _list_t List_t;
struct _item_t
{
	Item_t		*Previous;
	Item_t		*Next;
};

struct _list_t
{
	Item_t	*First;
	Item_t	*Last;
};


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

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

/* checked */
Item_t *
CreateItem()
{
	Item_t * p;
	p = malloc(sizeof *p);
	p->Next = NULL;
	p->Previous = NULL;
	p->Priority = 0;
	return p;
}


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


	}
	return STATUS_SUCCESS;
}



/* checked */
int
SetItemPriority(	IN Item_t * kItem,
			IN PRIORITY Priority)
{
	kItem->Priority = Priority;
	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;
		MmFreeFromNonPagedPool(z);
		z = tmp;
	}
	ItemList->First = NULL;
	ItemList->Last = NULL;

	return STATUS_SUCCESS;
}



NTSTATUS
DestroyItemList(IN List_t * ItemList)
{
	MmFreeFromNonPagedPool(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 STATUS_SUCCESS;
}



int
main()
{
	List_t * High;
	Item_t * a,b,c,d,e,z;

	High = InitializeList();

	a = CreateItem();
	b = CreateItem();
	c = CreateItem();
	d = CreateItem();
	e = CreateItem();

	SetItemPriority(a, 1);
	SetItemPriority(b, 2);
	SetItemPriority(c, 3);
	SetItemPriority(d, 4);
	SetItemPriority(e, 5);

	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;
}
