// Fill out your copyright notice in the Description page of Project Settings.


#include "PauseMenuWidget.h"

#include "Components/Button.h"
#include "FpsPlayerController.h"

UPauseMenuWidget::UPauseMenuWidget(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Sans ce drapeau le widget ne peut pas prendre le focus clavier, et
	// NativeOnKeyDown ne serait jamais appele. Il ne se change qu'a la
	// construction, d'ou sa presence ici et pas dans Open().
	SetIsFocusable(true);
}

void UPauseMenuWidget::NativeConstruct()
{
	Super::NativeConstruct();

	if (ResumeButton)
	{
		ResumeButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleResumeClicked);
	}

	if (QuitToMenuButton)
	{
		QuitToMenuButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleQuitToMenuClicked);
	}

	if (SettingsButton)
	{
		SettingsButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleSettingsClicked);
	}

	if (InviteButton)
	{
		InviteButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleInviteClicked);

		// Evalue une seule fois : le menu de pause n'est construit qu'a la
		// premiere ouverture, donc bien apres que la session ait reussi ou
		// echoue. Rien ne peut plus changer cet etat en cours de partie.
		const AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>();
		InviteButton->SetIsEnabled(Controller && Controller->CanInviteFriends());
	}
}

void UPauseMenuWidget::NativeDestruct()
{
	if (ResumeButton)
	{
		ResumeButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleResumeClicked);
	}

	if (SettingsButton)
	{
		SettingsButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleSettingsClicked);
	}

	if (QuitToMenuButton)
	{
		QuitToMenuButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleQuitToMenuClicked);
	}

	if (InviteButton)
	{
		InviteButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleInviteClicked);
	}

	Super::NativeDestruct();
}

void UPauseMenuWidget::Open()
{
	SetInteractive(true);
}

void UPauseMenuWidget::Close()
{
	SetVisibility(ESlateVisibility::Collapsed);
}

void UPauseMenuWidget::SetInteractive(bool bInteractive)
{
	// HitTestInvisible et non Collapsed : le menu reste lisible derriere l'ecran
	// qui passe devant, mais on ne peut plus cliquer Reprendre a travers.
	SetVisibility(bInteractive ? ESlateVisibility::Visible : ESlateVisibility::HitTestInvisible);

	if (bInteractive)
	{
		// Le focus doit etre repris a CHAQUE fois que le menu redevient la couche
		// active, pas seulement a sa premiere ouverture : l'ecran de reglages et
		// la boite de confirmation le prennent pour eux et ne le rendent pas.
		SetKeyboardFocus();
	}
}

FReply UPauseMenuWidget::NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent)
{
	const FKey Key = InKeyEvent.GetKey();

	// GetVirtualKey() et non la constante, depreciee en 5.8 : la resolution se
	// fait a l'appel, donc selon la manette reellement branchee.
	if (Key == EKeys::Escape || Key == EKeys::Virtual_Gamepad_Back.GetVirtualKey())
	{
		if (AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>())
		{
			// HandleEscapeInput et non ResumeGame : c'est le controller qui tient
			// la priorite entre boite, reglages, coffre, inventaire et pause. Un
			// second chemin qui refermerait directement le menu laisserait
			// l'ecran pose par-dessus affiche dans le vide.
			Controller->HandleEscapeInput();

			// Handled : sans ca la touche continue de remonter et serait
			// consommee une seconde fois par ce qui se trouve derriere.
			return FReply::Handled();
		}
	}

	return Super::NativeOnKeyDown(InGeometry, InKeyEvent);
}

void UPauseMenuWidget::HandleSettingsClicked()
{
	if (AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>())
	{
		Controller->OpenSettings();
	}
}

void UPauseMenuWidget::HandleResumeClicked()
{
	if (AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>())
	{
		Controller->ResumeGame();
	}
}

void UPauseMenuWidget::HandleQuitToMenuClicked()
{
	if (AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>())
	{
		Controller->RequestQuitToMainMenu();
	}
}

void UPauseMenuWidget::HandleInviteClicked()
{
	if (AFpsPlayerController* Controller = GetOwningPlayer<AFpsPlayerController>())
	{
		Controller->ShowInviteFriends();
	}
}
