#ifndef LIST_H
#define LIST_H

#include <stdlib.h>

typedef void* Pointer;
typedef unsigned int Index;

enum Position { FRONT, REAR};
typedef enum Position Position;

// The following declarations should not be used by the invoking program.
struct Element
{
	Pointer data;
	struct Element *next, *prev;
};
typedef struct Element Element;

// Creation of a list should follow this format:
// 	List list;
// The list should be passed to the list's functions like this:
//	List_Create(&list,sizeof(DATA_TYPE));
struct List
{
	Element *first, *last; 
	size_t len;
};
typedef struct List List;

void List_Create(List *, size_t);
// Creates a list.
//	List list;
//	List_Create(&list,sizeof(DATA_TYPE));
//	...
// The arguments are as follows:
//	List *list; # A pointer to a list (pass by reference)
//	size_t len; # The length of the buffer/data being stored in each 
//	 element of the list.

void List_Destroy(List *);
// Destroys a list.
//	List list;
//	...
//	List_Destroy(&list);
// Arguments are as follows:
//	List *list; # A pointer to a list (pass by reference)

void List_Insert(List*,Pointer,Position);
// Inserts a piece of data into the list.
//	List list;
//	...
//	List_Insert(&list,data,FRONT);
//	...
// Arguments are as follows:
//	List *list # A pointer to a list (pass by reference)
//	Pointer data; # A pointer to the data. A copy of the data will be made,
//	 so the data may be static (and passed by reference) or dynamic. 
//	Position pos; # The position can either be FRONT or REAR, and tells which
//	 end of the list to attach the data.

void List_Remove(List*,Index);
// Removes a specified element from the list.
//	List list;
//  ...
//	List_Remove(&list,rand() % List_Length(&list));
//	...
// Arguments are as follows:
//	List *list; # A pointer to a list (passed by reference)
//	Index pos; # The position of the element to be deleted. NOTE: Numbering
//	 starts at zero (0).

Pointer List_Position(List*,Index);
// Returns a pointer to a copy of the data found in a specified element.
//	List list;
//	int *i;
//	...
//	i = List_Length(&list);
//	...
// Arguments are as follows:
//	List *list; # A pointer to a list (passed by reference)
//	Index pos; # The position of the element to return the data of.

size_t List_Length(List*);
// Returns the number of elements found in the list.
//	List list;
//	size_t s;
//	...
//	s = List_Length(&list);
//	...
// Arguments are as follows:
//	List *list; # A pointer to the list (passed by reference)

#endif
