// ScoreBrd.c

#include "ult_64.h"
#include "main.h"
#include "file.h"
#include "define.h"
#include "ml.h"

#include "misc.h"
#include "view.h"
#include "scorebrd.h"


#define RED			2
#define YELLOW	5
#define GREEN		12

#define MTL_TIME 1
#define MTL_AWAY 2
#define MTL_HOME 3


static vector16
	Base;

static s32
	Radius;

static u8
	*Object;

static SMaterial
	*Materials;

static Gfx
	*GfxList;


/********************************************************************/

static u8
	SmallFont[][5][3] =
	{
		 1,  2,  1,
		 2,  0,  2,
		 1, 18,  1,
		 2,  0,  2,
		 1,  2,  1,

		17, 18,  1,
		18,  0,  2,
		17, 18,  1,
		18,  0,  2,
		17, 18,  1,

		 1,  2,  1,
		18,  0,  2,
		 1,  2,  1,
		 2,  0, 18,
		 1,  2,  1,

		 1,  2,  1,
		18,  0,  2,
		 1,  2,  1,
		18,  0,  2,
		 1,  2,  1,

		 1, 18,  1,
		 2,  0,  2,
		 1,  2,  1,
		18,  0,  2,
		17, 18,  1,

		 1,  2,  1,
		 2,  0, 18,
		 1,  2,  1,
		18,  0,  2,
		 1,  2,  1,

		 1,  2,  1,
		 2,  0, 18,
		 1,  2,  1,
		 2,  0,  2,
		 1,  2,  1,

		 1,  2,  1,
		18,  0,  2,
		17, 18,  1,
		18,  0,  2,
		17, 18,  1,

		 1,  2,  1,
		 2,  0,  2,
		 1,  2,  1,
		 2,  0,  2,
		 1,  2,  1,

		 1,  2,  1,
		 2,  0,  2,
		 1,  2,  1,
		18,  0,  2,
		17, 18,  1,

		17, 18, 17,
		18,  0, 18,
		17, 18, 17,
		18,  0, 18,
		17, 18, 17,
	},
	LargeFont[][7][4] =
	{
		 1,  2,  2,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1, 18, 18,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,

		17, 18, 18,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		17, 18, 18,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		17, 18, 18,  1,

		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		 1,  2,  2,  1,
		 2,  0,  0, 18,
		 2,  0,  0, 18,
		 1,  2,  2,  1,

		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		 1,  2,  2,  1,

		 1, 18, 18,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		17, 18, 18,  1,

		 1,  2,  2,  1,
		 2,  0,  0, 18,
		 2,  0,  0, 18,
		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		 1,  2,  2,  1,

		 1,  2,  2,  1,
		 2,  0,  0, 18,
		 2,  0,  0, 18,
		 1,  2,  2,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,

		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		17, 18, 18,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		18, 18, 18,  1,

		 1,  2,  2,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,

		 1,  2,  2,  1,
		 2,  0,  0,  2,
		 2,  0,  0,  2,
		 1,  2,  2,  1,
		18,  0,  0,  2,
		18,  0,  0,  2,
		17, 18, 18,  1,

		17, 18, 18, 17,
		18,  0,  0, 18,
		18,  0,  0, 18,
		17, 18, 18, 17,
		18,  0,  0, 18,
		18,  0,  0, 18,
		17, 18, 18, 17,
	};


static void DrawSmallNum( s32 num, s32 digits, s32 color, s32 tnum, s32 xpos, s32 ypos )
{
	u8
		*tex;
	s32
		c,
		x,
		y,
		off,
		clip,
		dim = FALSE;

	if (digits < 0)
	{
		digits = -digits;
		clip = TRUE;
	}
	else
		clip = FALSE;

	tex = Materials[tnum].Texture;
	tex += (ypos * 32) + xpos;
	tex += (digits - 1) * 4;

	while (digits)
	{
		if (dim)
			off = 10;
		else
		{
			off = num % 10;
			num /= 10;
		}

		for (y=0; y<5; y++)
		{
			for (x=0; x<3; x++)
			{
				c = SmallFont[off][y][x];

				if (c)
					c += color;

				if (clip && digits == 1)
				{
					if (x == 2)
						tex[x] = c;
				}
				else
					tex[x] = c;
			}

			tex += 32;
		}

		if (!num)
			dim = TRUE;

		digits--;
		tex -= 4 + (5 * 32);
	}
}


static void DrawLargeNum( s32 num, s32 digits, s32 color, s32 tnum, s32 xpos, s32 ypos )
{
	u8
		*tex;
	s32
		c,
		x,
		y,
		off,
		dim = FALSE;

	tex = Materials[tnum].Texture;
	tex += (ypos * 32) + xpos;
	tex += (digits - 1) * 6;

	while (digits)
	{
		if (dim)
			off = 10;
		else
		{
			off = num % 10;
			num /= 10;
		}

		for (y=0; y<7; y++)
		{
			for (x=0; x<4; x++)
			{
				c = LargeFont[off][y][x];

				if (c)
					c += color;

				tex[x] = c;
			}

			tex += 32;
		}

		if (!num)
			dim = TRUE;

		digits--;
		tex -= 6 + (7 * 32);
	}
}


void ScoreBrd_Update()
{
	s32
		i,
		y,
		num,
		secs;

	num = pcl__gMatch->sb___mQuarter + 1;
	DrawSmallNum( num, -2, YELLOW, MTL_TIME, 23, 17 );


	num = GetNumberTimeOutsRemaining(0);
	DrawSmallNum( num, 1, YELLOW, MTL_TIME, 7, 39 );

	num = GetNumberTimeOutsRemaining(1);
	DrawSmallNum( num, 1, YELLOW, MTL_TIME, 22, 39 );


	num = pcl__gMatch->apcl_mTeamRam[0]->cl___tStatGame.uw___tTF;
	DrawSmallNum( num, 2, YELLOW, MTL_TIME, 4, 57 );

	num = pcl__gMatch->apcl_mTeamRam[1]->cl___tStatGame.uw___tTF;
	DrawSmallNum( num, 2, YELLOW, MTL_TIME, 21, 57 );


	secs = time_left / ONE_SEC;
	if (secs < 0)
		secs = 0;

	num = secs / 60;
	DrawLargeNum( num, 2, YELLOW, MTL_TIME, 4, 4 );

	secs -= num * 60;

	num = secs / 10;
	DrawLargeNum( num, 1, YELLOW, MTL_TIME, 17, 4 );

	num = secs % 10;
	DrawLargeNum( num, 1, YELLOW, MTL_TIME, 23, 4 );


	num = pcl__gMatch->apcl_mTeamRam[0]->uw___tPoints;
	DrawLargeNum( num, 3, RED, MTL_HOME, 8, 10 );

	num = pcl__gMatch->apcl_mTeamRam[1]->uw___tPoints;
	DrawLargeNum( num, 3, RED, MTL_AWAY, 8, 10 );


	y = 29;

	for (i=0; i<5; i++)
	{
		num = player[i].plyrROM->ub___pNum;
		DrawSmallNum( num, 2, YELLOW, MTL_HOME, 2, y );

		num = player[i].plyrRAM->cl___pStatGame.uw___pPF;
		if(num > 9)
		{	// bug # 699 (sort of)
			num = 9;
		}
		DrawSmallNum( num, 1, RED, MTL_HOME, 13, y );

		num = player[i].plyrRAM->uw___pPoints;
		DrawSmallNum( num, 3, GREEN, MTL_HOME, 19, y );

		y += 7;
	}


	y = 29;

	for (i=5; i<10; i++)
	{
		num = player[i].plyrROM->ub___pNum;
		DrawSmallNum( num, 2, YELLOW, MTL_AWAY, 2, y );

		num = player[i].plyrRAM->cl___pStatGame.uw___pPF;
		DrawSmallNum( num, 1, RED, MTL_AWAY, 13, y );

		num = player[i].plyrRAM->uw___pPoints;
		DrawSmallNum( num, 3, GREEN, MTL_AWAY, 19, y );

		y += 7;
	}
}


Gfx *ScoreBrd_Draw( Gfx *gp )
{
	if (View_Inside( &Base, Radius ) && View->Camera.Pitch < 14000)
	{
		gDPPipeSync( gp++ );
		gDPSetAlphaCompare( gp++, G_AC_NONE );
		gDPSetRenderMode( gp++, G_RM_OPA_SURF, G_RM_OPA_SURF2 );
		gSPDisplayList( gp++, GfxList );
	}

	return( gp );
}


void ScoreBrd_Init( void *workspace )
{
	vector16
		min,
		max;
	Gfx
		*gp;
	u8
		*mem;
	s32
		size;

	Object = AllocAndLoadFile( "ScoreBrd.OBJ", MEM_ANY );
	Materials = (SMaterial *)AllocAndLoadFile( "ScoreBrd.MTL", MEM_ANY );
	FixUpMatList( Materials, 4 );

	Obj_CalcExtents( Object, &min, &max );

	// ScoreBoard geometry is scaled down by half, so we need to bump it back up...

	min.x <<= 1;
	min.y <<= 1;
	min.z <<= 1;

	max.x <<= 1;
	max.y <<= 1;
	max.z <<= 1;

	Base.x = (min.x + max.x) >> 1;
	Base.y = (min.y + max.y) >> 1;
	Base.z = (min.z + max.z) >> 1;

	Radius  = (max.x - Base.x) * (max.x - Base.x);
	Radius += (max.y - Base.y) * (max.y - Base.y);
	Radius += (max.z - Base.z) * (max.z - Base.z);
	Radius = (s32)sqrtf( (float)Radius );


	gDPSetCombineMode( &TexModeCombine, G_CC_DECALRGB, G_CC_DECALRGB );
	gp = DrawObject( workspace, Object, Materials );
	gSPEndDisplayList( gp++ );
	size = (s32)gp - (s32)workspace;
	GfxList = (Gfx *)MemMalloc( size, MEM_ANY );
	gp = DrawObject( GfxList, Object, Materials );
	gSPEndDisplayList( gp++ );
}


void ScoreBrd_Deinit()
{
	MemFree( GfxList );

	MemFree( Materials );
	MemFree( Object );
}
