#pragma once

/**
 * Purpose: common player state, usable on client and server
 * Client: singleton representing the viewed player
 * Server: instance per client, clients decoupled from players
 */
CLASS(PlayerState, Object)
	ATTRIB(PlayerState, m_client, entity);
	CONSTRUCTOR(PlayerState, entity client)
	{
		CONSTRUCT(PlayerState);
		this.m_client = client;
	}
ENDCLASS(PlayerState)

.PlayerState _ps;
#define PS(this) ((this)._ps)

// TODO: renew on death
void PlayerState_attach(entity this);
void PlayerState_detach(entity this);

/**
 * Purpose: common client state, usable on client and server
 * Client: singleton representing the viewed player
 * Server: instance per client
 */
CLASS(ClientState, Object)
	ATTRIB(ClientState, m_client, entity);
	CONSTRUCTOR(ClientState, entity client)
	{
		CONSTRUCT(ClientState);
		this.m_client = client;
	}
	METHOD(PlayerState, ps_push, void(PlayerState this, entity cl))
	{
		TC(PlayerState, this);
	}
ENDCLASS(ClientState)

.ClientState _cs;

#if NDEBUG
	#define CS(this) (this._cs)
#else
	ClientState CS(Client this) { TC(Client, this); assert(this._cs); return this._cs; }
#endif

// NOTE: this exists to ease migration later on - ClientState does not exist early enough for replicated cvars!
#define CS_CVAR(this) (this)

void ClientState_attach(entity this);
void ClientState_detach(entity this);
