#pragma once

#include <common/constants.qh>
#include <common/weapons/_all.qh>

bool autocvar_cl_db_saveasdump;
bool autocvar_cl_unpress_zoom_on_spawn = true;
bool autocvar_cl_unpress_zoom_on_death = true;
bool autocvar_cl_unpress_zoom_on_weapon_switch = true;
bool autocvar_cl_unpress_attack_on_weapon_switch = false;
bool autocvar_hud_showbinds;
bool autocvar_hud_showbinds_limit;
bool autocvar__hud_showbinds_reload;
bool autocvar_developer_csqcentities;
#if 0
// TODO: change this path after next (0.9) release
// or the release after it to support the old-stable release
// this can't be done now as players would lack these from their configs then
bool autocvar_cl_race_checkpoint_splits_console;
bool autocvar_cl_race_cptimes_showspeed = false;
bool autocvar_cl_race_cptimes_showspeed_unit = true;
float autocvar_cl_race_cptimes_namesize = 10;
#else
AUTOCVAR_SAVE(cl_race_checkpoint_splits_console, bool, 1, "print checkpoint splits to console");
AUTOCVAR_SAVE(cl_race_cptimes_showspeed, bool, 0, "show race checkpoint speed (NOTE: ignores vertical speed)");
AUTOCVAR_SAVE(cl_race_cptimes_showspeed_unit, bool, 1, "show race checkpoint speed units");
AUTOCVAR_SAVE(cl_race_cptimes_namesize, float, 10, "maximum player name length in race checkpoint messages");
#endif
bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gametype
bool autocvar_cl_race_cptimes_showself = false;
bool autocvar_cl_welcome = true;
bool autocvar_cl_autodemo_delete;
bool autocvar_cl_autodemo_delete_keepmatches;
bool autocvar_menu_gamemenu = true;

// Map coordinate base calculations need these
vector mi_center;
vector mi_scale;
// Minimap
string minimapname;

bool postinit;
entity gametype;
string gametype_custom_name;
// temporary hack
#define ISGAMETYPE(NAME) (gametype == MAPINFO_TYPE_##NAME)

float FONT_USER = 8;


void PostInit();

void Ent_Remove(entity this);

void Gametype_Init();

entity players;
entity teams;
float team_count; // real teams

void AuditLists();

float RegisterPlayer(entity player);

void RemovePlayer(entity player);

void MoveToLast(entity e);

float RegisterTeam(entity Team);

void RemoveTeam(entity Team);

entity GetTeam(int Team, bool add);

bool SetTeam(entity pl, int Team);

vector hud_fontsize;

float RANKINGS_RECEIVED_CNT;
float RANKINGS_DISPLAY_CNT;
string grecordholder[RANKINGS_CNT];
float grecordtime[RANKINGS_CNT];

entity playerslots[255]; // 255 is engine limit on maxclients
entity teamslots[17];    // 17 teams (including "spectator team")
.bool gotscores;
.entity owner;
.bool ready;
.bool eliminated;

IntrusiveList g_drawables;
IntrusiveList g_drawables_2d;
IntrusiveList g_damagetext;
IntrusiveList g_radarlinks;
IntrusiveList g_radaricons;
STATIC_INIT(main)
{
	g_drawables = IL_NEW();
	g_drawables_2d = IL_NEW();
	g_damagetext = IL_NEW();
	g_radarlinks = IL_NEW();
	g_radaricons = IL_NEW();
}

.void(entity) draw;
.void(entity) draw2d;
.void(entity) entremove;
float drawframetime;
vector view_origin, view_forward, view_right, view_up;

.float renderflags; // engine field

bool button_zoom;
bool spectatorbutton_zoom;
bool observe_blocked;
bool button_attack2;

float current_viewzoom = 1;
float zoomin_effect;
bool warmup_stage;

bool campaign;
string hostname;
string welcome_msg;
int srv_minplayers;
int srv_maxplayers;
float welcome_msg_menu_check_maxtime;
void Welcome_Message_Show_Try();

string ignore_list;
bool ignore_list_apply_time;
void ignore_list_apply();

void Fog_Force();

string _getcommandkey(string text, string command, bool forcename);
#define getcommandkey(cmd_name, command) _getcommandkey(cmd_name, command, false)
#define getcommandkey_forcename(cmd_name, command) _getcommandkey(cmd_name, command, true)

void Release_Common_Keys();

string vote_called_vote;
bool ready_waiting;
bool ready_waiting_for_me;
bool vote_waiting;
bool vote_waiting_for_me;

float current_zoomfraction;

int vid_width, vid_height;
float vid_pixelheight;

float camera_active;		// Demo camera is active if set to true
float chase_active_backup;
float camera_roll;
vector camera_direction;

const float ALPHA_MIN_VISIBLE = 0.003;

float armorblockpercent;
float damagepush_speedfactor;

//hooks
int calledhooks;
const int HOOK_START        = 1; // VM init
const int HOOK_END          = 2; // VM shutdown
const int HOOK_INTERMISSION = 4; // intermission start

.float ping, ping_packetloss, ping_movementloss;

float g_trueaim_minrange;

int hud;
float view_quality;

int num_spectators;
const int MAX_SPECTATORS = 7;
int spectatorlist[MAX_SPECTATORS];

int framecount;

float GetSpeedUnitFactor(int speed_unit);
string GetSpeedUnit(int speed_unit);

.int enttype; // entity type sent from server
.int sv_entnum; // entity number sent from server

.int team;
.int team_size;

int binddb;

// Spectating
// -1 - observing
// 0 - playing
// >0 - id of spectated player
int spectatee_status = -1; ///< the -1 disables HUD panels before CSQC receives necessary data
float spectatee_status_changed_time;

#define player_currententnum (spectatee_status > 0 ? spectatee_status : player_localnum + 1)

// database for misc stuff
int tempdb;
int ClientProgsDB;
vector hook_shotorigin[4]; // WEAPONTODO

float serverprevtime, serverdeltatime;

float ticrate;

int serverflags;
