#ifndef CLIENT_H
#define CLIENT_H
#include <string>
#include <vector>
#include "engine/util_vector.h"

#undef NDEBUG
#include <assert.h>

#include "engine/wrect.h"
#include "engine/cl_dll.h"
#include "cvar.h"

void CheckForClientHook(FARPROC* pProc,LPCTSTR lpProcName);
int WallActive(void);
bool LambertActive(void);
int GlExtraActive(void);
void StatusDump(void);
void ParseDump(void);

std::string getOgcDirFile(const char* basename);
extern char ogcdir [256];
extern char hldir  [256];

extern struct engine_studio_api_s* pIEngineStudio;

void tintArea(int x,int y,int w,int h, struct ColorEntry* clr);
void gDrawFilledBoxAtLocation( float* origin, DWORD color = 0xFFFFFFFF, int radius=1);
void gSetHudMessage2(const char* message);
void gSetHudMessage(const char* message);
void Con_Echo(const char *fmt, ... );

// from cldll_int.h 
#ifndef CDLL_INT_H
typedef unsigned char 		byte;
typedef unsigned short 		word;
typedef struct
{
	char *name;
	short ping;
	byte thisplayer;  // TRUE if this is the calling player

  // stuff that's unused at the moment,  but should be done
	byte spectator;
	byte packetloss;

	char *model;
	short topcolor;
	short bottomcolor;

} hud_player_info_t;
#endif


//================================================================
struct local_player_info
{
	local_player_info():team(0),iClip(0),iFOV(0)
		,sin_yaw(0),minus_cos_yaw(-1),inZoomMode(false)
		,alive(false),ent(0),headshots(0)
	{}

	int team;
	struct cl_entity_s *ent;
	int iClip;
	int iFOV;  // holds the current FOV in CS, not the one which OGC has set.
	bool inZoomMode;
	bool alive;
	float punchangle[3];
	int pmFlags; 
	int pmMoveType; // movetype 5 = ladder
	float pmVelocity[3];
	float pmEyePos[3];

	float viewAngles[3];
	float sin_yaw, minus_cos_yaw;

	//int kills;  // already found in playerinfo
	//int deaths; // already found in playerinfo
	int headshots;
	float hspercent;
};
extern local_player_info me;



//================================================================
enum    { MAX_TARGET_SPOTS=10 };
enum    { MAX_HITPOINTS = 10 };
class PlayerInfo 
{
public:
	void init( int _entindex) 
	{ 
		team=0;
		iInfo=0;
		entinfo.name="\\missing-name\\";
		entinfo.ping=0;
		entinfo.thisplayer=0;
		entinfo.spectator=0;
		entinfo.packetloss=0;
		entinfo.model="missing-model";
		entinfo.topcolor=0;
		numTargetSpots=0;
		inpvs=0;
		alive=false;
		entindex = _entindex;
		distance = 1000.0;
		visible  = false;
		frags=0;
		deaths=0;
		ratio=0;
		bestplayer=false;
		hitpoints = MAX_HITPOINTS;
		health = 0;
	}

	hud_player_info_t entinfo;
	int    team;
	int    iInfo;
	float  distance;
	bool   visible;

	// for estimated health
	int hitpoints;
	int health;

	// infos needed for points system:
	int    frags;
	int    deaths;
	float  ratio;
	bool   bestplayer; // based on ratio, not frags!
	float  fovangle;   // minimum fov a player is in

	// aimbot points
	float points;

	// model based aiming data:
	int     numTargetSpots;
	vec3_t  TargetSpots[MAX_TARGET_SPOTS];

	// in player view scope (entity data received from the server)
	bool getPVS()   { return inpvs!=0;   }
	void clearPVS() { inpvs = 0;         }
	void setPVS(int i=cvar.inpvs)   { inpvs = alive ? i : 0; }
	void decrPVS()  { if(inpvs) --inpvs; }

	void setAlive( bool state=true ) { alive = state; }
	bool getAlive()                  { return  alive; }

	struct cl_entity_s * getEnt() { return gEngfuncs.GetEntityByIndex(entindex); }

	float lastOrg[3];
	float lastMsg;

private:
	int inpvs;
	bool alive;
	int entindex;

public:
	PlayerInfo() { init(0); }
};



//================================================================
enum{  MAX_VPLAYERS =36 };
class VecPlayers
	: public std::vector<PlayerInfo>
{
	typedef std::vector<PlayerInfo> STL_VecPlayers;
public:
	VecPlayers()
		: STL_VecPlayers (MAX_VPLAYERS)
	{
		for(int i=0;i<(int)size();i++) operator [] (i).init( i );
	}

	PlayerInfo& operator [] (unsigned int i)
	{
		if(i>=MAX_VPLAYERS) return STL_VecPlayers::operator[](0);
		return STL_VecPlayers::operator[](i);
	}
};
extern VecPlayers vPlayers;

#endif

