/* misc.c */

#include <OSIncludes.h>
#pragma header

#include <libraries/mui.h>
#include <pragma/muimaster_lib.h>

#define CATCOMP_NUMBERS
#include "catalogs/PrefsAttack.h"
#include "PWPrefs.h"

#include <stdio.h>
#include <string.h>

static struct TagItem *tagbase;

/* IntNachricht ====================================================*/

int IntNachricht(char *body,char *auswahl)
{
	struct EasyStruct es = {sizeof(es),
		                     0,
		                     ReqTitle,
		                     body,
		                     auswahl};
	

	if (!IntuitionBase) return -1;

	return EasyRequestArgs(0,&es,0,0);
}

/* Hinweis ========================================================*/

void Hinweis(char *body)
{
	if (IntuitionBase)
	{
		IntNachricht(body,MSG(MSG_REQ_OK));
	} else {
		printf("PrefsAttack: %s",body);
	}
}

/* MyAllocVec ======================================================*/

APTR MyAllocVec(ULONG size,ULONG flags)
{
	ULONG *mem;
	
	#ifdef DebugMe
		AllocOffset++;
	#endif

	if (MyPool)
	{
		mem=AllocPooled(MyPool,size+4);
		if (mem)
		{
			*mem++=size+4;
			if (flags&MEMF_CLEAR)
			{
				memset(mem,0,size);
			}
		}
		return mem;

	} else {
		return AllocVec(size,flags);
	}
}

/* MyFreeVec ======================================================*/

void MyFreeVec(APTR mem)
{
	#ifdef DebugMe
		AllocOffset--;
	#endif


	if (MyPool)
	{
		FreePooled(MyPool,((LONG *)mem-1),((LONG *)mem)[-1]);
	} else {
		FreeVec(mem);
	}
}

/* AllocString ====================================================*/

BOOL AllocString(char* &ziel,char *name)
{
	ziel=MyAllocVec(strlen(name)+2,MEMF_ANY|MEMF_CLEAR);
	if (ziel)
	{
		strcpy(ziel,name);
		return TRUE;
	} else {
		return FALSE;
	}
}

/* AddNew_Gruppe ===================================================*/

struct Gruppe *AddNew_Gruppe(void)
{
	struct Gruppe *gr;
	
	gr=MyAllocVec(sizeof(struct Gruppe),MEMF_ANY|MEMF_CLEAR);
	
	if (!gr) return 0;
	
	NewList(&gr->gr_SeitenListe);
	AddTail(&GruppenListe,(struct Node *)gr);
	
	return gr;
}

/* AddNew_Seite ====================================================*/

struct Seite *AddNew_Seite(struct Gruppe *gruppe)
{
	struct Seite *seite;
	
	seite=MyAllocVec(sizeof(struct Seite),MEMF_ANY|MEMF_CLEAR);

	if (!seite) return 0;
	
	NewList(&seite->se_ObjektListe);
	seite->se_LabelWeight=100;
	seite->se_GadgetWeight=100;
	AddTail(&gruppe->gr_SeitenListe,(struct Node *)seite);
	return seite;
}

/* AddNew_Objekt ====================================================*/

struct Objekt *AddNew_Objekt(struct Seite *seite)
{
	struct Objekt *obj;

	obj=MyAllocVec(sizeof(struct Objekt),MEMF_ANY|MEMF_CLEAR);

	if (!obj) return 0;
	
	NewList(&obj->ob_ItemListe);
	AddTail(&seite->se_ObjektListe,(struct Node *)obj);

	return obj;
}

/* AddNew_Item ======================================================*/

struct ObjektItem *AddNew_Item(struct Objekt *objekt)
{
	struct ObjektItem *item;

	item=MyAllocVec(sizeof(struct ObjektItem),MEMF_ANY|MEMF_CLEAR);

	if (!item) return 0;
	
	AddTail(&objekt->ob_ItemListe,(struct Node *)item);

	return item;
}

/* Remove_Gruppe ====================================================*/

void Remove_Gruppe(struct Gruppe *gruppe)
{
	struct Seite *seite,*nseite;;
	
	seite=(struct Seite *)gruppe->gr_SeitenListe.lh_Head;
	
	while (seite->se_Node.ln_Succ)
	{
		nseite=(struct Seite *)seite->se_Node.ln_Succ;
		Remove_Seite(seite);
		seite=nseite
	}
	
	Remove((struct Node *)gruppe);
	if (gruppe->gr_HelpNode) MyFreeVec(gruppe->gr_HelpNode);
	if (gruppe->gr_Tabelle) MyFreeVec(gruppe->gr_Tabelle);
	if (gruppe->gr_ImageName) MyFreeVec(gruppe->gr_ImageName);

	MyFreeVec(gruppe);
}

/* Remove_Seite =====================================================*/

void Remove_Seite(struct Seite *seite)
{
	struct Objekt *obj,*nobj;
	
	obj=(struct Objekt *)seite->se_ObjektListe.lh_Head;
	
	while (obj->ob_Node.ln_Succ)
	{
		nobj=(struct Objekt *)obj->ob_Node.ln_Succ;
		Remove_Objekt(obj);
		obj=nobj;
	}
	
	Remove((struct Node *)seite);
	if (seite->se_HelpNode) MyFreeVec(seite->se_HelpNode);
	if (seite->se_Tabelle) MyFreeVec(seite->se_Tabelle);
	MyFreeVec(seite);
}

/* Remove_Objekt ====================================================*/

void Remove_Objekt(struct Objekt *obj)
{
	struct ObjektItem *item,*nitem;
	
	item=(struct ObjektItem *)obj->ob_ItemListe.lh_Head;
	
	while (item->obi_Node.ln_Succ)
	{
		nitem=(struct ObjektItem *)item->obi_Node.ln_Succ;
		Remove_Item(item);
		item=nitem;
	}
	
	Remove((struct Node *)obj);
	if (obj->ob_Name) MyFreeVec(obj->ob_Name);
	if (obj->ob_KeyWord) MyFreeVec(obj->ob_KeyWord);
	if (obj->ob_StringValue) MyFreeVec(obj->ob_StringValue);
	if (obj->ob_Tabelle) MyFreeVec(obj->ob_Tabelle);
	if (obj->ob_FrameName) MyFreeVec(obj->ob_FrameName);
	if (obj->ob_HelpText) MyFreeVec(obj->ob_HelpText);
	if (obj->ob_HelpNode) MyFreeVec(obj->ob_HelpNode);
	MyFreeVec(obj);
}

/* Remove_Item ======================================================*/

void Remove_Item(struct ObjektItem *item)
{
	if (item->obi_Name) MyFreeVec(item->obi_Name);
	if (item->obi_KeyWord) MyFreeVec(item->obi_KeyWord);
	Remove((struct Node *)item);
	MyFreeVec(item);
}

/* Remove_All =======================================================*/

void Remove_All(void)
{
	struct Gruppe *gruppe,*ngruppe;
	
	gruppe=(struct Gruppe *)GruppenListe.lh_Head;
	
	while (gruppe->gr_Node.ln_Succ)
	{
		ngruppe=(struct Gruppe *)gruppe->gr_Node.ln_Succ;
		Remove_Gruppe(gruppe);
		gruppe=ngruppe;
	}
}

/* SetName_Gruppe ===================================================*/

void SetName_Gruppe(struct Gruppe *gruppe,char *name)
{
	strncpy(gruppe->gr_Name,name,30);
}

/* SetHelpNode_Gruppe ====================================================*/

BOOL SetHelpNode_Gruppe(struct Gruppe *gruppe,char *name)
{
	return AllocString(gruppe->gr_HelpNode,name);
}

/* SetImageName_Gruppe ====================================================*/

BOOL SetImageName_Gruppe(struct Gruppe *gruppe,char *name)
{
	return AllocString(gruppe->gr_ImageName,name);
}

/* SetName_Seite ====================================================*/

void SetName_Seite(struct Seite *seite,char *name)
{
	strncpy(seite->se_Name,name,30);
}

/* SetHelpNode_Seite ====================================================*/

BOOL SetHelpNode_Seite(struct Seite *seite,char *name)
{
	return AllocString(seite->se_HelpNode,name);
}

/* SetName_Objekt ===================================================*/

BOOL SetName_Objekt(struct Objekt *obj,char *name)
{
	return AllocString(obj->ob_Name,name);
}

/* SetFrameName_Objekt ===================================================*/

BOOL SetFrameName_Objekt(struct Objekt *obj,char *name)
{
	return AllocString(obj->ob_FrameName,name);
}

/* SetHelp_Objekt ===================================================*/

BOOL SetHelp_Objekt(struct Objekt *obj,char *name)
{
	char *fp;
	
	while ((fp=strstr(name,"\\n")))
	{
		*fp++ = 10;

		memmove(fp,fp+1,strlen(fp+1))
	}

	return AllocString(obj->ob_HelpText,name);
}

/* SetHelpNode_Objekt ===================================================*/

BOOL SetHelpNode_Objekt(struct Objekt *obj,char *name)
{
	return AllocString(obj->ob_HelpNode,name);
}

/* SetKeyWord_Objekt ================================================*/

BOOL SetKeyWord_Objekt(struct Objekt *obj,char *name)
{
	return AllocString(obj->ob_KeyWord,name);
}

/* SetStringValue_Objekt ============================================*/

BOOL SetStringValue_Objekt(struct Objekt *obj,char *name,WORD size)
{
	if (size)
	{
		obj->ob_StringValue=MyAllocVec(size+2,MEMF_ANY|MEMF_CLEAR);
	}

	if (!obj->ob_StringValue) return FALSE;
	
	if (name)
	{
		strcpy(obj->ob_StringValue,name);
	}
	return TRUE;
}

/* SetName_Item =====================================================*/

BOOL SetName_Item(struct ObjektItem *item,char *name)
{
	return AllocString(item->obi_Name,name);
}

/* SetKeyWord_Item =====================================================*/

BOOL SetKeyWord_Item(struct ObjektItem *item,char *name)
{
	return AllocString(item->obi_KeyWord,name);
}

/* ResetObjekte =====================================================*/

void ResetObjekte(void)
{
	struct Gruppe *gr;
	struct Seite *se;
	struct Objekt *obj;

	gr=(struct Gruppe *)GruppenListe.lh_Head;
	
	while (gr->gr_Node.ln_Succ)
	{
		se=(struct Seite *)gr->gr_SeitenListe.lh_Head;
		while (se->se_Node.ln_Succ)
		{
			obj=(struct Objekt *)se->se_ObjektListe.lh_Head;
			while (obj->ob_Node.ln_Succ)
			{
				switch (obj->ob_Typ)
				{
					case OBJ_BOOL:
						set(obj->ob_MUIGetObject,MUIA_Selected,obj->ob_LongValue);
						break;
						
					case OBJ_INTEGER:
						sprintf(s,"%ld",obj->ob_LongValue);
						set(obj->ob_MUIGetObject,MUIA_String_Contents,s);
						break;

					case OBJ_SLIDER:
						set(obj->ob_MUIGetObject,MUIA_Slider_Level,obj->ob_LongValue);
						break;
						
					case OBJ_STRING:
					case OBJ_FILE:
					case OBJ_FONT:
						set(obj->ob_MUIGetObject,MUIA_String_Contents,obj->ob_StringValue);
						break;
						
					case OBJ_CYCLE:
						set(obj->ob_MUIGetObject,MUIA_Cycle_Active,obj->ob_LongValue);
						break;	
					
					case OBJ_LISTVIEW:
						DoMethod(obj->ob_MUIGetObject,MUIM_List_Clear);
						break;

				}
				obj=(struct Objekt *)obj->ob_Node.ln_Succ;
			}
			se=(struct Seite *)se->se_Node.ln_Succ;
		}
		gr=(struct Gruppe *)gr->gr_Node.ln_Succ;
	}
}
	
/* FindKeyWord ========================================================*/

struct Objekt *FindKeyWord(char *kw)
{
	struct Gruppe *gr;
	struct Seite *se;
	struct Objekt *obj;
	
	gr=(struct Gruppe *)GruppenListe.lh_Head;
	
	if (kw)
	{
		while (gr->gr_Node.ln_Succ)
		{
			se=(struct Seite *)gr->gr_SeitenListe.lh_Head;
			while (se->se_Node.ln_Succ)
			{
				obj=(struct Objekt *)se->se_ObjektListe.lh_Head;
				while (obj->ob_Node.ln_Succ)
				{
					if (obj->ob_KeyWord)
					{
						if (stricmp(obj->ob_KeyWord,kw)==0) return obj;
					}
					obj=(struct Objekt *)obj->ob_Node.ln_Succ;
				}
				se=(struct Seite *)se->se_Node.ln_Succ;
			}
			gr=(struct Gruppe *)gr->gr_Node.ln_Succ;
		}
	}
	return 0;
}

/* FindItem ===========================================================*/

struct ObjektItem *FindItem(struct Objekt *o, char *ikw,WORD *inr)
{
	struct ObjektItem *it;
	WORD nr;
	
	it=(struct ObjektItem *)o->ob_ItemListe.lh_Head;
	nr=0;
	while (it->obi_Node.ln_Succ)
	{
		if (stricmp(it->obi_KeyWord,ikw)==0)
		{
			if (inr) *inr=nr;
			return it;
		}
		nr++;
		it=(struct ObjektItem *)it->obi_Node.ln_Succ;
	}
	
	if (inr) *inr=-1;
	return 0;
}

void InitTag(struct TagItem *t)
{
	tagbase=t;
}

void AddTag(Tag tag,ULONG data)
{
	tagbase->ti_Tag=tag;
	tagbase->ti_Data=data;
	tagbase++;
}

void TagDone(void)
{
	tagbase->ti_Tag=TAG_DONE;
}

void BreakString(STRPTR s)
{
	STRPTR sp;
	STRPTR lastspace=0;
	WORD spos=0;
	
	if (strstr(s,"Hotkey, um alle Icons im aktuellen"))
	{
		spos=0;
	}
	sp=s;
	while (*sp)
	{
		if (*sp == ' ')
		{
			if (spos>=BubbleBreak)
			{
				if (spos==BubbleBreak)
				{
					*sp='\n';
					lastspace=0;
					spos=-1;
				} else {
					if (lastspace)
					{
						*lastspace='\n';
						spos=(ULONG)sp-(ULONG)lastspace;
					}
				}
			}
			lastspace=sp;
		}
		spos++;
		sp++;
	}
}

UBYTE *FindChunk(ULONG chunk,UBYTE *mem, ULONG memlen)
{
	memlen-=4;
	while (memlen>=0)
	{
		if (*(ULONG *)mem==chunk) return mem+8;
		mem+=2;
		memlen-=2;
	}
	return 0;
}

