Attribute VB_Name = "Light"

'This module handle light sources that need adaptive quality
'All lamps in a level will be stored in this module at the same time

Option Explicit

Private Type AutomaticLight
    LightSource As Long 'The reference number in the engine
    Pos As Vector3
    Radius As Single
End Type

Dim Lights() As AutomaticLight
Dim NumberOfLights As Long
Dim LightQuality As Single

Public Sub Light_Reset()
    Static I As Long
    For I = 0 To NumberOfLights - 1
        frmMain.DGE.LightSource_Delete Lights(I).LightSource
    Next I
    NumberOfLights = 0
    ReDim Preserve Lights(0 To 10)
End Sub

Private Function AddEmptyLight() As Long
    AddEmptyLight = NumberOfLights
    
    'Make room for the light source
    NumberOfLights = NumberOfLights + 1
    If NumberOfLights > UBound(Lights()) Then
        ReDim Preserve Lights(0 To UBound(Lights()) * 2)
    End If
End Function

Public Sub Light_Insert_SpotLight(Pos As Vector3, Direction As TileVector, Color As Vector3, ProjectedImage As UVRect, Radius As Single, Slopes As Single, DirY As Single)
    Static NewIndex As Long
    NewIndex = AddEmptyLight
    
    'Create the light source
    Lights(NewIndex).LightSource = frmMain.DGE.LightSource_Create_Spotlight_Atlas_Shadowcasting(Pos.X, Pos.Y, Pos.Z, Direction.X, DirY, Direction.Z, 0, 1, 0, Radius, Color.X, Color.Y, Color.Z, Slopes, Slopes, ProjectedImage.MinU, ProjectedImage.MaxU, ProjectedImage.MinV, ProjectedImage.MaxV, 0.125, 0, 3)
    Lights(NewIndex).Pos = Pos
    Lights(NewIndex).Radius = Radius
End Sub

Public Sub Light_Insert_PointLight(Pos As Vector3, Color As Vector3, Radius As Single)
    Static NewIndex As Long
    NewIndex = AddEmptyLight
    
    'Create the light source
    Lights(NewIndex).LightSource = frmMain.DGE.LightSource_Create_Point_Shadowless(Pos.X, Pos.Y, Pos.Z, Radius, Color.X, Color.Y, Color.Z)
    Lights(NewIndex).Pos = Pos
    Lights(NewIndex).Radius = Radius
End Sub

Private Sub ScheduleLight(LightIndex As Long, CameraTarget As Vector3, CameraDistance As Single, VisibleRect As TileRect)
    Static X As Single
    Static Z As Single
    Static R As Single
    Static Dist As Single
    X = Lights(LightIndex).Pos.X
    Z = Lights(LightIndex).Pos.Z
    R = Lights(LightIndex).Radius
    If VisibleRect.MinX - R <= X And X <= VisibleRect.MaxX + R + 1 And VisibleRect.MinZ - R <= Z And Z <= VisibleRect.MaxZ + R + 1 Then
        frmMain.DGE.LightSource_SetEnabled Lights(LightIndex).LightSource, True
        If VisibleRect.MinX <= X And X <= VisibleRect.MaxX + 1 And VisibleRect.MinZ <= Z And Z <= VisibleRect.MaxZ + 1 And Graphics_DynamicShadows Then
            Dist = (AbsVector3(ToVector3(CameraTarget, Lights(LightIndex).Pos)) * 1.2) + (CameraDistance * 0.5)
            If Dist > 32 Then
                'No shadows
                frmMain.DGE.LightSource_SetShadowTransparency Lights(LightIndex).LightSource, 1
            ElseIf Dist > 16 Then
                'Fade low resolution shadows
                frmMain.DGE.LightSource_SetResolutionGroup Lights(LightIndex).LightSource, 4
                frmMain.DGE.LightSource_SetShadowTransparency Lights(LightIndex).LightSource, InverseLerp(16, 32, Dist)
            ElseIf Dist > 8 Then
                'Show medium resolution shadows
                frmMain.DGE.LightSource_SetResolutionGroup Lights(LightIndex).LightSource, 3
                frmMain.DGE.LightSource_SetShadowTransparency Lights(LightIndex).LightSource, 0
            Else
                'Show high resolution shadows
                frmMain.DGE.LightSource_SetResolutionGroup Lights(LightIndex).LightSource, 2
                frmMain.DGE.LightSource_SetShadowTransparency Lights(LightIndex).LightSource, 0
            End If
        Else
            'No shadows
            frmMain.DGE.LightSource_SetShadowTransparency Lights(LightIndex).LightSource, 1
        End If
    Else
        frmMain.DGE.LightSource_SetEnabled Lights(LightIndex).LightSource, False
    End If
End Sub

Public Sub Light_Update(CameraTarget As Vector3, CameraDistance As Single, VisibleRect As TileRect)
    Static I As Long
    
    'Update each light source
    For I = 0 To NumberOfLights - 1
        ScheduleLight I, CameraTarget, CameraDistance, VisibleRect
    Next I
End Sub

