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

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ScreenFadeComponent.generated.h"

class UUserWidget;

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnScreenFadeFinished);

/**
 * Fondu plein ecran, pose sur un PlayerController.
 *
 * Un composant et non du code dans le controller : le fondu sert au jeu (mort,
 * respawn) comme au menu principal, et deux implementations du meme voile
 * finiraient par diverger.
 *
 * Le voile est un widget UMG et non le fondu camera du moteur : StartCameraFade
 * ne teinte que le rendu de la SCENE et laisse tout le HUD visible par-dessus.
 * On garde quand meme StartCameraFade en parallele, uniquement pour le fondu
 * AUDIO, que le voile ne sait pas faire.
 */
UCLASS(ClassGroup = (Survival), meta = (BlueprintSpawnableComponent))
class EMBERWILD_API UScreenFadeComponent : public UActorComponent
{
	GENERATED_BODY()

public:
	UScreenFadeComponent();

	/**
	 * Se declenche a la fin de CHAQUE fondu, entrant comme sortant.
	 * A celui qui ecoute de savoir ce qu'il attendait.
	 */
	UPROPERTY(BlueprintAssignable, Category = "Fondu")
	FOnScreenFadeFinished OnFadeFinished;

	/** Du noir vers le jeu. */
	UFUNCTION(BlueprintCallable, Category = "Fondu")
	void FadeIn(float Duration);

	/** Du jeu vers le noir, ou l'ecran reste jusqu'au prochain FadeIn. */
	UFUNCTION(BlueprintCallable, Category = "Fondu")
	void FadeOut(float Duration);

	/** Couvre l'ecran immediatement, sans animation ni delegue. */
	UFUNCTION(BlueprintCallable, Category = "Fondu")
	void SnapToBlack();

	UFUNCTION(BlueprintPure, Category = "Fondu")
	bool IsFading() const { return bFading; }

protected:
	virtual void BeginPlay() override;
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

	/** Ton WBP_Fade : un simple rectangle plein ecran, sans logique. */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Fondu")
	TSubclassOf<UUserWidget> FadeWidgetClass;

	/** Noir classique. Le blanc donne un reveil brutal. */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Fondu")
	FLinearColor FadeColor = FLinearColor::Black;

private:
	/** Cree le voile au premier besoin, et pas avant : il depend du controller. */
	void EnsureWidget();

	/** 1 = ecran entierement couvert, 0 = voile invisible. */
	void SetCoverage(float Coverage);

	APlayerController* GetOwningController() const;

	UPROPERTY(Transient)
	TObjectPtr<UUserWidget> FadeWidget;

	/** 0 = ecran couvert, 1 = jeu entierement visible. */
	float Alpha = 1.f;

	/** Valeur visee par Alpha : 0 pour partir au noir, 1 pour revenir. */
	float Target = 1.f;

	/** Duree du fondu en cours, distincte des reglages qui restent constants. */
	float CurrentDuration = 1.f;

	bool bFading = false;
};
