#pragma once
#include "GasaCommon.h"
#include "Engine/Engine.h"

#include "Engine/LevelScriptActor.h"
#include "Networking/GasaNetLibrary.h"

#include "GasaLevelScriptActor.generated.h"

UCLASS(Blueprintable)
class GASA_API AGasaLevelScriptActor : public ALevelScriptActor
{
    GENERATED_BODY()
public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Post Process")
    TObjectPtr<APostProcessVolume> GlobalPPV;

	AGasaLevelScriptActor();

#pragma region GameFramework
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	bool bOverrideGameFrameworkReady = false;

	UFUNCTION()
	void OnGameFrameworkInitialized();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName="On Game Framework Initialized"))
	void BP_OnGameFrameworkInitialized();	
#pragma endregion GameFramework

#pragma region NetSlime
	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
	FORCEINLINE bool IsClient()               const { return Gasa::IsClient( this ); }
	FORCEINLINE bool IsListenServer()         const { return Gasa::IsListenServer( this ); }
	FORCEINLINE bool IsNetOwner()             const { return Gasa::IsNetOwner( this ); }
	FORCEINLINE bool IsServer()               const { return Gasa::IsServer( this ); }
	FORCEINLINE bool IsSimulatedProxy()       const { return Gasa::IsSimulatedProxy( this ); }
	FORCEINLINE void NetLog(
		FString           Message,
		EGasaVerbosity    Verbosity = EGasaVerbosity::Log,
		FLogCategoryBase& Category  = LogGasaNet,
		bool              DumpStack = false,
		int32             Line      = __builtin_LINE(),
		ANSICHAR const*   File      = __builtin_FILE(),
		ANSICHAR const*   Func      = __builtin_FUNCTION()
	)
	{
		Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
	}
#pragma endregion NetSlime

#pragma region Actor
    void BeginPlay() override;
#pragma endregion endActor
};

namespace Gasa
{
	inline
    AGasaLevelScriptActor* GetLevelActor(UObject* Context, ULevel* OwnerLevel = nullptr) {
		UWorld* World = GEngine->GetWorldFromContextObject(Context, EGetWorldErrorMode::LogAndReturnNull);
		if (World == nullptr)
		{
			Log("World is null... are you running in a proper context?", ELogV::Error);
			return nullptr;
		}
		return Cast<AGasaLevelScriptActor>(World->GetLevelScriptActor(OwnerLevel));
	}
}
