#pragma once

// -----------------------------------------------------------------------------
// wallhack.h
// -----------------------------------------------------------------------------
// WallhackFeature (glow): runs a cached two-tier loop instead of rescanning
// all 64 slots every repaint. Every 250 ms a snapshot refresh resolves all
// slots through the controller chain (m_hPlayerPawn) and caches each valid
// pawn together with the address of its identity slot and its team. Every
// 10 ms the repaint loop re-validates each cached pawn with a single read
// (the identity slot must still point at it) and paints it with the glow
// writes: m_glowColorOverride (packed uint32), m_bGlowing, m_iGlowType,
// plus the glow timer pins. Friendly players are blue, enemies red,
// flashed enemies white, and anyone defusing the bomb white.
// The glow level (All/Enemy/Team/Off) decides which teams are painted.
// -----------------------------------------------------------------------------

#include <vector>

#include "../core/memory.h"
#include "../core/offsets.h"
#include "../sdk/entitylist.h"
#include "../sdk/localplayer.h"

namespace features {

// Player glow painting running on its own thread.
class Wallhack
{
public:
	// Binds the memory reader, offsets, entity list and local player.
	void Initialize(const core::ProcessMemory* memory, const core::GameOffsets* offsets,
		const sdk::EntityList* entities, const sdk::LocalPlayer* player);

	// Starts the wallhack thread.
	void Start();

	// Thread entry point.
	static unsigned long __stdcall ThreadProc(void* param);

private:
	// One cached snapshot entry: the pawn pointer plus the address of its
	// identity slot (m_pEntity lives there) so the pointer can be
	// re-validated per repaint with a single read instead of a full slot
	// resolution. The team is cached with the entry.
	struct CachedPawn
	{
		uintptr_t pawn = 0;
		uintptr_t identity = 0;
		int team = 0;
	};

	// Rebuilds the pawn snapshot: resolves all 64 slots through the
	// controller chain and keeps only valid, alive player pawns.
	void RefreshPawns(uintptr_t localPawn);

	// Repaints every cached pawn; each pointer is validated against its
	// identity slot before the writes (freed pawns are skipped until the
	// next refresh).
	void Repaint(uintptr_t localPawn);

	// Paints the glow color and flags onto one pawn (six writes, like the
	// Python example: color + glowing + glow type + timer pins).
	void PaintGlow(uintptr_t pawn, int team, int localTeam);

	const core::ProcessMemory* m_memory = nullptr;
	const core::GameOffsets* m_offsets = nullptr;
	const sdk::EntityList* m_entities = nullptr;
	const sdk::LocalPlayer* m_player = nullptr;

	std::vector<CachedPawn> m_pawns;   // refreshed every 250 ms
	int m_localTeam = 0;               // cached with the snapshot
	unsigned long m_lastRefresh = 0;   // GetTickCount of the last refresh
};

} // namespace features