#ifndef NODE_SAMPLES_GLSL_
#define NODE_SAMPLES_GLSL_

#include "common.glsl"
#include "svo.glsl"
#include "worldFrameData.glsl"
#include "palette.glsl"

struct NodeSampleFace
{
    uint radiance;
    uint filterValue;
};

struct NodeSampleFrame
{
    NodeSampleFace faces[6];
};

struct NodeSample
{
    NodeSampleFrame frames[8];
};

struct LightSample
{
    vec3 radiance;
    vec3 filterValue;
};

layout(
    std430,
    set = VOXEL_PALETTE_DESCSET,
    binding = 1
) readonly buffer NodeSamplesBuffer
{
    NodeSample nodeSamples[];
};

LightSample fetchFaceSample(NodeID node, uint face)
{
    if ((node & GLSL_SVO_VOXEL_BIT) != 0)
    {
        Voxel voxel = readVoxel(node);

        vec4 color = decodeXYZW8(voxel.color);

        LightSample result;
        result.radiance = decodeXYZW8(voxel.lightSpec).rgb;
        result.filterValue = (vec3(1.0) - color.rgb) * color.a;

        if (color.a > 0.9999)
        {
            // Opaque; no light comes through.
            result.filterValue = vec3(1.0);
        }

        return result;
    }

    uint frame = (uFrameData.ticks / 125) & 7;
    NodeSampleFace sampleFace = nodeSamples[node].frames[frame].faces[face];

    LightSample result;
    result.radiance = decodeXYZW8(sampleFace.radiance).rgb;
    result.filterValue = decodeXYZW8(sampleFace.filterValue).rgb;

    return result;
}

LightSample mix(LightSample a, LightSample b, float c)
{
    LightSample result;
    result.radiance = mix(a.radiance, b.radiance, vec3(c));
    result.filterValue = mix(a.filterValue, b.filterValue, vec3(c));
    return result;
}

#endif