// Project Lab - NHTV Igad

#pragma once

#include "Engine/GameInstance.h"
#include "MoviePlayer.h"
#include "DefaultGameInstance.generated.h"


UENUM(BlueprintType)
enum class EGraphicsSetting : uint8
{
	ResolutionQuality = 0,
	AntiAliasingQuality,
	ShadowQuality,
	PostProcessQuality,
	TextureQuality,
	EffectsQuality,
};


UCLASS()
class UNREALPROJECT_API UDefaultGameInstance : public UGameInstance
{
	GENERATED_BODY()
	friend class USessionManager;
public:
	UDefaultGameInstance();

	virtual void Init() override;
	virtual void Shutdown() override;
	virtual bool HandleOpenCommand(const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld);

	virtual ULocalPlayer* CreateInitialPlayer(FString& OutError) override;
	virtual void OnSessionUserInviteAccepted(const bool bWasSuccess, const int32 ControllerId,
		TSharedPtr<const FUniqueNetId> Us, const FOnlineSessionSearchResult& res) override;

	void ShowNetworkError(const FString& msg);
	void SetupLoadingScreen();
	
	UFUNCTION(BlueprintCallable, Category = "Save")
	void SaveSettings();
	UFUNCTION(BlueprintCallable, Category = "Save")
	void LoadSettings();
	UFUNCTION(BlueprintCallable, Category = "Save")
	UCharacterSettings* GetCharacterSettings();
	UFUNCTION(BlueprintCallable, Category = "Prefs")
	void SavePrefs();
	UFUNCTION(BlueprintCallable, Category = "Prefs")
	void LoadPrefs();
	UFUNCTION(BlueprintCallable, Category = "Prefs")
	UPrefs* GetPrefs();
	UFUNCTION(BlueprintCallable, Category = "Levels")
	class UMapData* GetCurrentLevelMapData();
	UFUNCTION(BlueprintCallable, Category = "Levels")
	class UMapData* GetMapData(FString levelPath);

	// Get overall graphics settings, returns -1 if the user is using custom
	UFUNCTION(BlueprintCallable, Category = "Quality")
	int32 GetScalabilityQuality();
	// Set overall graphics settings
	UFUNCTION(BlueprintCallable, Exec, Category = "Quality")
	void SetScalabilityQuality(int32 scalability);
	// Set graphics settings from custom values, calling this will enable custom
	UFUNCTION(BlueprintCallable, Category = "Quality")
	void SetScalabilityQualityValues(int32 ResolutionQuality, int32 AntiAliasingQuality, int32 ShadowQuality, int32 PostProcessQuality, int32 TextureQuality, int32 EffectsQuality);

	// Get individual graphics value
	UFUNCTION(BlueprintCallable, Exec, Category = "Quality")
	int32 GetScalabilityQualityValue(EGraphicsSetting setting);
	// Set individual graphics value
	UFUNCTION(BlueprintCallable, Category = "Quality")
	void SetScalabilityQualityValue(EGraphicsSetting setting, int32 value);

	// The class that manages online sessions and establishing connections to other clients
	UPROPERTY(BlueprintReadOnly, Category = "Network")
	class USessionManager* sessionManager;

	UPROPERTY(BlueprintReadOnly, Category = "Levels")
	TArray<class UMapData*> maps;
	UPROPERTY()
	TMap<FString, class UMapData*> mapsByLevelName;
	UPROPERTY()
	TMap<FString, class UMapData*> mapsByLevelPath;

	UPROPERTY(BlueprintReadOnly, Category = "Player")
	bool splashScreenShown;

	UPROPERTY(EditDefaultsOnly)
	FString menuLevelPath;

	UPROPERTY(BlueprintReadOnly, Category = "Player")
	FString playerID;
private:
	virtual bool m_Tick(float DeltaSeconds);

	void m_LoadMaps();

	FLoadingScreenAttributes m_loadingScreen;
	FDelegateHandle m_tickDelegateHandle;
	ULocalPlayer* m_localPlayer;

	UPROPERTY()
	class UCharacterSettings* m_characterSettings;
	UPROPERTY()
	class UPrefs* m_prefs;
};
