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

typedef struct node
{
	char Character;
	struct node *Next;
	struct node *Prev;
}node;

// TODO: change all the function to use a dlinked list
node *alloc_node(char c, node *Next, node *Prev)
{
  	node *NewNode = malloc(sizeof(node));
  	NewNode->Character = c;
  	NewNode->Next = Next;
      
	return NewNode;
}

// TIP: In the next 2 function you probably need to check for null-pointers
// NOTE: adds an element to the beginning
void list_add(node **Head, char c)
{
  	node *NewNode = alloc_node(c, *Head, 0);
  	*Head = NewNode;
}

// NOTE: inserts after a specific node
void list_insert_after(node *Node, char c)
{
  	node *NewNode = alloc_node(c, Node->Next, 0);
  	Node->Next = NewNode;
}

// NOTE: get's a node with the specified character
node *list_get(node **Head, char c)
{
  	node *Result;
	for(node *Iter = *Head; Iter; Iter = Iter->Next)
	{
		if(Iter->Character == c)
		{
			Result = Iter;
			break; 
		}
	}
	return Result;
}

// NOTE: removes a specific node from the list 
void list_remove(node **Head, node *Node)
{
	// NOTE: this should get simpler
  	// Find prev node
  	node *Prev = 0;
  	for(node *Iter = *Head; Iter; Iter = Iter->Next)
	{
		if(Iter == Node)
			break; 
		Prev = Iter;
	}
  	if(Prev)
		Prev->Next = Node->Next;
	free(Node); 	
}

// NOTE: frees the whole list
void list_free(node **Head)
{
	for(node *Iter = *Head; Iter; )
	{
		node *ToFree = Iter;
		Iter = Iter->Next;
      
		free(ToFree);
	}
}

int main(int argc, char **argv)
{
	node *Head = 0;

	list_add(&Head, 'c');
	list_add(&Head, 'y');
	list_add(&Head, 'b');
	
	node *ToBeRemoved = list_get(&Head, 'y');
	list_remove(&Head, ToBeRemoved);

	list_add(&Head, 'a');
	node *InsertAfter = list_get(&Head, 'c');
	list_insert_after(InsertAfter, 'd');

	// NOTE: prints out the whole list
	for(node *Iter = Head; Iter; Iter = Iter->Next)
	{
		printf("%c ", Iter->Character);
	}
	printf("\n");

	// NOTE: prints out the previous Node of B, B and the next one
	node *B = list_get(&Head, 'b');
	if(B)
	{
		printf("%s %c %s\n",B->Prev? B->Prev: "Null", B->Character, B->Next? B->Next: "Null");
	}
	
	list_free(&Head);
	
}
