#ifndef __SM_DEMOSCRIPT

#define __SM_DEMOSCRIPT

#include "SM_DemoEffect.h"
#include "SM_DemoTune.h"
#include "SM_Main.h"


/*
  FORMATO SCRIPT

  // Comentario
  [  Abre comentario
  ]  Cierra comentario 


Sincronizacion:

Comandos de efectos:

  FXSTART     nombrefx
  FXSTOP      nombrefx
  FXLOAD      nombrefx
  FXSHUT      nombrefx
  FXCOMMAND   nombrefx parametros hasta final de linea

Sistema:
  VIDEOSTART	xres yres bpp fullscreen	(fullscreen=1 si pantalla completa)
  VIDEOEND 	chapa video
  
  CLEARON                      ...en cada frame borra la pantalla
  CLEAROFF                     ...no borra la pantalla (por defecto apagado)
  

  SYNC 	    	pos row                  	...Espera a que musica este en pos row

  LOADMUSIC 	nombremusica       
  PLAYMUSIC 
  STOPMUSIC 
  FREEMUSIC 

  LOADMP3     nombreMP3
  PLAYMP3     
  STOPMP3     
  FREEMP3
  SKIPTOTIME  time
  SYNCTIME    time
*/


namespace SM_DemoScript
{
  int                 Init                (char* pcScript, bool bLooped, bool bIgnoreLoads = false);
  int                 Shutdown            ();
  int                 Reset               ();
                                          
  int                 RunPreStartFrame    (int iStartLayer, int iEndLayer);
  int                 RunPreRender        (int iStartLayer, int iEndLayer);
  int                 Run                 (int iStartLayer, int iEndLayer);  // 1: OK ; 0: He acabado ; -1: ERROR  
  int                 RunPostRender       (int iStartLayer, int iEndLayer);
  int                 RunPostEndFrame     (int iStartLayer, int iEndLayer);
                                          
  int                 RunCommands         ();

  void                SetRunToMode        (bool bRunToMode);
  void                SetSound            (bool bSound);
  void                SetTime             (float fTime);
  float               GetTime             ();
                                          
  void                InsertActiveFXList  (SM_DemoEffect*     pEffect);


  SM_DemoEffect*      GetFirstEffect      ();
  SM_DemoEffect*      GetNextEffect       ();
  SM_DemoEffect*      GetFirstActiveEffect();
  SM_DemoEffect*      GetNextActiveEffect ();

  
  enum
  {
    E_MIN_LAYER   = 0,
    E_FILTER_LAYER= 8,
    E_MAX_LAYER   = 15,
  };

  struct TCommand
  {
  public:
    enum eCommand
    {
      CM_ERROR,
      CM_FX_START,
      CM_FX_STOP,
      CM_FX_LOAD,
      CM_FX_SHUT,
      CM_FX_COMMAND,
      CM_FX_LAYER,
      CM_SYS_SYNC,
      CM_SYS_VIDEOSTART,
      CM_SYS_VIDEOEND,
        
      // Music
      CM_SYS_LOADMP3,
      CM_SYS_LOADTRACK,
      CM_SYS_FREEMUSIC,
      CM_SYS_PLAYMUSIC,
      CM_SYS_STOPMUSIC,
      CM_SYS_SKIPTO,
      CM_SYS_SKIPTOTIME,
      CM_SYS_SYNCTIME,
    

      CM_SYS_CLEARON,
      CM_SYS_CLEAROFF,
      CM_SYS_MEMBACKBUFFER,
      CM_SYS_VIDEOBACKBUFFER, 
      CM_SYS_DUMP,
      CM_SYS_WAIT,
    };
                    TCommand        ();
                    ~TCommand       ();
                    
    int             Init            ();
    int             Shutdown        ();
                    
    void            SetCommand      (eCommand  Command);
    eCommand        GetCommand      ();
                    
    void            SetFx           (SM_DemoEffect*  pEffect);
    SM_DemoEffect*  GetFx           ();
    const char*     GetFxName       ();

    void            SetTune         (SM_DemoTune*  pEffect);
    const char*     GetTuneName     ();

    void            SetArgs         (const char*  pcArgs);
    char*           GetArgs         ();
                    
    void            SetPosRow       (int iPos , int iRow);
    void            GetPosRow       (int& iPos, int& iRow);
                    
    void            SetVideo        (unsigned uResX, unsigned uResY, unsigned uBPP, bool bFullscreen);
    void            GetVideo        (unsigned& uResX, unsigned& uResY, unsigned& uBPP, bool& bFullscreen);
                    
    void            SetTime         (float fTime);
    float           GetTime         ();
                    
    void            SetLoop         (bool bLoop);
    bool            GetLoop         ();

    TCommand*       Clone           ();

    int             ToString        (char* pcString, unsigned uLen);
                    
  protected:
    eCommand        m_Command;
    SM_DemoEffect*  m_pEffect; 
    SM_DemoTune*    m_pTune;
    char*           m_pcArgs;
    int             m_iRow, m_iPos;    
    unsigned        m_uResX, m_uResY, m_uBPP;
    bool            m_bFullscreen;
    bool            m_bLoop;
    float           m_fTime;
  };  

  struct TCommandNode
  {
	  TCommand*     pCommand;
	  TCommandNode* pNext;
  };

  void                SetCommandList      (TCommandNode* pCommandList);
  TCommandNode*       GetCommandList      ();
  
  void                InsertCommandList   (TCommand*     pCommand);
  void                ShutdownCommandList ();  
};

#endif