/*********************************************************************************************/
/*                                                                                           */
/* Display Meters															   */
/*                                                                                           */
/*********************************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION
#include <sys\types.h>
#include <stdio.h>
#include "../spec_psx/typedefs.h"
#include "../spec_psx/gen_draw.h"
#include "../spec_psx/specific.h"
#else
#include "../specific/stypes.h"
#endif

#include "objects.h"
#include "lara.h"
#include "laraanim.h"
#include "savegame.h"
#include "title.h"
#include "text.h"
#include "health.h"

#define MAX_TIME_ALLOWED	((59*60*30)+(59*30)+27)
extern int assault_penalties, assault_penalty_display_timer;
extern int assault_target_penalties;
extern int QuadbikeLapTime, QuadbikeLapTimeDisplayTimer;

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define NUM_PU	1

/*---------------------------------------------------------------------------
 *	Type Definitions
\*--------------------------------------------------------------------------*/

typedef struct {
	sint16	duration;
	sint16	sprnum;
} DISPLAYPU;

/*---------------------------------------------------------------------------
 *	Externals
\*--------------------------------------------------------------------------*/

extern uint16 DashTimer;
extern sint16 ExposureMeter;

/*---------------------------------------------------------------------------
 *	Globals
\*--------------------------------------------------------------------------*/

char PoisonFlag;
int overlay_flag=1;
TEXTSTRING *ammotext = NULL;

long	qbx;

/*---------------------------------------------------------------------------
 *	Locals
\*--------------------------------------------------------------------------*/

#ifdef PC_VERSION
static DISPLAYPU pickups[NUM_PU];
#endif

static TEXTSTRING* LpModeTS=0;
static int LnModeTSLife=0;

/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

int FlashIt(void)
{
	static	int		flash_state=0;
	static	int		flash_count=0;

	if (flash_count)
		flash_count--;
	else
	{
		flash_state ^= 1;
		flash_count = 5;
	}
	return(flash_state);
}

void DrawAssaultTimer(void)
{
	int x, timer, hund, ttimer;
	char txt[8], *c;

	if (CurrentLevel != LV_GYM || !assault_timer_display || QuadbikeLapTimeDisplayTimer)
		return;

	if (savegame.timer > MAX_TIME_ALLOWED)
		savegame.timer = MAX_TIME_ALLOWED;	// Set to 59 minutes max.

	ttimer = savegame.timer;

	if (ttimer < 2)
		ttimer = 0;

	timer = ttimer / 30;
	hund = (((ttimer%30)*334)/100);
	sprintf(txt, "%d:%02d.%02d", timer/60, timer%60, hund);

	x = (phd_winxmax>>1) - 20*5/2;
	for (c = txt; *c; c++)
	{
		if (*c == ':')
		{
			x -= 6;
			S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 10), 2, 0);
			x += 14;
		}
		else if (*c == '.')
		{
			x -= 6;
			S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 11), 2, 0);
			x += 14;
		}
		else
		{
			S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + (*c-'0')), 2, 0);
			x += 20;
		}
	}
}

void DrawAssaultPenalties(long type)	// type 0 = assault course, 1 = targets missed.
{
	int x, timer, y;
	char txt[10], *c;

	if (CurrentLevel != LV_GYM || !assault_penalty_display_timer || !assault_timer_display)
		return;

	if (type == 0)	// Assault course run penalties ?
	{
		if (assault_penalties == 0)
			return;
		if (assault_penalties > MAX_TIME_ALLOWED)
			assault_penalties = MAX_TIME_ALLOWED;	// Set to 59 minutes max.
		y = 36;
		timer = assault_penalties / 30;
		sprintf(txt, "%d:%02d s", timer/60, timer%60);
		x = (phd_winxmax>>1) - (70*5/2);
	}
	else			// Missed targets penalties.
	{
		if (assault_target_penalties == 0)
			return;
		if (assault_target_penalties > MAX_TIME_ALLOWED)
			assault_target_penalties = MAX_TIME_ALLOWED;	// Set to 59 minutes max.
		y = (assault_penalties == 0) ? 36 : 64;
		timer = assault_target_penalties / 30;
		sprintf(txt, "T %d:%02d s", timer/60, timer%60);
		x = (phd_winxmax>>1) - (70*5/2) - 18;
	}

	for (c = txt; *c; c++)
	{
		if (*c == ' ')
			x += 8;
		else if (*c == 'T')	// Target sprite?
		{
			x -= 6;
			S_DrawScreenSprite2d(x,y+1,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 12), 0, 0);
			x += 16;
		}
		else if (*c == 's')
		{
			x -= 6;
			S_DrawScreenSprite2d(x-4,y,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 13), 9, 0);
			x += 14;
		}
		else if (*c == ':')
		{
			x -= 6;
			S_DrawScreenSprite2d(x,y,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 10), 9, 0);
			x += 14;
		}
		else if (*c == '.')
		{
			x -= 6;
			S_DrawScreenSprite2d(x,y,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 11), 9, 0);
			x += 14;
		}
		else
		{
			S_DrawScreenSprite2d(x,y,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + (*c-'0')), 9, 0);
			x += 20;
		}
	}
}

void DrawQuadbikeLapTime(void)
{
	int x, timer, hund,lp, col;
	char txt[8], *c;

	if (CurrentLevel != LV_GYM || !QuadbikeLapTimeDisplayTimer)
		return;

	for (lp=0;lp<2;lp++)
	{
		if (lp==0)
		{
			timer = QuadbikeLapTime / 30;
			hund = ((QuadbikeLapTime%30)*334)/100;
			x = (phd_winxmax>>1) - 20*5/2;
			col = 9;
		}
		else
		{
			timer = savegame.best_quadbike_times[0]/30;
			hund = ((savegame.best_quadbike_times[0]%30)*334)/100;
			x = (phd_winxmax>>1) + 40*5/2;
			col = 10;
		}

		sprintf(txt, "%d:%02d.%02d", timer/60, timer%60, (int)(hund));
		for (c = txt; *c; c++)
		{
			if (*c == ':')
			{
				x -= 6;
				S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 10), col, 0);
				x += 14;
			}
			else if (*c == '.')
			{
				x -= 6;
				S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + 11), col, 0);
				x += 14;
			}
			else
			{
				S_DrawScreenSprite2d(x,36,0, 0x10000, 0x10000, (sint16)(objects[ASSAULT_NUMBERS].mesh_index + (*c-'0')), col, 0);
				x += 20;
			}
		}
	}
}

/******************************************************************************
 *				Draw All Required Game Information
 *****************************************************************************/
void	DrawGameInfo(int timed)
{
	int	flash_state;

	DrawAmmoInfo();
	DrawModeInfo();

	if ( overlay_flag>0 )
	{
		flash_state = FlashIt();
		DrawAssaultTimer();
		DrawAssaultPenalties(0);
		DrawAssaultPenalties(1);
		DrawQuadbikeLapTime();
		DrawHealthBar(flash_state);
		DrawAirBar(flash_state);
#ifdef PC_VERSION
		DrawPickups(timed);
#endif

	/* -------- draw dash power-up/timer bar */

		if (DashTimer < LARA_DASH_TIME)
			S_DrawDashBar((DashTimer*100)/LARA_DASH_TIME);

	/* -------- draw exposure bar */

//		ExposureMeter = LARA_EXPOSURE_TIME;	//## GIBBBBBBBYYYY
		if (ExposureMeter < LARA_EXPOSURE_TIME)
		{
			if (ExposureMeter < 0)
				S_DrawColdBar(0);
			else
			{
				if (!((ExposureMeter < (LARA_EXPOSURE_TIME >> 2) && (flash_state))))
					S_DrawColdBar((ExposureMeter*100)/LARA_EXPOSURE_TIME);
			}
		}
	}
	T_DrawText();
}

/******************************************************************************
 *			Draw Laras Health Bar on Screen
 *****************************************************************************/
void	DrawHealthBar( int flash_state)
{
	int				hitpoints;
	static	int		old_hitpoints=0;

#ifdef INVINCABLE_LARA
	lara_item->hit_points = LARA_HITPOINTS;
#endif

	hitpoints = (int)lara_item->hit_points;				// Get HitPoints 0-100

	if ( hitpoints<0 )
		hitpoints=0;
	else if ( hitpoints>LARA_HITPOINTS )
		hitpoints=LARA_HITPOINTS;

	if ( old_hitpoints!=hitpoints )
	{
		old_hitpoints = hitpoints;
		health_bar_timer = 40;
	}
	if ( health_bar_timer<0 )
		health_bar_timer = 0;
	if ( hitpoints<=LARA_HITPOINTS>>2 )
	{
		if (flash_state)
			S_DrawHealthBar( hitpoints/10 );
		else
			S_DrawHealthBar( 0 );
	}
	else if ((health_bar_timer > 0)
		||  (hitpoints <= 0)
		||  (lara.gun_status == LG_READY)
		||  (lara.poisoned))
			S_DrawHealthBar(hitpoints/10);

	if (PoisonFlag)
		PoisonFlag--;
}

/*****************************************************************************
 *			Draw Air Bar on Screen when Underwater..
 ****************************************************************************/
void	DrawAirBar( int flash_state )
{
	int		air;


	if ((lara.skidoo == NO_ITEM)
	||  (items[lara.skidoo].object_number != UPV))
	{
		if ((lara.water_status != LARA_UNDERWATER)
		&&  (lara.water_status != LARA_SURFACE)
		&& (!((room[lara_item->room_number].flags & SWAMP)
		&&  (lara.water_surface_dist < -775))))
			return;
	}

//	lara.air=LARA_AIR;	//## GIBBBBYYYYY

	air = (int)lara.air;
	if ( air<0 )
		air=0;
	else if ( air>LARA_AIR )
		air=LARA_AIR;
	if (air<=LARA_AIR>>2)
	{
		if (flash_state)
			S_DrawAirBar( (air*100)/LARA_AIR );
		else
			S_DrawAirBar( 0 );
	}
	else
		S_DrawAirBar( (air*100)/LARA_AIR );
}

/******************************************************************************
 *					Draw Ammo information
 *****************************************************************************/

void MakeAmmoString(char *string)
{
	/* Convert string into ASCII codes */
	char *c;

	for (c=string; *c!=0; c++)
	{
		if (*c == 32)
			continue;
		else if (*c - 'A' >= 0)
			*c += 12-'A';
		else
			*c += 1-'0';
	}
}

void RemoveAmmoText()
{
	if (ammotext)
	{
		T_RemovePrint(ammotext);
		ammotext = NULL;
	}
}

void DrawAmmoInfo( void )
{
	char ammostring[80];

	ammostring[0]=0;

	if (items[lara.skidoo].object_number == UPV)
	{
		wsprintf(ammostring, "%5d", lara.harpoon.ammo);
	}
	else
	{
		if ((lara.gun_status != LG_READY)
		||  (overlay_flag <= 0)
		||  (savegame.bonus_flag))
		{
			RemoveAmmoText();
			return;
		}


		switch (lara.gun_type)
		{
			case LG_PISTOLS:
				return;
				break;

			case LG_MAGNUMS:
				wsprintf(ammostring, "%5d", lara.magnums.ammo);
				break;

			case LG_UZIS:
				wsprintf(ammostring, "%5d", lara.uzis.ammo);
			break;

			case LG_SHOTGUN:
				wsprintf(ammostring, "%5d", lara.shotgun.ammo/SHOTGUN_AMMO_CLIP);
			break;

			case LG_HARPOON:
				wsprintf(ammostring, "%5d", lara.harpoon.ammo);
				break;

			case LG_M16:
				wsprintf(ammostring, "%5d", lara.m16.ammo);
				break;

			case LG_ROCKET:
				wsprintf(ammostring, "%5d", lara.rocket.ammo);
				break;

			case LG_GRENADE:
				wsprintf(ammostring, "%5d", lara.grenade.ammo);
				break;

			case LG_FLARE:
			default:
				return;
			break;
		}
	}

	RemoveAmmoText();
//	if ( ammotext )
//		T_ChangeText( ammotext, ammostring );
//	else
#ifdef PC_VERSION
	{
		ammotext = T_Print(-10,35,0, ammostring );
		T_RightAlign(ammotext, 1);
	}
#else
	{
		ammotext = T_Print(-24, 220, 3, ammostring );
		T_RightAlign(ammotext, 1);
	}
#endif
}


/******************************************************************************
 *				Kick off showing weve picked up an Object
 *****************************************************************************/
#ifdef PC_VERSION
/******************************************************************************
 *			Initialise pick up displayer
 *****************************************************************************/
void	InitialisePickUpDisplay( void )
{
	int		i;

	for ( i=0;i<NUM_PU;i++ )
		pickups[i].duration = 0;
}


/******************************************************************************
 *			Draw Pickups onto Screen as Reminder weve got them
 *****************************************************************************/
void	DrawPickups(int timed)
{
	int				i,time;
	static	int		old_game_timer;
	DISPLAYPU		*pu;
	int				wa,w,x,y, drawn;

	time = savegame.timer - old_game_timer;
	old_game_timer = savegame.timer;

	if ((time <= 0) || (time >= 60))
		return;

	w = phd_winwidth/10;
	x = phd_winwidth - w;
	y = phd_winheight - w;
	wa = w;//(w*4)/3;

	pu = pickups;
	drawn = 0;
	for ( i=0;i<NUM_PU;i++,pu++,x-=wa )
	{
		if (timed)
			pu->duration -= time;
		if ( pu->duration>0 )
		{
			if (drawn==4 || drawn==8)
			{
				y-=(wa*2)/3;
				x = phd_winwidth - w;
			}

			S_DrawPickup(x,y+w, pu->sprnum);
			drawn++;
		}
		else
			pu->duration=0;
	}
}

/*****************************************************************************
 *			Show that weve picked up Something
 ****************************************************************************/
void	AddDisplayPickup(sint16 objnum)
{
	if ((objnum==SECRET_ITEM1)
	||  (objnum==SECRET_ITEM2)
	||  (objnum==SECRET_ITEM3))
		S_CDPlay(gameflow.secret_track,0);

	pickups[0].duration = 75;
	pickups[0].sprnum = objnum;
}

#endif

void DisplayModeInfo(char* szString)
	{
	if (!szString)
		{
		T_RemovePrint(LpModeTS);
		LpModeTS=0;
		return;
		}
	if (LpModeTS)
		T_ChangeText(LpModeTS,szString);
	else
		{
		LpModeTS=T_Print(-16,-16,0,szString);
		T_RightAlign(LpModeTS,1);
		T_BottomAlign(LpModeTS,1);
		}
	LnModeTSLife=75;
	}

void DrawModeInfo(void)
	{
/*	static int old_game_timer;
	int time;

	time=savegame.timer-old_game_timer;	// ugh
	old_game_timer=savegame.timer;
	if (time<=0 || time>=60)
		return;*/

	if (LpModeTS)
		{
		if (--LnModeTSLife==0)
			{
			T_RemovePrint(LpModeTS);
			LpModeTS=0;
			}
		}
	}
