#ifndef __SMMAXSCENE

#define __SMMAXSCENE

#pragma warning(disable:4786) 

#ifndef RETAIL

#define MAXSCENE_IMPORTER

#endif

#include <vector>
#include <map>
#include "SM_Renderable.h"
#include "SM_KeyFrame.h"
#include "SM_KFAnimable.h"
#include "MBStaticList.h"


class   D3DMesh;
class   D3DGeometry;
class   D3DLight;
class   MVFSFILE;
struct  Vector3D;
struct  Quaternion;
struct  MetaFileNode;
struct  Viewport;
struct  KeyFrameSequence;
struct  ScalarSequence;
struct  RenderMesh;
class   RenderParticleSystem;
class   SM_GeomMorpher;
class	  SM_DistortBall;
class   SM_SpikeTube;
class   SM_FFTBall;
class   SM_Twister;



struct MaxCamera : IKFAnimable
{
  MaxCamera()
  {
    m_pScalarSequence=0;
  }

  KeyFrame          m_KeyFrame;  
  float             m_fFOV;
  float             m_fNear;
  float             m_fFar;
  char              m_pcName[256];

  void              SetScalarSequence(ScalarSequence* pSequence);
  virtual void      SetStartTime(float fTime);

//protected:

  ScalarSequence*   m_pScalarSequence;
  float             m_fScalarSequenceStartTime;  

  int               Load(MVFSFILE* f);
  int               Save(MVFSFILE* f);  
};

struct MaxTexture
{
  char*             m_pcTextureName;
};

struct MaxMaterial
{
  int               m_iShaderID;  
};





class MaxScene : public IRenderable
{
public:
          MaxScene          ();
          ~MaxScene         ();
  int     Init              ();
  int     Shutdown          ();
  
  #ifdef MAXSCENE_IMPORTER
  int     CompileML         (const char* pcMLFilename, MVFSFILE* f);
  #endif

  int     LoadBin           (MVFSFILE* f);
  

  void    SetParticleSystemParams(const char* pcName, const char* pcParams);  
  void    SetCamera         (const char* pcName);
  void    Render            (RenderContext* pRenderContext, int iOutcode);
  void    Render            (RenderContext* pRenderContext, int iOutcode, bool bClearColor);  
  void    ClearCache        ();
  void    PreCache          ();
  void    RenderShadows     ();
  void    ClearForShadow    (RenderContext* pRenderContext);
  
  void    SetStartTime      (float fTime);
  void    SetAnimationOffset(float fTime);
  void    SetSpeed          (float fSpeed);

  float   GetSceneTime      (float fTime)
  {
    return m_fStartTime + m_fOffsetTime + (fTime - m_fStartTime)*m_fSpeed;
  }

  float   GetStartTime      ()
  {
    return m_fStartTime;
  }

  void    UpdateRC(RenderContext* pRC, float fTime);

  


  
  D3DMesh*     GetMesh      (char* pcName);
  D3DGeometry* GetGeometry  (char* pcName);
  
  bool                            m_bVertexColors;
  bool                            m_bFog;
  bool                            m_bFlipX, m_bFlipY;
  bool                            m_bRenderShadows;
  float                           m_fFogNear, m_fFogFar;
  unsigned                        m_uColor;

  float                           m_fX, m_fY, m_fWidth, m_fHeight;

  float                           m_fNoiseX, m_fNoiseY, m_fNoiseZ;
  float                           m_fNoiseStartTime, m_fNoiseDuration;  

  
  void                            Reset();
  
protected:
  void                            ResetStatus();
  void                            UpdateTimes();
  
  struct MeshObject
  {
    RenderMesh* m_pRenderMesh;
    KeyFrame    m_PositionRotation;
    KeyFrame    m_PivotPositionRotation;
    int         m_iParent;
  };

  struct LoadData
  {
    LoadData();
    ~LoadData();

    int Init();
    int Shutdown();    

    std::vector<MeshObject>         m_MeshObjects;
    std::vector<MaxTexture*>        m_Textures;
    std::vector<MaxMaterial*>       m_Materials;
    std::map<int, int>              m_IDToMesh;
    std::map<int, int>              m_IDToCamera;  
    std::map<int, int>              m_IDToTexture;  
    std::map<int, int>              m_IDToMaterial;  
    std::map<int, int>              m_IDToLight;
    std::vector<int>                m_ControllerIndexToID;
    std::vector<int>                m_ScalarControllerIndexToID;
    std::vector<D3DMesh*>           m_Meshes;
    std::vector<D3DLight*>          m_Lights;
    std::vector<KeyFrameSequence*>  m_KeyFrames;
    std::vector<ScalarSequence*>    m_Scalars;
    std::vector<MaxCamera*>         m_Cameras;      

  };

  void    ClearZ            (RenderContext* pRenderContext, bool bClearColor);

  #ifdef MAXSCENE_IMPORTER
  int     SaveBin           (MVFSFILE* f, LoadData* pData);

  int     LoadMeshes        (MetaFileNode* pSceneRoot, LoadData* pData);
  int     LoadCameras       (MetaFileNode* pSceneRoot, LoadData* pData);
  int     LoadControllers   (MetaFileNode* pSceneRoot, LoadData* pData);
  int     LoadTextures      (MetaFileNode* pSceneRoot, LoadData* pData);
  int     LoadMaterials     (MetaFileNode* pSceneRoot, LoadData* pData);
  int     LoadLights        (MetaFileNode* pSceneRoot, LoadData* pData);
  #endif

  void    AssignController      (int iID, KeyFrameSequence* pKeyFrameSequence, LoadData* pData);
  void    AssignScalarController(int iID, ScalarSequence* pScalarSequence, LoadData* pData);
  int     SaveControllersAssignment(MVFSFILE* f, LoadData* pData);
  int     SaveScalarControllersAssignment(MVFSFILE* f, LoadData* pData);

  

  const char*       GetString          (MetaFileNode* pNode);
  Vector3D*         GetVector3D        (MetaFileNode* pNode, Vector3D* pVector3D);
  Quaternion*       GetQuaternion      (MetaFileNode* pNode, Quaternion* pQuaternion);
  int*              GetInt             (MetaFileNode* pNode, int* pInt);
  float*            GetFloat           (MetaFileNode* pNode, float* pfloat);
  KeyFrameSequence* GetKeyFrameSequence(MetaFileNode* pNode, KeyFrameSequence* pKeyFrameSequence);
  ScalarSequence*   GetScalarSequence  (MetaFileNode* pNode, ScalarSequence* pScalarSequence);
    
  
  enum eObjectType
  {
    E_MESH   ,
    E_LIGHT  ,
    E_CAMERA ,
  };

  
  
public:
  float                               m_fStartTime;
  float                               m_fOffsetTime;  
  float                               m_fSpeed;
                                      
  unsigned                            m_uMeshes;
  D3DMesh*                            m_pMeshes;
                                      
  unsigned                            m_uLights;
  D3DLight*                           m_pLights;
                                      
  unsigned                            m_uCameras;
  MaxCamera*                          m_pCameras;
                                      
  unsigned                            m_uKeyFrames;
  KeyFrameSequence*                   m_pKeyFrames;
                                      
  unsigned                            m_uScalars;
  ScalarSequence*                     m_pScalars;
                                      
  MBStaticList<RenderParticleSystem*> m_ParticleSystems;
  MBStaticList<SM_GeomMorpher*>       m_GeomMorphers;
  MBStaticList<D3DMesh*>              m_Metaballs;
  MBStaticList<SM_DistortBall*>       m_DistortBalls;
  MBStaticList<SM_SpikeTube*>         m_SpikeTubes;
  MBStaticList<SM_FFTBall*>           m_FFTBalls;
  MBStaticList<SM_Twister*>           m_Twisters;

  int                                 m_iCamera;    
};


#endif
