//-------------------------------------
//
// SuperCode (c) 1996 by T.Kühn 
//
// Programmiersprache:	ANSI-C
// Projektstart:			27.12.94
//
// Modul:				Libraries/Memory/Lists
//
//-------------------------------------

/*

VOID Lib_Init();
VOID Lib_Free();
VOID Lib_Open(struct Library **Base,UBYTE *Name,ULONG Version);
VOID Lib_Close(struct Library **Base);

UBYTE *Memory_Alloc(long Size);
UBYTE *MemGfx_Alloc(long Size);
VOID Memory_Free(UBYTE **Mem);

VOID List_Init(struct tkList *List,void (*Func)() );
VOID List_AddTail(struct tkList *List,APTR Node);
VOID List_Remove(struct tkList *List,APTR Node);
VOID List_Free(struct tkList *List);
LONG List_FindNum(struct tkList *List,APTR Ptr,UBYTE *String);
APTR List_FindPtr(struct tkList *Liste,LONG Num,UBYTE *String);
LONG List_StrCmp(struct tkNode *Node1,struct tkNode *Node2);
LONG List_FuncCmp(struct FuncItem *Func1,struct FuncItem *Func2);
VOID List_QuickSort(struct tkNode **Array,register LONG Left,register LONG Right,LONG (*Func)(const void*,const void*));
VOID List_Sort(struct tkList *List,long (*Func)(const void*,const void*));
*/

//-------------------------------------

#include <clib/alib_protos.h>
#include <pragma/exec_lib.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <string.h>

#include <Struct.h>

//-------------------------------------
struct Library
	*GadToolsBase=0,
	*IntuitionBase=0,
	*LayersBase=0,
	*GfxBase=0,
	*WorkbenchBase=0,
	*CxBase=0,
	*KeymapBase=0,
	*LocaleBase=0,
	*UtilityBase=0,
	*IFFParseBase=0,
	*AslBase=0;


//-------------------------------------
VOID Lib_Open(struct Library **Base,UBYTE *Name,ULONG Version)
{
	ULONG ThisVersion=Version;
	ULONG err;

	do	{	err=ASK_CONT;
			(*Base)=OpenLibrary(Name,0);
			ThisVersion=(*Base)->lib_Version;

			if (!(*Base)) err=display_error(ERR_LIB,ASK_EXIT|ASK_AGAIN|ASK_CONT,Name,Version);
			else if (ThisVersion<Version) err=display_error(ERR_LIB2,ASK_EXIT|ASK_AGAIN|ASK_CONT,Name,Version,ThisVersion)

		} while(err==ASK_AGAIN)
}
//-------------------------------------
VOID Lib_Close(struct Library **Base)
{
	if (*Base) { CloseLibrary(*Base);*Base=0; }
}
//-------------------------------------
UBYTE *Memory_Alloc(long Size)
{
	APTR Ptr=0;
	if (Size)
	{
		do	{ Ptr=AllocVec(Size,MEMF_CLEAR);
			} while((!Ptr) && ASK_AGAIN==display_error(ERR_MEM,ASK_EXIT|ASK_AGAIN,Size))
	}
	return(Ptr);
}
//-------------------------------------
UBYTE *MemGfx_Alloc(long Size)
{
	APTR Ptr=0;

	if (Size)
	{
		do	{ Ptr=AllocVec(Size,MEMF_CLEAR|MEMF_CHIP);
			} while((!Ptr) && ASK_AGAIN==display_error(ERR_MEMC,ASK_EXIT|ASK_AGAIN,Size))
	}

	return(Ptr);
}
//-------------------------------------
VOID Memory_Free(UBYTE **Mem)
{
	if (Mem && (*Mem) )
	{
		FreeVec( (*Mem) );
		(*Mem)=0;
	}
}
//-------------------------------------
VOID Lib_Init()
{
	Lib_Open(&IntuitionBase,"intuition.library",LibVersion);
	Lib_Open(&GfxBase,"graphics.library",LibVersion);
	Lib_Open(&LayersBase,"layers.library",LibVersion);
	Lib_Open(&GadToolsBase,"gadtools.library",LibVersion);
	Lib_Open(&WorkbenchBase,"workbench.library",LibVersion);
	Lib_Open(&CxBase,"commodities.library",LibVersion);
	Lib_Open(&KeymapBase,"keymap.library",LibVersion);
	Lib_Open(&LocaleBase,"locale.library",LibVersion);
	Lib_Open(&UtilityBase,"utility.library",LibVersion);
	Lib_Open(&IFFParseBase,"iffparse.library",LibVersion);
	Lib_Open(&AslBase,"asl.library",LibVersion);
}
//-------------------------------------
VOID Lib_Free()
{
	Lib_Close(&AslBase);
	Lib_Close(&IFFParseBase);
	Lib_Close(&UtilityBase);
	Lib_Close(&LocaleBase);
	Lib_Close(&KeymapBase);
	Lib_Close(&CxBase);
	Lib_Close(&WorkbenchBase);
	Lib_Close(&GadToolsBase);
	Lib_Close(&LayersBase);
	Lib_Close(&GfxBase);
	Lib_Close(&IntuitionBase);
}
//-------------------------------------


//-------------------------------------
VOID List_Init(struct tkList *List,ULONG type,void (*Func)() )
{
	NewList( (struct List *)List );
	List->lh_Type=type;
	List->lh_Numb=0;
	List->lh_Free=Func;
}
//-------------------------------------
VOID List_AddTail(struct tkList *List,struct tkNode *Node)
{
	AddTail((struct List*)List,(struct Node*)Node);
	List->lh_Numb++;
	List->Sort=FALSE;
}
//-------------------------------------
VOID List_AddSort(struct tkList *List,struct tkNode *Node,long (*Func)(const void*,const void*))
{
	struct tkNode *Node2=List->lh_Head;
	struct tkNode *node_insert=0;

	if (Func && Node2)
	{
		while(Node2->ln_Succ)
		{
			if (1==(*Func)(Node2,Node))
			{
				node_insert=Node2->ln_Pred;
				break;
			}
			(*Func)(Node2,Node);
			node_insert=Node2;
			Node2=Node2->ln_Succ;
		}
		Insert((struct List*)List,(struct Node*)Node,(struct Node*)node_insert);
	}
}
//-------------------------------------
VOID List_Remove(struct tkList *List,APTR Node)
{
	Remove(Node);
	List->lh_Numb--;
}
//-------------------------------------
VOID List_Free(struct tkList *List)
{
	struct tkNode *Node;

	while (!Empty(List))
	{
		Node=(APTR)List->lh_Head;
		if (List->lh_Free) (*List->lh_Free)(Node);
		List_Remove(List,Node);
		Memory_Free( (APTR)&Node);
	}
}
//-------------------------------------
LONG List_FindNum(struct tkList *List,APTR Ptr,UBYTE *String)
{
	struct tkNode *List1=List->lh_Head;
	register UBYTE *Str1,*Str2;
	WORD count,Num;
	BOOL Found=FALSE;

	if (Ptr)
	{
		for(Num=0 ; ((List1->ln_Succ!=0)&&(Found==FALSE)) ; Num++,List1=List1->ln_Succ )
		{
			if (Ptr==List1) Found=TRUE;
		};
	}
	else
	{
		for(Num=0 ; ((List1->ln_Succ!=0)&&(Found==FALSE)) ; Num++,List1=List1->ln_Succ )
		{
			Str1=(List1->ln_Name);
			Str2=String;
			for (	count=0;
					(*Str1!=0) && (count<31) && ((UBYTE)(*Str1&0xDF)==(UBYTE)(*Str2&0xDF));
					count++,Str1++,Str2++);
			if ( ((UBYTE)(*Str1&0xDF)>(UBYTE)(*Str2&0xDF)) || (*Str2==0)) Found=TRUE;
		};
	}
	if (!Found) Num=0;
	return(Num-1)
}
//-------------------------------------
APTR List_FindPtr(struct tkList *Liste,LONG Num,UBYTE *String)
{
	register struct tkNode *Node=Liste->lh_Head;
	register struct tkNode *NodeBack=0;
	register UBYTE Asc;

	if (!String)
	{
		for (;(Node->ln_Succ!=0)&&(Num>0);Num--,Node=Node->ln_Succ);
		NodeBack=Node;
	}
	else
	{
		if (String[0]!='?')
		{
			Asc=String[0]&0xDF;
			for(; Node->ln_Succ ; Node=Node->ln_Succ )
				if (Asc>=(Node->ln_Name[0]&0xDF) ) break;
		}

//		if (Num==FIND_NEARLY)
//		{
//				for(; Node->ln_Succ ; Node=Node->ln_Succ )
//				if (0<=stricmp(Node->ln_Name,String)) {NodeBack=Node;break;}
//		}
//		else
		{
			for(; Node->ln_Succ ; Node=Node->ln_Succ )
				if (0==stricmp(Node->ln_Name,String)) {NodeBack=Node;break;};
		}
	}
	return(NodeBack);
}
//-------------------------------------
LONG List_StrCmp(struct tkNode *Node1,struct tkNode *Node2)
{
	return(stricmp(Node1->ln_Name,Node2->ln_Name));	
}
//-------------------------------------
VOID List_QuickSort(struct tkNode **Array,register LONG Left,register LONG Right,LONG (*Func)(const void*,const void*))
{
	register LONG i=Left,j=Right;
	register struct tkNode *Swap,*Test=Array[(i+j)/2];

	do
	{
		while (-1==(*Func)(Array[i],Test)) i++;
		while ( 1==(*Func)(Array[j],Test)) j--;
		if (i<=j)
		{
			Swap=Array[i];
			Array[i]=Array[j];
			Array[j]=Swap;
			i++;j--;
		}
	} while (i <= j);

	if (Left<j)  List_QuickSort(Array,Left,j,Func);
	if (Right>i) List_QuickSort(Array,i,Right,Func);
}
//-------------------------------------
VOID List_Sort(struct tkList *List,long (*Func)(const void*,const void*))
{
	struct tkNode *Node,**Array;
	LONG Count,i;

	if (!List->Sort)
	{
		Node=List->lh_Head;
		for (Count=-1;(Node);Count++,Node=Node->ln_Succ);
	
		if (Count>1)
		{
			Array=(struct tkNode**)Memory_Alloc( (Count+2)*4 );
			for (i=0,Node=List->lh_Head;(Node->ln_Succ);Node=Node->ln_Succ)
			{
				Array[i++]=Node;
				Remove((APTR)Node);
			}
			if (!Func) Func=(APTR)List_StrCmp;

			List_QuickSort(Array,0,Count-1,Func);

			for (i=0;i<Count;i++) AddTail((APTR)List,(APTR)Array[i]);
			Memory_Free( (APTR)&Array);
		}
		List->Sort=TRUE;
	}
}
//-------------------------------------
VOID List_DoAll(struct tkList *List,long (*Func)(const void*,APTR data),APTR data)
{
	struct tkNode *Node;

	Node=List->lh_Head;
	
	if (Func)
	{
		while(Node->ln_Succ)
		{
			(*Func)(Node,data);
			Node=Node->ln_Succ;
		}
	}
}
//-------------------------------------

