/*
	fifo.c

ＦＩＦＯバッファ一般アルゴリズム

	fifo_new(data_size)
	fifo_destroy(id)

	fifo_set(id, data)
	fifo_get(id, data)
	fifo_isEmpty(id)
	fifo_getLeftNum(id)

リスト一般アルゴリズム

	LIST	*list_new(int size)
	void	list_destroy(LIST *list)

	void	list_top(LIST *list)
	void	list_next(LIST *list)
	void	list_prev(LIST *list)
	void	list_moveTo(LIST *list, int index)
	int		list_getData(LIST *list, void *data)
	int		list_setData(LIST *list, void *data)
	int		list_insertData(LIST *list, void *data)
	void	list_deleteData(LIST *list)

	int		list_isOut(LIST *list)
	int		list_getDataNum(LIST *list)
	int		list_isEmpty(LIST *list)
*/

#include <stdio.h>
#include <stdlib.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <memory.h>

#include "fifo.h"

FIFO	*fifo_new(int data_size)
{
	FIFO *fifo;
	fifo = TL_calloc(1,sizeof(FIFO));
	if (fifo == NULL)
		return NULL;
	fifo->data = TL_calloc(1000, data_size);
	fifo->datanum = 0;
	fifo->datasize = data_size;
	return fifo;
}

void	fifo_destroy(FIFO *fifo)
{
	TL_free(fifo->data);
	TL_free(fifo);
}

int		fifo_set(FIFO *fifo, void *data)
{
	char *p;
	p = fifo->data + fifo->datasize*fifo->datanum;
	memcpy(p, data, fifo->datasize);
	fifo->datanum++;
	return 0;
}

int		fifo_get(FIFO *fifo, void *data)
{
	if (fifo->datanum <= 0)
		return -1;
	memcpy(data, fifo->data, fifo->datasize);
	fifo->datanum--;
	if (fifo->datanum > 0)
		memcpy(fifo->data,fifo->data+fifo->datasize,
			   fifo->datanum*fifo->datasize);
	return 0;
}

int		fifo_isEmpty(FIFO *fifo)
{
	if (fifo->datanum <= 0)
		return 1;
	else
		return 0;
}

int		fifo_getLeftNum(FIFO *fifo)
{
	return fifo->datanum;
}

/*--------------------------------------------------------*/
/*                       リスト一般                       */
/*--------------------------------------------------------*/

LIST	*list_new(int size)
{
	LIST *list;
	list = TL_calloc(1,sizeof(LIST)+sizeof(LISTE));
	if (list == NULL)
		return NULL;
	list->datanum = 0;
	list->datasize = size;
	list->outdata = (LISTE*)(list+1);
	list->cur = list->outdata;
	list->outdata->prev = list->outdata->next = list->outdata;
	list->pos = 0;
	return list;
}

void	list_destroy(LIST *list)
{
	TL_free(list);
}

void	list_top(LIST *list)
{
	if (list->datanum <= 0)
		return;
	list->cur = list->outdata->next;
	list->pos = 0;
}

void	list_next(LIST *list)
{
	if (list->pos >= list->datanum)
		return;
	list->pos++;
	list->cur = list->cur->next;
}

void	list_prev(LIST *list)
{
	if (list->pos < 0)
		return;
	list->pos--;
	list->cur = list->cur->prev;
}

void	list_moveTo(LIST *list, int index)
{
	int i;
	i = index - list->pos;
	for (;i>0;i--)
		list_next(list);
	for (;i<0;i++)
		list_prev(list);
}

int		list_getData(LIST *list, void *data)
{
	if (list->pos < 0 || list->datanum <= list->pos)
		return -1;
	memcpy(data, list->cur+1, list->datasize);
	return 0;
}

int		list_setData(LIST *list, void *data)
{
	if (list->pos < 0 || list->datanum <= list->pos)
		return -1;
	memcpy(list->cur+1, data, list->datasize);
	return 0;
}

int		list_insertData(LIST *list, void *data)
{
	LISTE *le;
	if (list->pos < 0)
		return -1;
	le = TL_calloc(1, sizeof(LISTE) + list->datasize);
	if (le == NULL)
		return -1;
	memcpy(le+1,data,list->datasize);
	/*
		旧：	□			→	□		→		□
				cur->prev	←	cur		←		cur->next
			
		新：	□			→	□		→		□		→		□
				cur->prev	←	le		←		cur		←		cur->next
								(cur->prev)		(cur)			(cur->next)
	*/
	le->next = list->cur;
	le->prev = list->cur->prev;
	list->cur->prev->next = le;
	list->cur->prev = le;
	list->pos++;
	list->datanum++;
	return 0;
}

int		list_deleteData(LIST *list)
{
	LISTE *e;
	if (list->pos < 0 || list->datanum <= list->pos)
		return -1;
	list->cur->prev->next = list->cur->next;
	list->cur->next->prev = list->cur->prev;
	e = list->cur;
	list->cur = list->cur->next;
	TL_free(e);
	list->datanum--;
	return 0;
}

int		list_isOut(LIST *list)
{
	if (list->pos < 0 || list->datanum <= list->pos)
		return 1;
	else
		return 0;
}

int		list_getDataNum(LIST *list)
{
	return list->datanum;
}

int		list_isEmpty(LIST *list)
{
	if (list->datanum == 0)
		return 1;
	else
		return 0;
}

