/*
	DooM/HereTic/HeXen/StriFe INFO.c processors, by Frans P. de Vries.

Derived from:

	DooM MaP StaTistics, by Frans P. de Vries.

	You are allowed to use any parts of this code in another program, as
	long as you give credits to the authors in the documentation and in
	the program itself.  Read the file README for more information.

	This program comes with absolutely no warranty.

	THINGS.C - Common thing routines.
*/

#define _GNU_SOURCE
#include <stdio.h>
#include "things.h"


/*
	the global variables
*/
UBCINT NumThClasses = 0;
ThClass **ThClasses = NULL;

UBCINT NumThItems = 0;
ThItem  **ThItems = NULL;

/*
	the local function prototypes
*/
void DumpThings( void);


/*
	forget the things data
*/
void ForgetThings( void)
{
	int n;

	for (n = 0; n < NumThClasses; n++)
		if (ThClasses[n] != NULL)
		{
			FreeMemory( ThClasses[n]->wikiname);
			if (ThClasses[n]->wikilink != NULL)
				FreeMemory( ThClasses[n]->wikilink);
			FreeMemory( ThClasses[n]->wikistr);
			FreeMemory( ThClasses[n]);
		}

	FreeMemory( ThClasses);
	ThClasses = NULL;
	NumThClasses = 0;

	for (n = 0; n < NumThItems; n++)
		if (ThItems[n] != NULL)
		{
			FreeMemory( ThItems[n]->wikiname);
			if (ThItems[n]->wikilink != NULL)
				FreeMemory( ThItems[n]->wikilink);
			FreeMemory( ThItems[n]->wikistr);
			FreeMemory( ThItems[n]);
		}

	FreeMemory( ThItems);
	ThItems = NULL;
	NumThItems = 0;
}

/*
	dump the things data for the given mode
*/
void DumpThings( void)
{
	int c, i;

	for (c = 0; c < NumThClasses; c++)
	{
		printf( "%3d:         %28s %-58.58s\n", ThClasses[c]->class,
		        ThClasses[c]->wikiname, ThClasses[c]->wikistr);
		for (i = 0; i < NumThItems; i++)
			if (ThClasses[c]->class == ThItems[i]->class)
				printf( "%3d: %d %5d %28s %-66.66s\n", i,
				        ThItems[i]->class, ThItems[i]->type, ThItems[i]->wikiname, ThItems[i]->wikistr);
	}
	printf( "\n");
}


/*
	create a thing class and append it to classes array
*/
void AppendClass( UBCINT class, char *wikiname, char *wikilink, char *wikistr)
{
	ThClass *tptr;
	int ret;

	/* initialize class */
	tptr = (ThClass *) GetMemory( sizeof(ThClass));
	tptr->class = class;
	tptr->wikiname = strdup( wikiname);
	if (wikilink != NULL)
	{
		tptr->wikilink = strdup( wikilink);
		/* special handling of class headers with multiple links */
		if (wikistr != NULL)
			tptr->wikistr = strdup( wikistr);
		else
		{
			ret = asprintf( &tptr->wikistr, "[[%s|%s]]", wikilink, wikiname);
			if (ret == -1)
				ProgError( "unable to concatenate class wiki string");
		}
	}
	else /* don't link */
	{
		tptr->wikilink = NULL;
		tptr->wikistr = strdup( wikiname);
	}

	/* append class to global array */
	ThClasses = (ThClass **) ResizeMemory( ThClasses, (NumThClasses+1) * sizeof(tptr));
	ThClasses[NumThClasses++] = tptr;
}

/*
	create a thing item and append it to items array
	wikilink: if non-empty string, use as link in [[link|name]]
	          if empty string, use wikiname as link in [[name]]
	          if NULL, don't link wikiname
*/
void AppendItem( UBCINT class, UBCINT type, char *wikiname, char *wikilink)
{
	ThItem *tptr;
	int ret = 0;

	/* initialize item */
	tptr = (ThItem *) GetMemory( sizeof(ThItem));
	tptr->class = class;
	tptr->type = type;

	/* compile wiki string */
	tptr->wikiname = strdup( wikiname);
	if (wikilink != NULL)
	{
		tptr->wikilink = strdup( wikilink);
		if (strcmp( wikilink, "") != 0) /* use alternate link */
			ret = asprintf( &tptr->wikistr, "[[%s|%s]]", wikilink, wikiname);
		else /* use name as link */
			ret = asprintf( &tptr->wikistr, "[[%s]]", wikiname);
	}
	else /* don't link */
	{
		tptr->wikilink = NULL;
		tptr->wikistr = strdup( wikiname);
	}
	if (ret == -1)
		ProgError( "unable to concatenate item wiki string");

	/* append item to global array */
	ThItems = (ThItem **) ResizeMemory( ThItems, (NumThItems+1) * sizeof(tptr));
	ThItems[NumThItems++] = tptr;
}


/*
	look up name of class
*/
char *LookupClassName( int class)
{
	int i;

	for (i = 0; i < NumThClasses; i++)
		if (class == ThClasses[i]->class)
			return ThClasses[i]->wikiname;

	return "";
}

/*
	look up class of thing type
*/
int LookupThingClass( int type)
{
	int i;

	for (i = 0; i < NumThItems; i++)
		if (type == ThItems[i]->type)
			return ThItems[i]->class;

	if (type != -1)
		printf("\tNo item found for type: %d\n", type);
	return -1;
}

/*
	look up (wikified) name of thing type
*/
char *LookupThing( int type, Bool wiki)
{
	int i;

	for (i = 0; i < NumThItems; i++)
		if (type == ThItems[i]->type)
			return (wiki ? ThItems[i]->wikistr : ThItems[i]->wikiname);

	if (type != -1)
		printf("\tNo item found for type: %d\n", type);
	return "";
}

/* vim:set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */
