/*
 *	File:					MUI_lists.h
 *	Description:	A set of functions for manipulating MUI and Exec lists.
 *
 *	(C) 1993 Ketil Hunn
 *
 */

#include <exec/memory.h>

struct EventNode *AddEvent(Object *list, char *name)
{
	struct EventNode *eventnode;
	DoMethod(app, MUIM_Application_InputBuffered);

	if(eventnode=AllocMem(sizeof(struct EventNode), MEMF_ANY|MEMF_CLEAR))
	{
		strcpy(eventnode->name,name);
		if(eventnode->textlist=AllocMem(sizeof(struct List), MEMF_ANY|MEMF_CLEAR))
		{
			NewList(eventnode->textlist);
			DoMethod(list, MUIM_List_Insert, &eventnode, 1);
		}
	}
	return eventnode;
}

struct Node *AddText(struct List *list, char *name, LONG pos)
{
	struct Node *newnode, *node=list->lh_Head;

	if(newnode=AllocMem(sizeof(struct Node), MEMF_ANY|MEMF_CLEAR))
	{
		newnode->ln_Name=strdup(name);
		if(pos==MUIV_List_Insert_Bottom)
			AddTail(list, newnode);
		else if(pos==MUIV_List_Insert_Top)
			AddHead(list, newnode);
		else
		{
			while(pos--)
				node=node->ln_Succ;
			Insert(list, newnode, node);
		}
	}
	return newnode;
}

void DeleteEvent(Object *list, LONG pos)
{
	struct EventNode *node;

	DoMethod(list, MUIM_List_GetEntry, pos, &node);
	DoMethod(list, MUIM_List_Remove, pos);
	FreeTextList(node->textlist);
	FreeMem(node->textlist, sizeof(struct List));
	FreeMem(node, sizeof(struct EventNode));
}

void DeleteText(struct List *list, LONG pos)
{
	struct Node *node=list->lh_Head;

	while(pos--)
		node=node->ln_Succ;
	Remove(node);
	free(node->ln_Name);
	FreeMem(node, sizeof(struct Node));
}

void FreeEventList(void)
{
	struct EventNode *node;
	ULONG pos=0;

	while(TRUE)
	{
		DoMethod(eventlist, MUIM_List_GetEntry, pos++, &node);
		if(!node)
		  break;
		FreeTextList(node->textlist);
		FreeMem(node->textlist, sizeof(struct List));
		FreeMem(node,sizeof(struct EventNode));
	}
	DoMethod(eventlist,MUIM_List_Clear);
}

void FreeTextList(struct List *list)
{
	struct Node *node;

	while(!IsListEmpty(list))
	{
		node=list->lh_Head;
		RemHead(list);
		free(node->ln_Name);
		FreeMem(node, sizeof(struct Node));
	}
}

// Returns the number of entries in a given list
__inline ULONG Count(Object *list)
{
	ULONG count;

	get(list, MUIA_List_Entries, &count);
	return count;
}

void Up(Object *list)
{
	ULONG pos=Active(list);

	DoMethod(list, MUIM_List_Exchange,pos,pos--);
	set(list,MUIA_List_Active, pos);
}

void Down(Object *list)
{
	ULONG pos=Active(list);

	DoMethod(list, MUIM_List_Exchange,	pos,pos++);
	set(list,MUIA_List_Active, pos);
}

void Top(Object *list)
{
	ULONG pos=Active(list);
	APTR	*node;

	DoMethod(list, MUIM_List_GetEntry, pos, &node);
	DoMethod(list, MUIM_List_Remove, pos);
	DoMethod(list, MUIM_List_Insert, &node, 1, MUIV_List_Insert_Top);
	set(list, MUIA_List_Active, MUIV_List_Active_Top);
}

void Bottom(Object *list)
{
	ULONG pos=Active(list);
	APTR	*node;

	DoMethod(list, MUIM_List_GetEntry, pos, &node);
	DoMethod(list, MUIM_List_Remove, pos);
	DoMethod(list, MUIM_List_Insert, &node, 1, MUIV_List_Insert_Bottom);
	set(list, MUIA_List_Active, MUIV_List_Active_Bottom);
}

struct EventNode *CopyEvent(Object *list)
{
	struct EventNode *dest, *source;
	struct Node *node;
	long pos=Active(list);

	if(dest=AllocMem(sizeof(struct EventNode), MEMF_ANY|MEMF_CLEAR))
	{
		DoMethod(list, MUIM_List_GetEntry, pos, &source);
		memcpy(dest, source, sizeof(struct EventNode));
		DoMethod(list, MUIM_List_Insert, &dest, 1, pos);
		set(list, MUIA_List_Active, pos+1);
		if(dest->textlist = AllocMem(sizeof(struct List), MEMF_ANY|MEMF_CLEAR))
		{
			NewList(dest->textlist);
			for(node=source->textlist->lh_Head; node->ln_Succ; node=node->ln_Succ)
				AddText(dest->textlist, node->ln_Name, MUIV_List_Insert_Bottom);
			return dest;
		}
	}
	return NULL;
}

void UpdateTextList(Object *source, struct List *dest)
{
	LONG i;
	char *string;

	FreeTextList(dest);
	for(i=0;;i++)
	{
		DoMethod(source, MUIM_List_GetEntry, i, &string);
		if(!string)
			break;
		AddText(dest, string, MUIV_List_Insert_Bottom);
	}
}

void SortByDate(Object *list)
{
	struct EventNode *first, *second;
	long pos, i, j;
	long count=Count(list);
	BOOL swap;

	set(eventlist, MUIA_List_Quiet, TRUE);
	set(window, MUIA_Window_Sleep, TRUE);
	for(i=0; i<count; i++)
	{
		DoMethod(eventlist, MUIM_List_GetEntry, pos=0, &first);
		for(j=1; j<count; j++)
		{
			DoMethod(eventlist, MUIM_List_GetEntry, ++pos, &second);
			swap=FALSE;
			if(first->year>second->year)
				swap=TRUE;
			else if(first->year==second->year)
				if(first->month>second->month)
					swap=TRUE;
				else if(first->month==second->month)
					if(first->day>second->day)
						swap=TRUE;
					else if(first->day==second->day)
						if(first->hour>second->hour)
							swap=TRUE;
						else if(first->hour==second->hour)
							if(first->minutes>second->minutes)
								swap=TRUE;
			if(swap==TRUE)
				DoMethod(list, MUIM_List_Exchange, pos, pos-1);
			else
				first=second;
		}
	}
	set(eventlist, MUIA_List_Quiet, FALSE);
	set(window, MUIA_Window_Sleep, FALSE);
}
