/********************************************************
    © 2020 Continuum Graphics LLC. All Rights Reserved
 ********************************************************/

#if !defined _SHADOWMATRICES_
#define _SHADOWMATRICES_

#include "/../UserLib/Lighting/TimeOverride.glsl"

#if defined TELEFOCAL_SHADOWS || defined TIME_OVERRIDE
    #if defined vsh
        flat out mat4 shadowModelViewCustom;
        flat out mat4 shadowModelViewInverseCustom;

        void CalculateShadowMatrices() {
            // Init
            shadowModelViewCustom        = shadowModelView;
            shadowModelViewInverseCustom = shadowModelViewInverse;

            //--// Rotation part

            #ifdef TIME_OVERRIDE
                // Should make sunPathRotation an option and have it be accessible here. Then the y component could just be sunPathRotation.
                vec3 lightAngles = shadowLightAngles;
                TimeOverride(lightAngles.x, lightAngles.y, lightAngles.z);
                lightAngles = radians(lightAngles);

                vec3 cosine = cos(lightAngles);
                vec3 sine   = sin(lightAngles);

                #define A cosine.x
                #define B   sine.x
                #define C cosine.y
                #define D   sine.y
                #define E cosine.z
                #define F   sine.z

                mat3 rotation = mat3(
                    -B*E + D*A*F, -C*F, A*E + D*B*F,
                    -C*A        , -D  ,-C*B        ,
                    D*A*E + B*F, -C*E, D*B*E - A*F
                );

                shadowModelViewCustom[0].xyz = rotation[0];
                shadowModelViewCustom[1].xyz = rotation[1];
                shadowModelViewCustom[2].xyz = rotation[2];

                // transpose(rotation matrix) = inverse(rotation matrix)
                rotation = transpose(rotation);

                shadowModelViewInverseCustom[0].xyz = rotation[0];
                shadowModelViewInverseCustom[1].xyz = rotation[1];
                shadowModelViewInverseCustom[2].xyz = rotation[2];
            #endif

            //--// Translation

            #ifdef TELEFOCAL_SHADOWS
                // TODO: Figure out why centerDepthSmooth doesn't seem to work
                //vec3 focalPosition = gbufferModelViewInverse[2].xyz * -gbufferProjectionInverse[3].z / ((centerDepthSmooth * 2.0 - 1.0) * gbufferProjectionInverse[2].w + gbufferProjectionInverse[3].w);
                vec3 focalPosition = gbufferModelViewInverse[2].xyz * TELEFOCAL_SHADOWS_DISTANCE;

                shadowModelViewCustom[3].xyz += mat3(shadowModelViewCustom) * focalPosition;
                shadowModelViewInverseCustom[3].xyz -= focalPosition;
            #endif
        }
    #elif defined fsh
        flat in mat4 shadowModelViewCustom;
        flat in mat4 shadowModelViewInverseCustom;
    #endif
#else
    #define CalculateShadowMatrices()
    #define shadowModelViewCustom shadowModelView
    #define shadowModelViewInverseCustom shadowModelViewInverse
#endif


#endif
