
#pragma once

#include "CoreMinimal.h"
#include "StatForgeDefs.h"

class STATFORGE_API FStatForgeRegistry
{
public:
	
	static TArray<FStatDef>& Get()
	{
		static TArray<FStatDef> Registry;
		return Registry;
	}
	
	static void RegisterStat(const FName& StatName)
	{
		UE_LOG(LogTemp, Warning, TEXT("StatForge: Registering %s"), *StatName.ToString());

		const bool bAlreadyRegistered = Get().ContainsByPredicate([&](const FStatDef& Def)
		{
			return Def.StatName == StatName;
		});
		
		if (!bAlreadyRegistered)
		{
			FStatDef StatDef;
			StatDef.StatName = StatName;
			Get().Add(StatDef);
		}
	}
};

#define STATFORGE_DECLARE_STAT(StatName)\
	namespace FStat\
	{\
		extern const FName StatName;\
	}\

#define STATFORGE_DECLARE_STAT_NS(Group, StatName)\
	namespace FStat\
	{\
		namespace Group\
		{\
			extern const FName StatName;\
		}\
	}\


#define STATFORGE_MAKE_STAT(StatName)\
	namespace FStat\
	{\
		const FName StatName = FName(#StatName);\
		namespace Detail\
		{\
			struct FAutoRegister_##StatName\
		{\
			FAutoRegister_##StatName() { FStatForgeRegistry::RegisterStat(FName(#StatName)); }\
		};\
			FAutoRegister_##StatName AutoRegister_##StatName;\
		}\
	}\

#define STATFORGE_MAKE_STAT_NS(Group, StatName)\
	namespace FStat\
	{\
		namespace Group\
		{\
			const FName StatName = FName(#Group "." #StatName);\
			namespace Detail\
			{\
				struct FAutoRegister_##Group##_##StatName\
				{\
					FAutoRegister_##Group##_##StatName()\
				{ FStatForgeRegistry::RegisterStat(FName(#Group "." #StatName)); }\
				};\
				FAutoRegister_##Group##_##StatName AutoRegister_##Group##_##StatName;\
			}\
		}\
	}\
