// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
namespace Stride.Rendering.Lights
{
    /// <summary>
    /// Defines a group of similar lights (directional, spot...etc.)
    /// </summary>
    shader DirectLightGroup :
        LightStream,
        ShadowGroup,    // Required for "ComputeShadow()".
        TextureProjectionGroup,    // Required for "ComputeTextureProjection()".
        NormalStream, // Required for "streams.normalWS".
        PositionStream4, // Required for "streams.PositionWS".
        MaterialPixelStream // Required for "streams.viewWS"
    {
        int GetMaxLightCount()
        {
            return 0;
        }

        /// <summary>
        /// Gets the number of lights of this group
        /// </summary>
        int GetLightCount()
        {
            return 0;
        }

        /// <summary>
        /// One-time initialization before the light loop.
        /// </summary>
        void PrepareDirectLights()
        {
        }

        /// <summary>
        /// Compute the light color/direction for the specified index within this group
        /// </summary>
        void PrepareDirectLight(int lightIndex)
        {
            PrepareDirectLightCore(lightIndex);

            // Compute NdotL
            streams.NdotL = max(dot(streams.normalWS, streams.lightDirectionWS), 0.0001f);

            // Computes the shadowColor
            streams.shadowColor = ComputeShadow(streams.PositionWS.xyz, lightIndex);

            // Compute the final color with NdotL
            streams.lightColorNdotL = streams.lightColor * streams.lightAttenuation * streams.shadowColor * streams.NdotL * streams.lightDirectAmbientOcclusion;
            streams.lightSpecularColorNdotL = streams.lightColorNdotL;

            // Mask the light by the color of the projected texture:
            streams.lightColorNdotL *= ComputeTextureProjection(streams.PositionWS.xyz, lightIndex);    // TODO: Modify "streams.lightColor" instead?

            
            float3 reflectionVectorWS = reflect(-streams.viewWS, streams.normalWS);
            streams.lightSpecularColorNdotL *= ComputeSpecularTextureProjection(streams.PositionWS.xyz, reflectionVectorWS, lightIndex);
        }

        void PrepareDirectLightCore(int lightIndex)
        {
        }

        float ComputeAttenuation(float3 position, int lightIndex)
        {
            return 1;
        }
    };
}
