enum ShadowSceneViewModeType
{
    ShadowSceneViewModeObjectsRotatingAroundLight,
    ShadowSceneViewModeLightRotatingAroundObjects,
    ShadowSceneViewModeCount
};

struct ShadowSceneObject
{
    void Init(GraphicsDevice &GD, const String &SimplifiedFilename, const String &FullFilename, float _Theta, float _LocalZOffset);
    void Init(GraphicsDevice &GD, const BaseMesh &_SimplifiedMesh, const BaseMesh &_FullMesh, float _Theta, float _LocalZOffset);

    D3D9Mesh SimplifiedMesh;
    D3D9Mesh FullMesh;
    float Theta;
    float LocalZOffset;
};

const UINT ShadowSceneObjectCount = 3;

struct AppState;

class ShadowScene
{
public:
    void Init(D3D9GraphicsDevice &GD);
    void StatusText(AppState &state);
    void RenderFrame(D3D9GraphicsDevice &GD, MatrixController &MC);
    void RenderScene(D3D9GraphicsDevice &GD, MatrixController &MC, ShadowMapShaderType Shader);
    void RenderLight(D3D9GraphicsDevice &GD);
    void UpdateScene(AppState &state);
    void ResetLight(const Vec3f &LightPos);

    __forceinline ShadowMap& GetShadowMap()
    {
        return _ShadowMap;
    }

//private:
    Clock _Timer;
    ShadowMap _ShadowMap;
    Camera _LightCameras[6];

    D3D9Mesh _BoxWalls[6];
    D3D9Texture _BoxTextures[6];
    D3D9Texture _WoodTexture;
    
    ShadowSceneObject _Objects[ShadowSceneObjectCount];

    Vec3f _BoxTextureRepeat[6];

    Matrix4 _LightPerspective;

    float _ElapsedTime;
    ShadowSceneViewModeType _ViewMode;
    UINT _BlurPasses;
    UINT _ShadowMapResolution;
    bool _UseVarianceShadowMaps;
    bool _Paused;
};