// Project Lab - NHTV Igad

#pragma once

#include "MenuAction.h"
#include "GameFramework/PlayerController.h"
#include "PlayerSetupState.h"
#include "PlayerControllerBase.generated.h"

// Input method for local players
UENUM(BlueprintType)
enum class EInputMethod : uint8
{
	PC,
	X360,
	DS4
};

/**
 * 
 */
UCLASS()
class UNREALPROJECT_API APlayerControllerBase : public APlayerController
{
	GENERATED_BODY()

public:
	APlayerControllerBase(const FObjectInitializer& init);
	
	virtual void BeginPlay() override;
	virtual void SetupInputComponent() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
	virtual void PlayerTick(float DeltaTime) override;
	virtual void Destroyed() override;

	virtual void OnLearnSkill(class UBaseSkillObject* object);
	virtual void OnUnlearnSkill(class UBaseSkillObject* object);

	UFUNCTION(BlueprintCallable, Category = "MenuStack")
	void AddMenuInputItem(class UMenuItemBase* item, int32 priority = 0);
	UFUNCTION(BlueprintCallable, Category = "MenuStack")
	void RemoveMenuInputItem(class UMenuItemBase* item);

	UFUNCTION(BlueprintCallable, Category = "Input")
	EInputMethod GetInputMethod() const;
	UFUNCTION(BlueprintCallable, Category = "Input")
	TArray<FString> ScanForJoysticks();
	UFUNCTION(BlueprintCallable, Category = "Input")
	void SelectJoystick(int32 joystick);

	virtual void PreClientTravel(const FString& PendingURL, ETravelType TravelType, bool bIsSeamlessTravel);

	// Called from the game when we should move to the lobby
	UFUNCTION(Client, Reliable)
	void EnterLobby();
	virtual void OnEnterLobby();

	// Call to return to the main menu / leave current game
	UFUNCTION(BlueprintCallable, Category = "Game")
	void ReturnToMenu();
	
	// Replication callbacks
	virtual void OnRep_PlayerState() override;
	virtual void OnRep_Pawn() override;

	// Template state acquisition functions
	template<typename T> T* GetPlayerState()
	{
		return Cast<T>(PlayerState);
	}
	template<typename T> T* GetGameState()
	{
		if(!GetWorld())
			return nullptr;
		return Cast<T>(GetWorld()->GameState);
	}

	// Called when the setupState is replicated
	UFUNCTION()
	virtual void OnRep_Setup();

	// Lobby Character selection
	UPROPERTY(replicatedUsing=OnRep_Setup)
	FPlayerSetupState setupState;

	UPROPERTY(BlueprintReadOnly, Category = "Overlay")
	class UScreenOverlay* overlay;

	UPROPERTY(BlueprintReadOnly, Category = "Overlay")
	class UTransitionScreen* transitionScreen;

protected:
	virtual void OnMenuAction(EMenuActionBinding action);
private:

	void m_OnMenuConfirm();
	void m_OnMenuBack();
	void m_OnMenuStart();
	void m_OnMenuUp();
	void m_OnMenuDown();
	void m_OnMenuLeft();
	void m_OnMenuRight();
	void m_OnMenuOpt1();
	void m_OnMenuOpt2();
	void m_OnMenuLeftPressed();
	void m_OnMenuRightPressed();
	void m_OnMenuLeftReleased();
	void m_OnMenuRightReleased();
	void m_OnMenuShoulderLeft();
	void m_OnMenuShoulderRight();
	void m_OnMenuOptionsButton();

	bool m_onSetupStateSet;

	bool m_repeatLeft;
	bool m_repeatRight;

	TArray<FString> m_recentJoystickScan;

	UPROPERTY()
	TArray<class UMenuItemBase*> m_menuItemStack;
};
