// Project Lab - NHTV Igad

#pragma once

#include "GUI/Menu/MenuScreenBase.h"
#include "SubMenu.h"
#include "MenuScreen.generated.h"

UCLASS()
class UMenuScreenSubMenu : public USubMenu
{
	GENERATED_BODY()
public:
	UMenuScreenSubMenu(const FObjectInitializer& init);
	virtual void NativeConstruct() override;
	virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;

	virtual void OnSuspend(USubMenu* newSubMenu, bool loseFocus);
	virtual void OnRestore(USubMenu* removedMenu);

	void FadeIn();
	void FadeOut();

	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	UMenuPanel* OpenScreenMenu(TSubclassOf<class UMenuPanel> cls);
	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	USideView* OpenSideView(TSubclassOf<class USideView> cls);

	class UMenuButton* AddButton(FString label);

	virtual void RescanItems() override;
	virtual void NativeOnMenuAction(EMenuActionBinding binding) override;

	// Assigns a button to be the back button, this button will receive a pressed event when the player presses the circle button
	void SetBackButton(UMenuButton* button) { m_backButton = button; }

	DECLARE_MULTICAST_DELEGATE_TwoParams(FOnAnimationEnded, UMenuScreenSubMenu*, int32)
	FOnAnimationEnded onAnimationEnded;

	UPROPERTY(EditDefaultsOnly, Category = "SubMenu")
	FString menuName;

private:
	UPROPERTY()
	UMenuButton* m_backButton;

	int32 m_animationType;
	float m_animationTime;
	bool m_isBeingClosed;
	friend class UMenuScreen;
};

UCLASS()
class USideView : public UMenuScreenSubMenu
{
	GENERATED_BODY()
public:
	virtual ~USideView() = default;
};

UCLASS()
class UPersistentSideView : public USideView
{
	GENERATED_BODY()
public:
	virtual ~UPersistentSideView() = default;
};

UCLASS()
class UMenuPanel : public UMenuScreenSubMenu
{
	GENERATED_BODY()
public:
};

/**
 * 
 */
UCLASS()
class UNREALPROJECT_API UMenuScreen : public UMenuScreenBase
{
	GENERATED_BODY()
public:
	void NativeConstruct() override;

	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	UMenuPanel* OpenScreenMenu(TSubclassOf<class UMenuPanel> cls);
	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	USideView* OpenSideView(TSubclassOf<class USideView> cls);
	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	void CloseAllSideViews();

	UFUNCTION(BlueprintImplementableEvent, Category="Menu Screen")
	void SwitchSideViewVisible(bool visible);

	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	void OpenPersistentSideView(UPersistentSideView* sideView);
	UFUNCTION(BlueprintCallable, Category = "Menu Screen")
	void ClosePersistentSideView(UPersistentSideView* sideView);

	// When this menu needs to be hidden
	UFUNCTION(BlueprintImplementableEvent)
	void OnShow();
	// When this menu needs to be shown
	UFUNCTION(BlueprintImplementableEvent)
	void OnHide();

	virtual void OpenSubMenu(class USubMenu* submenu) override;
	virtual void CloseSubMenu(class USubMenu* submenu) override;

private:
	void m_OpenSubMenu(class USubMenu* submenu, bool transferFocus = true);
	void m_CloseSubMenu(class USubMenu* submenu, bool persist = false);
	void m_OnFadeOutComplete(UMenuScreenSubMenu* panel, int32 type);

	bool m_sideViewActive;

	UButtonHintBar* m_buttonHintBar;
	UOverlay* m_menuContainer;
	UOverlay* m_sideViewContainer;
	UTextBlock* m_menuTitle; 
	UTextBlock* m_sideViewTitle;

	UPROPERTY()
	TArray<USideView*> m_currentSideViews;

	friend class UMenuScreenSubMenu;
};

UCLASS()
class UMainMenuScreen : public UMenuScreen
{
	GENERATED_BODY()
public:
};