#include "STDIO.H"
#include "STDLIB.H"
#include "MATH.H"

#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include <string.h>

#define BAR_OFFSET640 4
#define BAR_OFFSET320 2

DECLARE_MESSAGE(m_BuddyInfo, BuddyUpdate)
DECLARE_MESSAGE(m_BuddyInfo, BuddyStatus)

buddy_info_t gBuddyInfo[MAX_PLAYERS];

int CHudBuddy::Init(void)
{
	HOOK_MESSAGE(BuddyStatus);
	HOOK_MESSAGE(BuddyUpdate);	
	
	m_iBuddyHealth = -1;	
	m_iMaxBuddyHealth = -1;

	m_iBuddyKi = -1;	
	m_iMaxBuddyKi = -1;

	gHUD.AddHudElem(this);
	
	// by default this is off
	m_iFlags &= ~HUD_ACTIVE;
	return 1;
}

int CHudBuddy::VidInit(void)
{
	m_HUD_mainbar = gHUD.GetSpriteIndex( "mainbar" );
	m_HUD_healthline = gHUD.GetSpriteIndex("healthline");
	m_HUD_lffront = gHUD.GetSpriteIndex("lffront");
	m_HUD_kiline = gHUD.GetSpriteIndex( "kiline" );
	m_HUD_kifront = gHUD.GetSpriteIndex("kifront");
	return 1;
}

int CHudBuddy::MsgFunc_BuddyUpdate(const char *pszName, int iSize, void *pbuf)
{
	BEGIN_READ( pbuf, iSize );
	this->m_iBuddyHealth = READ_LONG();
	this->m_iBuddyKi = READ_LONG();

	return 1;
}

// this msg lets us know a buddy has entered the world
//
// we need to get his entindex and his owners entindex to draw
// the diamond above his head correctly
//
// if he's our we also grab his max information
int CHudBuddy::MsgFunc_BuddyStatus(const char *pszName, int iSize, void *pbuf)
{
	int Owner_Ent_Index;
	int Buddy_Ent_Index;
	
	int Buddy_Max_Health;
	int Buddy_Max_Ki;
	
	// if this is 0 the buddy has died
	short Buddy_Status;

	BEGIN_READ( pbuf, iSize );
	Buddy_Status = READ_SHORT();

	Owner_Ent_Index = READ_LONG();
	Buddy_Ent_Index = READ_LONG();

	cl_entity_t* pPlayer = gEngfuncs.GetLocalPlayer();

	Buddy_Max_Health = READ_LONG();
	Buddy_Max_Ki = READ_LONG();

	gBuddyInfo[Owner_Ent_Index].buddy_index = Buddy_Status ? Buddy_Ent_Index : 0;
	
	// Team check
	//int iUserTeam = g_PlayerExtraInfo[pPlayer->index].teamnumber;
	//if ( iUserTeam < 0 )
	//{	iUserTeam = 0;
	//}

	int iOwnerTeam = g_PlayerExtraInfo[Owner_Ent_Index].teamnumber;
	if (iOwnerTeam < 0)
	{	iOwnerTeam = 0;
	}

	gBuddyInfo[Owner_Ent_Index].buddy_team = iOwnerTeam;
	gBuddyInfo[Owner_Ent_Index].powerlevel = Buddy_Max_Ki;
	gBuddyInfo[Owner_Ent_Index].playerclass = g_PlayerExtraInfo[Owner_Ent_Index].playerclass;

	if (Owner_Ent_Index == pPlayer->index)
	{
		if (Buddy_Status)
		{
			m_iFlags |= HUD_ACTIVE;
		}
		else
		{
			m_iFlags &= ~HUD_ACTIVE;
		}
		
		this->m_iMaxBuddyHealth = Buddy_Max_Health;
		this->m_iMaxBuddyKi = Buddy_Max_Ki;
	}
	
	return 1;
}

int CHudBuddy::Draw(float flTime)
{
	if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) ))
		return 1;

	if ( (gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) )
		return 1;

	// ******************************** HEALTH BAR ********************************
	int r,g,b,x,y;
	UnpackRGB(r,g,b, RGB_WHITEISH);
	
	int iWidth = gHUD.GetSpriteRect(m_HUD_lffront).right - gHUD.GetSpriteRect(m_HUD_lffront).left;
	int iHeight = gHUD.GetSpriteRect(m_HUD_lffront).bottom - gHUD.GetSpriteRect(m_HUD_lffront).top;
	
	y = ScreenHeight - iHeight; //assume KiHeigth==HealthHeigth==PowerLevelHeigth
	x = ScreenWidth  - iWidth;
	SPR_Set(gHUD.GetSprite(m_HUD_lffront), r, g, b);
	SPR_Draw(0, x, y, &gHUD.GetSpriteRect(m_HUD_lffront));

	iWidth = gHUD.GetSpriteRect(m_HUD_mainbar).right - gHUD.GetSpriteRect(m_HUD_mainbar).left;			
	x -= iWidth;

	SPR_Set(gHUD.GetSprite(m_HUD_mainbar), r, g, b);
	SPR_Draw(0, x, y, &gHUD.GetSpriteRect(m_HUD_mainbar));
	//SPR_Draw(0, ScreenWidth - iWidth, ScreenHeight - iHeight, &gHUD.GetSpriteRect(m_HUD_mainbar));

	// draw line
	if (ScreenWidth<640)
	{	iWidth = iWidth - 2 * BAR_OFFSET320;
		//x = ScreenWidth - BAR_OFFSET320 - iWidth;
		x += BAR_OFFSET320;
	}
	else
	{	iWidth = iWidth - 2 * BAR_OFFSET640;
		//x = ScreenWidth - BAR_OFFSET640 - iWidth;
		x += BAR_OFFSET640;
	}
	int iBarFill = iWidth * m_iBuddyHealth / m_iMaxBuddyHealth;
	for (int i = 0;i<iBarFill;i++)
	{	SPR_Set(gHUD.GetSprite(m_HUD_healthline), r, g, b);
		SPR_DrawHoles(0, x + i, y, &gHUD.GetSpriteRect(m_HUD_healthline));
	}

	// draw numbers	
	int iNumberHeight = gHUD.GetSpriteRect(gHUD.m_HUD_comma).bottom - gHUD.GetSpriteRect(gHUD.m_HUD_comma).top;
	int iNumberWidth = gHUD.GetNumWidth( m_iBuddyHealth, DHN_KI );
	
	//check if number fits in bar		
	if (iNumberHeight<iHeight && iNumberWidth < iWidth)
	{	int iNumberX = x + (iWidth - iNumberWidth) / 2;		
		int iNumberY = y + (iHeight - iNumberHeight) / 2;
		gHUD.DrawHudNumber(iNumberX, iNumberY, DHN_KI, m_iBuddyHealth, r, g, b);
	}	
	// ******************************** HEALTH BAR ********************************

	// ********************************   KI   BAR ********************************
	iWidth = gHUD.GetSpriteRect(m_HUD_kifront).right - gHUD.GetSpriteRect(m_HUD_kifront).left;
	iHeight = gHUD.GetSpriteRect(m_HUD_kifront).bottom - gHUD.GetSpriteRect(m_HUD_kifront).top;
	
	y = y - iHeight; // * 2; //assume KiHeigt==HealthHeight==PowerLevelHeight
	x = ScreenWidth  - iWidth;
	
	SPR_Set(gHUD.GetSprite(m_HUD_kifront), r, g, b);
	SPR_Draw(0, x, y, &gHUD.GetSpriteRect(m_HUD_kifront));

	iWidth = gHUD.GetSpriteRect(m_HUD_mainbar).right - gHUD.GetSpriteRect(m_HUD_mainbar).left;
	x -= iWidth;

	SPR_Set(gHUD.GetSprite(m_HUD_mainbar), r, g, b);
	SPR_Draw(0, x, y, &gHUD.GetSpriteRect(m_HUD_mainbar));

	// draw line
	if (ScreenWidth<640)
	{	iWidth = iWidth - 2 * BAR_OFFSET320;
		x += BAR_OFFSET320;
	}
	else
	{	iWidth = iWidth - 2 * BAR_OFFSET640;
		x += BAR_OFFSET640;
	}
	
	iBarFill = iWidth * this->m_iBuddyKi / 1000;
	for (int i = 0;i<iBarFill;i++)
	{	SPR_Set(gHUD.GetSprite(m_HUD_kiline), r, g, b);
		SPR_DrawHoles(0, x + i, y, &gHUD.GetSpriteRect(m_HUD_kiline));
	}

	// draw powerlevel in ki bar
	iNumberHeight = gHUD.GetSpriteRect(gHUD.m_HUD_comma).bottom - gHUD.GetSpriteRect(gHUD.m_HUD_comma).top;
	iNumberWidth = gHUD.GetNumWidth( this->m_iBuddyKi, DHN_KI );
	
	//check if number fits in bar		
	if (iNumberHeight<iHeight && iNumberWidth < iWidth)
	{	int iNumberX = x + (iWidth - iNumberWidth) / 2;		
		int iNumberY = y + (iHeight - iNumberHeight) / 2;
		gHUD.DrawHudNumber(iNumberX, iNumberY, DHN_KI, this->m_iMaxBuddyKi, r, g, b);
	}
	// ********************************   KI   BAR ********************************
	return 1;
}