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

#pragma once

#include "CoreMinimal.h"
#include "SettingsTabWidget.h"
#include "SettingsDisplayWidget.generated.h"

class USettingRowWidget;
class USurvivalUserSettings;

/**
 * L'onglet "Affichage".
 *
 * Presque tout est deja ecrit dans UGameUserSettings : mode d'affichage,
 * resolution, VSync, limite de FPS, echelle de resolution. On ne fait que
 * l'habiller. Seule la luminosite nous appartient, parce que le gamma vit sur
 * le moteur et non dans les reglages.
 *
 * Le changement de resolution ou de mode passe par une CONFIRMATION A REBOURS :
 * c'est le seul filet contre un mode que l'ecran ne sait pas afficher, situation
 * dont on ne peut sinon sortir qu'en supprimant GameUserSettings.ini a la main.
 *
 * Classe Abstract : on cree un WBP_SettingsDisplay qui en herite.
 */
UCLASS(Abstract)
class EMBERWILD_API USettingsDisplayWidget : public USettingsTabWidget
{
	GENERATED_BODY()

public:
	USettingsDisplayWidget(const FObjectInitializer& ObjectInitializer);

	virtual void NativeConstruct() override;

	virtual void RefreshFromSettings() override;
	virtual void ResetToDefaults() override;

protected:
	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> DisplayModeRow;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> ResolutionRow;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> FrameRateLimitRow;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> VSyncRow;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> ResolutionScaleRow;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<USettingRowWidget> BrightnessRow;

	/** Doit contenir {0}, remplace par les secondes restantes. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Reglages")
	FText VideoConfirmMessage;

	/** Delai avant retour automatique au mode precedent. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Reglages", meta = (ClampMin = "3", ClampMax = "30"))
	float VideoConfirmSeconds = 10.f;

	/**
	 * Proposer aussi les formats ultralarges (21:9) en plus du 16:9.
	 *
	 * La liste que renvoie le systeme contient TOUT ce que la carte accepte :
	 * 4:3, 5:4, 16:10, des modes d'un autre age. On n'en garde que deux familles.
	 * Le 16:9 est toujours accepte -- il represente plus des trois quarts des
	 * joueurs Steam a lui seul. Le 21:9 est marginal mais reel, d'ou l'option.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Reglages")
	bool bAllowUltrawide = true;

	/** Plus petite resolution proposee. En dessous, le HUD devient illisible. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Reglages")
	FIntPoint MinimumResolution = FIntPoint(1280, 720);

private:
	UFUNCTION()
	void HandleDisplayModeChanged(int32 NewIndex);

	UFUNCTION()
	void HandleResolutionChanged(int32 NewIndex);

	UFUNCTION()
	void HandleFrameRateLimitChanged(int32 NewIndex);

	UFUNCTION()
	void HandleVSyncChanged(int32 NewIndex);

	UFUNCTION()
	void HandleResolutionScaleChanged(int32 NewIndex);

	UFUNCTION()
	void HandleBrightnessChanged(int32 NewIndex);

	/** Reponse a la question posee apres un changement de mode ou de resolution. */
	UFUNCTION()
	void HandleVideoConfirmAnswered(bool bConfirmed);

	/** Applique le mode video puis demande confirmation. */
	void ApplyVideoModeAndConfirm();

	/** Recharge la liste des resolutions de l'ecran et repositionne la ligne. */
	void RebuildResolutionList();

	/** Ecarte les formats non desires. Ne vide jamais la liste completement. */
	void FilterResolutions(const FIntPoint& CurrentResolution);

	/** Index de la resolution courante dans AvailableResolutions, 0 si inconnue. */
	int32 FindCurrentResolutionIndex(const USurvivalUserSettings* Settings) const;

	/** Index de la plus grande resolution proposee, INDEX_NONE si la liste est vide. */
	int32 FindLargestResolutionIndex() const;

	/** Resolutions proposees, dans l'ordre de la ligne. */
	TArray<FIntPoint> AvailableResolutions;
};
