/*
	HereTic INFO.c processor, 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.

	PRINT.C - Print routines.
*/

#include "../common/print.h"
#include "../common/things.h"
#include "../common/maps.h"
#include "../common/stub.h"


/*
	the global variables
*/
extern sfxinfo_t S_sfx[];
extern int GetWeaponAmmo[];
extern int WeaponAmmoUsePL1[];
extern int WeaponAmmoUsePL2[];

/*
	the local function prototypes
*/
void PrintSound(char *, int);
void PrintWpnAmmo( weapontype_t);
void PrintShotsPM( mobjinfo_t *, Bool);
void PrintWpnShotsPM( weapontype_t, Bool);
void PrintWpnSprites( weapontype_t);


/*
	the weapon print data function
*/
void PrintWeapon()
{
	if (Weap < 0 || Weap >= NUMWEAPONS)
		ProgError( "no such Weapon %d", Weap);

	if (XWik)
	{
		tpldata = TMPL_add_var( tpldata, "NAME", Wpn2Str( Weap), NULL);
		memset(fieldlist, 0, LISTSIZE);
		memset(field2list, 0, LISTSIZE);
	}
	else
	{
		printf( "\n");
		printf( "Weapon\t\t%s\n", Wpn2Str( Weap));
	}
	PrintWpnAmmo( Weap);
	PrintWpnShotsPM( Weap, FALSE);
	PrintWpnShotsPM( Weap, TRUE);
	if (!XWik)
		printf( "\n");
	PrintWpnSprites( Weap);

	if (XWik)
	{
		tpldata = TMPL_add_var( tpldata, "STATELIST", fieldlist, NULL);
		if (weaponthing[Weap] != -1)
		{
			Thng = weaponthing[Weap];
			PrintData();
		}
	}
	else
		PrintSpawns();
}

/*
	the main print data function
*/
void PrintData()
{
	mobjinfo_t *MOBJ;

	if (Enum != NULL)
		Objt = Enum2Obj( Enum);
	else if (Thng != -1)
		Objt = Thg2Obj( Thng);
	else
		if (Objt < 0 || Objt >= NUMMOBJTYPES)
			ProgError( "no such Object %d", Objt);

	MOBJ = &mobjinfo[Objt];
	PrintTypeHealth( MOBJ);

	if (MOBJ->flags & MF_SPECIAL) // pick-up item
	{
		PrintShotsPM( MOBJ, FALSE);
		PrintShotsPM( MOBJ, TRUE);
	}
	else
		PrintSpeed( MOBJ);

	PrintDimsTimesFlags( MOBJ);
	if (XWik)
	{
		tmpl_add_int( tpldata, "FLAGSHEX2", "%08X", MOBJ->flags2);
		tmpl_add_int( tpldata, "FLAGSDEC2", "%d", MOBJ->flags2);
	}
	else
		printf( "Flags2\t\t%08x  %d\n", MOBJ->flags2, MOBJ->flags2);
	PrintFlags2( MOBJ->flags2);

	TallyFrames( MOBJ->spawnstate, FALSE);
	TallyFrames( MOBJ->seestate, FALSE);
	TallyFrames( MOBJ->painstate, FALSE);
	TallyFrames( MOBJ->meleestate, FALSE);
	TallyFrames( MOBJ->missilestate, FALSE);
	TallyFrames( MOBJ->crashstate, FALSE);
	TallyFrames( MOBJ->deathstate, FALSE);
	TallyFrames( MOBJ->xdeathstate, FALSE);

	if (XWik)
	{
		memset(fieldlist, 0, LISTSIZE);
		memset(field2list, 0, LISTSIZE);
	}
	else
		printf( "\n");
	if (MOBJ->flags & MF_SPECIAL) // pick-up item
	{
		PrintItemSprites( MOBJ);
	}
	else
	{
		if ((MOBJ->doomednum != -1 && LookupThingClass( MOBJ->doomednum) == ThClassMnst) ||
		    Objt == MT_SORCERER2 || Objt == MT_CHICKEN ||
		    Objt == MT_CHICPLAYER || Objt == MT_PLAYER)
			PrintMonsterSprites( MOBJ);
		else
		{
			PrintSprite( MOBJ->spawnstate, ST_NONE, FALSE);
			if (XWik)
			{
				tpldata = TMPL_add_var( tpldata, "SPRITE", fieldlist, NULL);
				tpldata = TMPL_add_var( tpldata, "FRAMES", field2list, NULL);
				memset(fieldlist, 0, LISTSIZE);
				memset(field2list, 0, LISTSIZE);
			}
			PrintSprite( MOBJ->deathstate, ST_NONE, FALSE);
			if (XWik)
			{
				tpldata = TMPL_add_var( tpldata, "SPRITE2", fieldlist, NULL);
				tpldata = TMPL_add_var( tpldata, "FRAMES2", field2list, NULL);
			}
		}

		PrintSound( "Alert",  MOBJ->seesound);
		PrintSound( "Active", MOBJ->activesound);
		PrintSound( "Attack", MOBJ->attacksound);
		PrintSound( "Pain",   MOBJ->painsound);
		PrintSound( "Death",  MOBJ->deathsound);
	}
	PrintSpawns();
}


void PrintSound(char *type, int sound)
{
	char name[12], type2[8];

	// cannot run strupr on static param
	strcpy( type2, type);
	strupr( type2);
	if (!XWik)
		printf( "%s sound\t", type);
	if (sound != 0)
	{
		if (S_sfx[sound].link != NULL)
			strcpy( name, S_sfx[sound].link->name);
		else
			strcpy( name, S_sfx[sound].name);
		strupr( name);
		if (XWik)
			tpldata = TMPL_add_var( tpldata, type2, name, NULL);
		else
			printf( "%s\n", name);
	}
	else
	{
		if (XWik)
			tpldata = TMPL_add_var( tpldata, type2, "-", NULL);
		else
			printf( "-\n");
	}
}

void PrintWpnAmmo( weapontype_t weapon)
{
	int ammo;

	ammo = GetWeaponAmmo[weapon];
	if (XWik)
	{
		tmpl_add_int( tpldata, "INCAMMO", "%d", ammo);
		tmpl_add_int( tpldata, "INCAMM2", "%d", (int)(ammo * 1.5));
	}
	else
		printf("Incl ammo\t%d (%d on [[Skill level|skills]] 1 & 5)\n", ammo, (int)(ammo * 1.5));

	ammo = maxammo[wpnlev1info[weapon].ammo];
	if (XWik)
	{
		tmpl_add_int( tpldata, "MAXAMMO", "%d", ammo);
		tmpl_add_int( tpldata, "BPKAMMO", "%d", ammo * 2);
		tpldata = TMPL_add_var( tpldata, "BACKPACK", "Bag of Holding", NULL);
	}
	else
		printf("Max ammo\t%d (%d with [[bag of holding]])\n", ammo, ammo * 2);

	if (XWik)
	{
		tmpl_add_int( tpldata, "AMMOUSE1", "%d", WeaponAmmoUsePL1[weapon]);
		tmpl_add_int( tpldata, "AMMOUSE2", "%d", WeaponAmmoUsePL2[weapon]);
	}
	else
	{
		printf("Ammo use\t%d \n", WeaponAmmoUsePL1[weapon]);
		printf("Ammo use (p)\t%d \n", WeaponAmmoUsePL2[weapon]);
	}
}


void PrintShotsPM( mobjinfo_t *MOBJ, Bool powered)
{
	int weapon;

	switch (states[MOBJ->spawnstate].sprite)
	{
		case SPR_WGNT: weapon = wp_gauntlets; break;
		case SPR_WBOW: weapon = wp_crossbow; break;
		case SPR_WBLS: weapon = wp_blaster; break;
		case SPR_WSKL: weapon = wp_skullrod; break;
		case SPR_WPHX: weapon = wp_phoenixrod; break;
		case SPR_WMCE: weapon = wp_mace; break;
		default: return;
	}
	PrintWpnShotsPM( weapon, powered);
}

void PrintWpnShotsPM( weapontype_t weapon, Bool powered)
{
	int percycle = 0, tics = 0;
	statenum_t state, st;

	state = st = (powered ? wpnlev2info[weapon].holdatkstate
	                      : wpnlev1info[weapon].holdatkstate);
	if (state != S_NULL)
		for (;;)
		{
			if (states[st].action)
				states[st].action(NULL);
			else
				funcname[0] = '\0';
			if (strncmp( funcname, "A_Fire", strlen("A_Fire")) == 0 ||
			    strncmp( funcname, "A_StaffAttack", strlen("A_StaffAttack")) == 0 ||
			    strncmp( funcname, "A_BeakAttack", strlen("A_BeakAttack")) == 0 ||
			    strcmp( funcname, "A_GauntletAttack") == 0)
				percycle++;
			else if (strcmp( funcname, "A_ReFire") == 0 ||
			         strcmp( funcname, "A_BeakReady") == 0)
				break;
			tics += states[st].tics;
			st = states[st].nextstate;
			if (tics > 100)
				ProgError( "unable to count tics for holdatkstate %d", state);
		}

	if (tics != 0)
		if (XWik)
			tmpl_add_float( tpldata, (powered ? "SHOTMIN2" : "SHOTMIN"), "%.1f",
			                (float)percycle * (TICRATE * 60) / tics);
		else
			printf( "Shots / min%s\t%.1f\n", (powered ? " (p)" : ""),
			        (float)percycle * (TICRATE * 60) / tics);
}

int FrameTics( statenum_t state)
{
	if (states[state].action)
	{
		states[state].action(NULL);
		if (strcmp( funcname, "A_Chase") == 0 ||
		    strcmp( funcname, "A_ChicChase") == 0 ||  // Chicken
		    strcmp( funcname, "A_Sor1Chase") == 0)    // D'Sparil
			return states[state].tics;
	}

	return -1;
}


void PrintItemSprites( mobjinfo_t *MOBJ)
{
	int weapon;

	switch (states[MOBJ->spawnstate].sprite)
	{
		case SPR_WGNT: weapon = wp_gauntlets; break;
		case SPR_WBOW: weapon = wp_crossbow; break;
		case SPR_WBLS: weapon = wp_blaster; break;
		case SPR_WSKL: weapon = wp_skullrod; break;
		case SPR_WPHX: weapon = wp_phoenixrod; break;
		case SPR_WMCE: weapon = wp_mace; break;
		default:
			PrintSprite( MOBJ->spawnstate, ST_NONE, FALSE);
			tpldata = TMPL_add_var( tpldata, "SPRITE", fieldlist, NULL);
			tpldata = TMPL_add_var( tpldata, "FRAMES", field2list, NULL);
			return;
	}
	PrintSprite( MOBJ->spawnstate, ST_PICKUP, FALSE);
	PrintWpnSprites( weapon);

	tpldata = TMPL_add_var( tpldata, "STATELIST", fieldlist, NULL);
}

void PrintWpnSprites( weapontype_t weapon)
{
	PrintSprite( wpnlev1info[weapon].readystate, ST_WIELD, FALSE);
	PrintSprite( wpnlev1info[weapon].atkstate, ST_FIRE, TRUE);
	PrintSprite( wpnlev1info[weapon].holdatkstate, ST_REFIRE, FALSE);
	PrintSprite( wpnlev2info[weapon].readystate, ST_WIELD_P, FALSE);
	PrintSprite( wpnlev2info[weapon].atkstate, ST_FIRE_P, TRUE);
	PrintSprite( wpnlev2info[weapon].holdatkstate, ST_REFIRE_P, FALSE);
}

void PrintMonsterSprites( mobjinfo_t *MOBJ)
{
	memset(fieldlist, 0, LISTSIZE);
	PrintSprite( MOBJ->spawnstate, ST_NONE, FALSE);
	tpldata = TMPL_add_var( tpldata, "SPRITE", fieldlist, NULL);

	memset(fieldlist, 0, LISTSIZE);
	PrintSprite( MOBJ->spawnstate, ST_SPAWN, FALSE);
	PrintSprite( MOBJ->seestate, ST_SEE, FALSE);
	PrintSprite( MOBJ->meleestate, ST_MELEE, FALSE);
	PrintSprite( MOBJ->missilestate, ST_MISSL, FALSE);
	PrintSprite( MOBJ->painstate, ST_PAIN, FALSE);
	PrintSprite( MOBJ->deathstate, ST_DEATH, FALSE);
	PrintSprite( MOBJ->crashstate, ST_CRASH, FALSE);
	PrintSprite( MOBJ->xdeathstate, ST_XDEATH, FALSE);
	tpldata = TMPL_add_var( tpldata, "STATELIST", fieldlist, NULL);
}

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