#include "lists.h"
#include <stdlib.h>
#include <string.h>

int list_initialize(list_def *alist, int initial_size, int element_size)
{
	if (initial_size < element_size)
		initial_size = element_size;
		
	alist->first = malloc( initial_size );
	
	if (alist->first) {
		alist->count = 0;
		alist->buffer_size = initial_size;
		alist->element_size = element_size;
		alist->last = alist->first;
		return 0;
	}
	
	return 1;
}

int list_expand(list_def *alist)
{
	void *newfirst;
	int alistdiff;
	
	newfirst = realloc( alist->first, alist->buffer_size * LIST_EXP_FACT);
	
	if (newfirst) {
		alistdiff = (int)alist->last - (int)alist->first;
		alist->first = newfirst;
		alist->buffer_size = alist->buffer_size * LIST_EXP_FACT;
		alist->last = (void *)((int)newfirst + alistdiff);
		return 0;
	}
	
	return 1;
}

int list_compress(list_def *alist)
{
	void *newfirst;
	int datasize;
	
	datasize = alist->element_size*alist->count;
	newfirst = realloc(alist->first, datasize);
	if (newfirst) {
		alist->first = newfirst;
		alist->buffer_size = datasize;
		return 0;
	}
	
	return 1;
}
	
int list_add(list_def *alist, void *element)
{
	int result;
	
	if (alist->buffer_size/alist->element_size < (alist->count + 1)) {
		result = list_expand( alist );
		if (result == 1)
			return 1;
	}
	
	memcpy(alist->last, element, alist->element_size);
	
	alist->last = (void *)((char *)alist->last + alist->element_size);
	
	alist->count = alist->count + 1;
	
	return 0;
}

int list_cleanup(list_def *alist)
{
	free(alist->first);
	/*free(alist->last);*/
	alist->count = 0;
	alist->buffer_size = 0;
	alist->element_size = 0;

	return 0;
}

void *list_item(list_def *alist, int index)
{
	if (alist->buffer_size == 0)
		return 0;
		
	if (index >= alist->count)
		return 0;
	
	return (void *)((char *)alist->first + index * alist->element_size);
}
