#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include "event_api.h"
#include "pmtrace.h"
#include "pm_defs.h"
#include "triangleapi.h"
#define ROTATION_TIME 2.0
// added by Pcjoe
#include "vgui_TeamFortressViewport.h"
extern vec3_t g_CamAngles, v_forward, v_right, v_up;
	
void Draw_WorldSprite( HSPRITE sprite, vec3_t pos, float size, int RenderMode, TRICULLSTYLE tricullstyle,int r,int g, int b, int a, int frame);




HSPRITE	m_hsprCrosshair;		// Used to store the crosshair sprite
wrect_t m_CrosshairSize;		// Used to store the crosshair rectangle
extern vec3_t v_angles,v_origin;
extern buddy_info_t gBuddyInfo[MAX_PLAYERS];

/**
* sets the crosshair sprite. overwrites the engine Setcrosshair 
* function
* @author harSens
* @param HSPRITE sprite: the new crosshair sprite, NULL for none
* @param wrect_t size: the size of the new crosshair
* @param int k: if have no clue what those do , added for compatibility with the engine function
* @param int l: see k
* @param int m: see k
*/
void SetCrosshair(HSPRITE sprite, wrect_t size,int k,int l ,int m)
{	m_hsprCrosshair = sprite;
	if (m_hsprCrosshair)
	{	m_CrosshairSize.bottom = size.bottom;
		m_CrosshairSize.top = size.top;
		m_CrosshairSize.left = size.left;
		m_CrosshairSize.right = size.right;		
	}
}


int CHudCrosshair::Init(void)
{	m_hsprCrosshair = NULL;
	m_iAimedAtPlayer = 0;
	m_fLock = false;	
	gHUD.AddHudElem(this);
	Reset();
	m_iFlags |= HUD_ACTIVE;
	return 1;
}

int CHudCrosshair::VidInit()
{
	m_sprBeamBox=LoadSprite("sprites/beambox.spr");
	//m_sprBeamBox=LoadSprite("sprites/kamehamehaa.spr");
	
	return 1;
}

void CHudCrosshair::Reset()
{
	m_fLock = false;	
	m_fRotate = false;
	m_iBeamEnt=0;
}

// Pcjoe: Get Crosshair Pos
int CHudCrosshair::GetCrosshairPos( vec3_t &screen, cl_entity_t *player )
{	vec3_t org, view_ofs, v_forward, v_right, v_up;
	pmtrace_t tr;

	org = player->origin;
	gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs );
	org = org + view_ofs;

	AngleVectors( v_angles, v_forward, v_right, v_up);
	gEngfuncs.pEventAPI->EV_SetTraceHull(2);
	gEngfuncs.pEventAPI->EV_SetSolidPlayers(player->index - 1);
	gEngfuncs.pEventAPI->EV_PlayerTrace( org, org + v_forward * 8192, PM_NORMAL, -1, &tr );
	gEngfuncs.pTriAPI->WorldToScreen(tr.endpos,screen);
	m_vecOldPos = tr.endpos;
	return tr.ent;
}

void CHudCrosshair::DrawFollowRectangle()
{
	if(m_iBeamEnt)
	{
		cl_entity_t *pClient = gEngfuncs.GetEntityByIndex(m_iBeamEnt);
		ConsolePrint("Following Beam\n");
		if (pClient)
		{	
			vec3_t vecOrigin = pClient->curstate.origin;
			Draw_WorldSprite( m_sprBeamBox, vecOrigin, 100, kRenderTransAlpha, TRI_FRONT, 255, 255, 255, 255, 0);			
		}
	}
}

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

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

	// Pcjoe: Don't draw crosshair when new vgui class select is up
	if ( gViewPort->m_pESFClassMenu->isVisible() )
	{	return 1;
	}

	if (!m_hsprCrosshair)
	{	return 1;
	}
	
	cl_entity_t *player;

	int frame = 0;
	if (m_fRotate)
	{
		int iRotationParts = ((flTime-m_flRotateTime)/ROTATION_TIME) * SPR_Frames(m_hsprCrosshair);
		frame = iRotationParts % SPR_Frames(m_hsprCrosshair);
	}

	player = gEngfuncs.GetLocalPlayer();
	if ( !player )
	{	return 1;
	}

	
	
	// Added by Pcjoe, dont display crosshair if we're in melee
	/*modified by harSens
	std::list<model_manip_s>::iterator pManip = gHUD.m_ManipModel.FindByPlayerAndOtherIndex(player->index);
	*/
	model_manip_s *pManip = gHUD.m_ManipModel.FindByPlayerAndOtherIndex(player->index);
	if(pManip!=NULL && ((pManip->iFlags & MANIP_FLAG_CONNECT) || (pManip->iFlags & MANIP_FLAG_MSTRUGGLE)))
	{	return 1;
	}

	vec3_t screen;
	int r,g,b;

	physent_t *pEnt;
	int iHit;
	if(m_fLock)
	{
		iHit=0;
		gEngfuncs.pTriAPI->WorldToScreen(m_vecOldPos,screen);		
	}
	else
	{
		iHit = GetCrosshairPos( screen, player );		
	}
		
	//assume we didn't hit a player, turn white
	UnpackRGB(r,g,b, RGB_WHITEISH);
	m_iAimedAtPlayer = 0;
	m_bAimedAtBuddy = false;

	//check for player hit
	pEnt = gEngfuncs.pEventAPI->EV_GetPhysent( iHit );
	if (pEnt)
	{	if (pEnt->info > 0 && pEnt->info <= MAX_PLAYERS)
		{	if (pEnt->player && pEnt->solid != SOLID_NOT && g_PlayerInfoList[pEnt->info].name != NULL)
			{	if ( pEnt->team && (pEnt->team == g_iTeamNumber) )
				{	//crosshair hit player on our team -> turn green
					UnpackRGB(r,g,b, RGB_GREENISH);
				}
				else
				{	//crosshair hit player on opposite team -> turn red
					UnpackRGB(r,g,b, RGB_REDISH);
				}
				m_iAimedAtPlayer = pEnt->info;
			}
		}
		else if(pEnt->info > MAX_PLAYERS) // maybe they are aiming at a buddy?
		{
			for (int i = 0; i <= MAX_PLAYERS; i++)
			{
				if(gBuddyInfo[i].buddy_index == pEnt->info)
				{
					if ( (gBuddyInfo[i].buddy_team == g_iTeamNumber) )
					{	//crosshair hit player on our team -> turn green
						UnpackRGB(r,g,b, RGB_GREENISH);
					}
					else
					{	//crosshair hit player on opposite team -> turn red
						UnpackRGB(r,g,b, RGB_REDISH);
					}
					m_iAimedAtPlayer = i;
					m_bAimedAtBuddy = true;
				}
			}
		}
	}	
	
	
	
	//draw crosshair
	int width = m_CrosshairSize.right - m_CrosshairSize.left;
	int height = m_CrosshairSize.bottom - m_CrosshairSize.top;
	SPR_Set(m_hsprCrosshair, r, g, b );
	m_iX = XPROJECT(screen.x);
	m_iY = YPROJECT(screen.y);
	SPR_DrawHoles(frame, m_iX-width/2, m_iY-height/2, &m_CrosshairSize);
	
	return 1;
}