// Icon Studio - Mathew Simon

#pragma once

#include "CoreMinimal.h"
#include "IconStudioTypes.generated.h"

/**
 * Ce que contient l'image produite.
 *
 * Les passes autres que Final servent au debug et a la retouche : recuperer la
 * base color seule permet de recolorer une icone dans un logiciel externe sans
 * refaire le rendu. Elles gardent le meme masque de transparence que la passe
 * finale -- c'est lui qui decoupe l'objet, pas la passe.
 */
UENUM(BlueprintType)
enum class EIconStudioPass : uint8
{
	/** Rendu complet, eclairage et post-process compris. C'est la passe des icones. */
	Final UMETA(DisplayName = "Final Color"),

	/** Albedo brut, sans aucune lumiere. */
	BaseColor UMETA(DisplayName = "Base Color"),

	/** Normales monde encodees en RGB. */
	Normal UMETA(DisplayName = "World Normal"),

	/** Profondeur encodee sur RGB. Utilisable comme masque, pas comme image. */
	Depth UMETA(DisplayName = "Device Depth"),
};

/** Ce qu'on trouve derriere l'objet. */
UENUM(BlueprintType)
enum class EIconStudioBackground : uint8
{
	/** Canal alpha decoupe sur l'objet. C'est ce qu'il faut pour l'inventaire. */
	Transparent UMETA(DisplayName = "Transparent"),

	/** Aplat de couleur opaque, compose apres coup sur le meme masque. */
	SolidColor UMETA(DisplayName = "Solid Color"),
};

/**
 * Une des trois lumieres du studio.
 *
 * Les angles sont RELATIFS A LA CAMERA, jamais au monde. Sans ca, changer
 * l'angle de vue d'un objet deplacerait ses ombres et deux icones de la meme
 * serie n'auraient pas le meme eclairage -- exactement ce qu'on cherche a
 * eviter en travaillant avec des presets.
 */
USTRUCT(BlueprintType)
struct FIconStudioLight
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light")
	bool bEnabled = true;

	/** Positif = la lumiere part vers la droite de la camera. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light", meta = (EditCondition = "bEnabled", ClampMin = "-180", ClampMax = "180", Units = "deg"))
	float Yaw = 0.f;

	/** Negatif = la lumiere vient d'en haut. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light", meta = (EditCondition = "bEnabled", ClampMin = "-90", ClampMax = "90", Units = "deg"))
	float Pitch = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light", meta = (EditCondition = "bEnabled", ClampMin = "0", UIMax = "20"))
	float Intensity = 3.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light", meta = (EditCondition = "bEnabled"))
	FLinearColor Color = FLinearColor::White;

	/**
	 * Une ombre portee n'a rien a se poser dessus dans une scene vide, mais elle
	 * fait toute la lisibilite des creux d'un objet un peu detaille.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Light", meta = (EditCondition = "bEnabled"))
	bool bCastShadows = true;

	FIconStudioLight() = default;

	FIconStudioLight(float InYaw, float InPitch, float InIntensity, bool bInShadows)
		: bEnabled(true), Yaw(InYaw), Pitch(InPitch), Intensity(InIntensity), bCastShadows(bInShadows)
	{
	}
};

/**
 * Image produite par le studio : BGRA 8 bits, espace sRGB, alpha NON premultiplie.
 *
 * Non premultiplie parce que c'est ce que UMG attend d'une texture d'interface,
 * et ce que tout logiciel d'image comprend a l'ouverture du PNG.
 */
struct FIconStudioImage
{
	int32 Size = 0;
	TArray<FColor> Pixels;

	bool IsValid() const { return Size > 0 && Pixels.Num() == Size * Size; }
};
