#pragma once

namespace Juliet
{
    enum struct TextureFormat : uint8
    {
        Invalid,

        /* Unsigned Normalized Float Color Formats */
        A8_UNORM,
        R8_UNORM,
        R8G8_UNORM,
        R8G8B8A8_UNORM,
        R16_UNORM,
        R16G16_UNORM,
        R16G16B16A16_UNORM,
        R10G10B10A2_UNORM,
        B5G6R5_UNORM,
        B5G5R5A1_UNORM,
        B4G4R4A4_UNORM,
        B8G8R8A8_UNORM,
        /* Compressed Unsigned Normalized Float Color Formats */
        BC1_RGBA_UNORM,
        BC2_RGBA_UNORM,
        BC3_RGBA_UNORM,
        BC4_R_UNORM,
        BC5_RG_UNORM,
        BC7_RGBA_UNORM,
        /* Compressed Signed Float Color Formats */
        BC6H_RGB_FLOAT,
        /* Compressed Unsigned Float Color Formats */
        BC6H_RGB_UFLOAT,
        /* Signed Normalized Float Color Formats  */
        R8_SNORM,
        R8G8_SNORM,
        R8G8B8A8_SNORM,
        R16_SNORM,
        R16G16_SNORM,
        R16G16B16A16_SNORM,
        /* Signed Float Color Formats */
        R16_FLOAT,
        R16G16_FLOAT,
        R16G16B16A16_FLOAT,
        R32_FLOAT,
        R32G32_FLOAT,
        R32G32B32A32_FLOAT,
        /* Unsigned Float Color Formats */
        R11G11B10_UFLOAT,
        /* Unsigned Integer Color Formats */
        R8_UINT,
        R8G8_UINT,
        R8G8B8A8_UINT,
        R16_UINT,
        R16G16_UINT,
        R16G16B16A16_UINT,
        R32_UINT,
        R32G32_UINT,
        R32G32B32A32_UINT,
        /* Signed Integer Color Formats */
        R8_INT,
        R8G8_INT,
        R8G8B8A8_INT,
        R16_INT,
        R16G16_INT,
        R16G16B16A16_INT,
        R32_INT,
        R32G32_INT,
        R32G32B32A32_INT,
        /* SRGB Unsigned Normalized Color Formats */
        R8G8B8A8_UNORM_SRGB,
        B8G8R8A8_UNORM_SRGB,
        /* Compressed SRGB Unsigned Normalized Color Formats */
        BC1_RGBA_UNORM_SRGB,
        BC2_RGBA_UNORM_SRGB,
        BC3_RGBA_UNORM_SRGB,
        BC7_RGBA_UNORM_SRGB,
        /* Depth Formats */
        D16_UNORM,
        D24_UNORM,
        D32_FLOAT,
        D24_UNORM_S8_UINT,
        D32_FLOAT_S8_UINT,
        /* Compressed ASTC Normalized Float Color Formats*/
        ASTC_4x4_UNORM,
        ASTC_5x4_UNORM,
        ASTC_5x5_UNORM,
        ASTC_6x5_UNORM,
        ASTC_6x6_UNORM,
        ASTC_8x5_UNORM,
        ASTC_8x6_UNORM,
        ASTC_8x8_UNORM,
        ASTC_10x5_UNORM,
        ASTC_10x6_UNORM,
        ASTC_10x8_UNORM,
        ASTC_10x10_UNORM,
        ASTC_12x10_UNORM,
        ASTC_12x12_UNORM,
        /* Compressed SRGB ASTC Normalized Float Color Formats*/
        ASTC_4x4_UNORM_SRGB,
        ASTC_5x4_UNORM_SRGB,
        ASTC_5x5_UNORM_SRGB,
        ASTC_6x5_UNORM_SRGB,
        ASTC_6x6_UNORM_SRGB,
        ASTC_8x5_UNORM_SRGB,
        ASTC_8x6_UNORM_SRGB,
        ASTC_8x8_UNORM_SRGB,
        ASTC_10x5_UNORM_SRGB,
        ASTC_10x6_UNORM_SRGB,
        ASTC_10x8_UNORM_SRGB,
        ASTC_10x10_UNORM_SRGB,
        ASTC_12x10_UNORM_SRGB,
        ASTC_12x12_UNORM_SRGB,
        /* Compressed ASTC Signed Float Color Formats*/
        ASTC_4x4_FLOAT,
        ASTC_5x4_FLOAT,
        ASTC_5x5_FLOAT,
        ASTC_6x5_FLOAT,
        ASTC_6x6_FLOAT,
        ASTC_8x5_FLOAT,
        ASTC_8x6_FLOAT,
        ASTC_8x8_FLOAT,
        ASTC_10x5_FLOAT,
        ASTC_10x6_FLOAT,
        ASTC_10x8_FLOAT,
        ASTC_10x10_FLOAT,
        ASTC_12x10_FLOAT,
        ASTC_12x12_FLOAT,

        Count
    };

    enum struct TextureUsageFlag : uint8
    {
        None                = 0,
        Sampler             = 1 << 0, // Textures supports sampling
        ColorTarget         = 1 << 1, // Texture is color render target
        DepthStencilTarget  = 1 << 2, // Texture is depth stencil target
        GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage
        ComputeStorageRead  = 1 << 4, // Support Storage read at compute stage
        ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage
        ComputeStorageSimultaneousReadWrite =
            1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
    };

    enum struct TextureType : uint8
    {
        Texture_2D,
        Texture_2DArray,
        Texture_3D,
        Texture_3DArray,
        Texture_Cube,
        Texture_CubeArray,
    };

    enum struct TextureSampleCount : uint8
    {
        One,
        Two,
        Four,
        Eight,
    };

    // Create Information structs
    struct TextureCreateInfo
    {
        TextureType        Type;
        TextureFormat      Format;
        TextureUsageFlag   Flags;
        TextureSampleCount SampleCount;

        uint32 Width;
        uint32 Height;
        union
        {
            uint32 LayerCount;
            uint32 DepthPlane;
        }; // LayerCount is used in 2d array textures and Depth for 3d textures
        uint32 MipLevelCount;
    };

    // Opaque Type
    struct Texture;
} // namespace Juliet
