#ifndef __DNMREPOR_H__
#define __DNMREPOR_H__
 
#include "DNMDynSt.h"
#include "DNMMth.h"
#include "DNMObsta.h"
 
#ifdef __cplusplus
extern "C" {
#endif
  
  
#define DNM_C_ReportCollision					0x00000001	
#define DNM_C_ReportWall						0x00000002		/* Set when object collides with a wall */		
#define DNM_C_ReportChar						0x00000004		/* Set when contact with an other character */		
 
 
  
  /* Define the structure DNM_tdstReport */
  typedef struct DNM_stReport
  {
    /* Surface report */
    unsigned long m_ulPrevSurfaceState;
    unsigned long m_ulCurrSurfaceState;
 
    /* Obstacle report */
    DNM_tdstObstacle m_stObstacle;
    DNM_tdstObstacle m_stGround;
    DNM_tdstObstacle m_stWall;
    DNM_tdstObstacle m_stCharacter;
    DNM_tdstObstacle m_stWater;
    DNM_tdstObstacle m_stCeil;
	
    /* Kinetic report (only for camera) */
    MTH_tdstMove m_stAbsolutePrevSpeed;
    MTH_tdstMove m_stAbsoluteCurrSpeed;
    MTH_tdstMove m_stAbsolutePrevPosition;
    MTH_tdstMove m_stAbsoluteCurrPosition;
    
    /* For Camera */ /* <-- only for camera, why ? */
	char m_cBitField;
  } DNM_tdstReport;
 
 
   /* Define the structure DNM_tdstReport */
  typedef struct DNM_stMecReport
  {
    /* Surface report */
    unsigned long m_ulCurrSurfaceState;
 
    /* Obstacle report */
    DNM_tdstMecObstacle m_stObstacle;
    DNM_tdstMecObstacle m_stGround;
    DNM_tdstMecObstacle m_stWall;
    DNM_tdstMecObstacle m_stCharacter;
    DNM_tdstMecObstacle m_stWater;
    DNM_tdstMecObstacle m_stCeil;
  } DNM_tdstMecReport;
 
 
 
 
  /* Methods */
  
  /* Accessors */
#define DNM_M_ulReportGetSurfaceState(_p_stReport) ((_p_stReport)->m_ulCurrSurfaceState)
#define DNM_M_ulReportGetPrevSurfaceState(_p_stReport) ((_p_stReport)->m_ulPrevSurfaceState)
#define DNM_M_p_stReportGetAbsolutePrevSpeed(_p_stReport) (&(_p_stReport)->m_stAbsolutePrevSpeed)
#define DNM_M_p_stReportGetAbsoluteCurrSpeed(_p_stReport) (&(_p_stReport)->m_stAbsoluteCurrSpeed)
#define DNM_M_p_stReportGetAbsolutePrevPosition(_p_stReport) (&(_p_stReport)->m_stAbsolutePrevPosition)
#define DNM_M_p_stReportGetAbsoluteCurrPosition(_p_stReport) (&(_p_stReport)->m_stAbsoluteCurrPosition)
#define DNM_M_p_stReportGetObstacle(_p_stReport) (&(_p_stReport)->m_stObstacle)
#define DNM_M_p_stReportGetGround(_p_stReport) (&(_p_stReport)->m_stGround)
#define DNM_M_p_stReportGetWall(_p_stReport) (&(_p_stReport)->m_stWall)
#define DNM_M_p_stReportGetCharacter(_p_stReport) (&(_p_stReport)->m_stCharacter)
#define DNM_M_p_stReportGetWater(_p_stReport) (&(_p_stReport)->m_stWater)
#define DNM_M_p_stReportGetCeil(_p_stReport) (&(_p_stReport)->m_stCeil)
  
#define DNM_M_ulReportSetSurfaceState(_p_stReport,_ulValue) (DNM_M_ulReportGetSurfaceState(_p_stReport) = _ulValue)
#define DNM_M_ulReportAddSurfaceState(_p_stReport,_ulValue) (DNM_M_ulReportGetSurfaceState(_p_stReport) |= (_ulValue))
#define DNM_M_ulReportSetPrevSurfaceState(_p_stReport,_ulValue) (DNM_M_ulReportGetPrevSurfaceState(_p_stReport) = _ulValue)
#define DNM_M_eReportSetPrevVolumicEnvironment(_p_stReport,_eVolumicEnvironment) (DNM_M_eReportGetPrevVolumicEnvironment(_p_stReport) = _eVolumicEnvironment)
#define DNM_M_eReportSetCurrentVolumicEnvironment(_p_stReport,_eVolumicEnvironment) (DNM_M_eReportGetCurrentVolumicEnvironment(_p_stReport) = _eVolumicEnvironment)
#define DNM_M_ReportSetAbsolutePrevSpeed(_p_stReport,_p_stMove) MTH_M_MoveCopyClone(DNM_M_p_stReportGetAbsolutePrevSpeed(_p_stReport),_p_stMove)
#define DNM_M_ReportSetAbsoluteCurrSpeed(_p_stReport,_p_stMove) MTH_M_MoveCopyClone(DNM_M_p_stReportGetAbsoluteCurrSpeed(_p_stReport),_p_stMove)
#define DNM_M_ReportSetAbsolutePrevPosition(_p_stReport,_p_stMove) MTH_M_MoveCopyClone(DNM_M_p_stReportGetAbsolutePrevPosition(_p_stReport),_p_stMove)
#define DNM_M_ReportSetAbsoluteCurrPosition(_p_stReport,_p_stMove) MTH_M_MoveCopyClone(DNM_M_p_stReportGetAbsoluteCurrPosition(_p_stReport),_p_stMove)
 
#define DNM_M_ReportSetObstacle(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(&(_p_stReport)->m_stObstacle,_p_stObstacle)
#define DNM_M_ReportSetGround(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(&(_p_stReport)->m_stGround,_p_stObstacle)
#define DNM_M_ReportSetWall(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(DNM_M_p_stReportGetWall(_p_stReport),_p_stObstacle)
#define DNM_M_ReportSetCharacter(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(DNM_M_p_stReportGetCharacter(_p_stReport),_p_stObstacle)
#define DNM_M_ReportSetWater(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(DNM_M_p_stReportGetWater(_p_stReport),_p_stObstacle)
#define DNM_M_ReportSetCeil(_p_stReport,_p_stObstacle) DNM_M_ObstacleCopyClone(DNM_M_p_stReportGetCeil(_p_stReport),_p_stObstacle)
 
#define DNM_M_MecReportSetObstacle(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(&(_p_stReport)->m_stObstacle,_p_stObstacle)
#define DNM_M_MecReportSetGround(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(&(_p_stReport)->m_stGround,_p_stObstacle)
#define DNM_M_MecReportSetWall(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(DNM_M_p_stReportGetWall(_p_stReport),_p_stObstacle)
#define DNM_M_MecReportSetCharacter(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(DNM_M_p_stReportGetCharacter(_p_stReport),_p_stObstacle)
#define DNM_M_MecReportSetWater(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(DNM_M_p_stReportGetWater(_p_stReport),_p_stObstacle)
#define DNM_M_MecReportSetCeil(_p_stReport,_p_stObstacle) DNM_M_MecObstacleCopyClone(DNM_M_p_stReportGetCeil(_p_stReport),_p_stObstacle)
 
 
#define DNM_M_bReportIsWall(_p_stReport)					( _p_stReport->m_cBitField & DNM_C_ReportWall ? TRUE : FALSE )
#define DNM_M_bReportSetWallFlagToFalse(_p_stReport)		( _p_stReport->m_cBitField &= ~DNM_C_ReportWall )
#define DNM_M_bReportSetWallFlagToTrue(_p_stReport)			( _p_stReport->m_cBitField |= DNM_C_ReportWall )
 
#define DNM_M_bReportIsChar(_p_stReport)					( _p_stReport->m_cBitField & DNM_C_ReportChar ? TRUE : FALSE )
#define DNM_M_bReportSetCharFlagToFalse(_p_stReport)		( _p_stReport->m_cBitField &= ~DNM_C_ReportChar ) 
#define DNM_M_bReportSetCharFlagToTrue(_p_stReport)			( _p_stReport->m_cBitField |= DNM_C_ReportChar )
  
 
/* 
 * for camera 
 *----------------
 */
#define DNM_M_vReportSetLastMove(__p_stReport, __p_stMove)		MTH_M_MoveSetLinear(&__p_stReport->m_stAbsolutePrevSpeed, __p_stMove)
#define DNM_M_p_stReportGetLastMove(__p_stReport)				(MTH_M_p_stMoveGetLinear(&__p_stReport->m_stAbsolutePrevSpeed))
 
#define DNM_M_vReportSetLastTgtMove(__p_stReport, __p_stMove)	MTH_M_MoveSetLinear(&__p_stReport->m_stAbsolutePrevPosition, __p_stMove)
#define DNM_M_p_stReportGetLastTgtMove(__p_stReport)			(MTH_M_p_stMoveGetLinear(&__p_stReport->m_stAbsolutePrevPosition))
 
#define DNM_M_bReportCollision(_p_stReport)					( _p_stReport->m_cBitField & DNM_C_ReportCollision ? TRUE : FALSE )
#define DNM_M_bReportSetCollisionFlagToFalse(_p_stReport)	( _p_stReport->m_cBitField &= ~DNM_C_ReportCollision )
#define DNM_M_bReportSetCollisionFlagToTrue(_p_stReport)	( _p_stReport->m_cBitField |= DNM_C_ReportCollision )
 
#define DNM_M_bDynamicsIsAnimation(_p_stDynamics) (DNM_M_pstGetBaseBlock(_p_stDynamics)->ulFlags & DNM_C_Animation ? TRUE: FALSE)
 
 
 
/* 
 * end for camera 
 *----------------
 */
 
 
/* Clone */
#define DNM_M_ReportCopyClone(_p_stDst,_p_stSrc) memcpy(_p_stDst,_p_stSrc,sizeof(DNM_tdstReport))
 
/* Copy current state values into previous kinetic values */
/*#define DNM_M_ReportStateTranslate(_p_stReport) {\*/
/*  DNM_M_eReportSetPrevDynamicalState(_p_stReport,DNM_M_eReportGetDynamicalState(_p_stReport));\*/
/*  DNM_M_ulReportSetPrevSurfaceState(_p_stReport,DNM_M_ulReportGetSurfaceState(_p_stReport));\*/
/*}*/
 
#define DNM_M_ReportStateTranslate(_p_stReport)		(DNM_M_ulReportSetPrevSurfaceState(_p_stReport,DNM_M_ulReportGetSurfaceState(_p_stReport)))
 
 
/* Default initialisation */
DNM_tdstReport *DNM_p_stReportDefaultInit(DNM_tdstReport *_p_stReport);
 
extern DNM_tdstMecReport g_stReport;
 
 
#ifdef __cplusplus
}
#endif
 
#endif
