/***************************************************************************
 *                                                                         *
 * Module  : rtimport.h                                                    *
 *                                                                         *
 * Purpose : World handling functions.                                     *
 *                                                                         *
 **************************************************************************/

#ifndef RTIMPORT_H
#define RTIMPORT_H

/**
 * \defgroup rtimport RtWorldImport
 * \ingroup rttool
 *
 * World Import Toolkit for Renderware.
 */

/****************************************************************************
 Includes
 */

#include "rwcore.h"
#include "rpworld.h"

#include "rtimport.rpe"        /* automatically generated header file */

/****************************************************************************
 Defines
 */

/* Progress callback message types */
#define rtWORLDIMPORTPROGRESSBSPBUILDSTART      0
#define rtWORLDIMPORTPROGRESSBSPBUILDUPDATE     1
#define rtWORLDIMPORTPROGRESSBSPBUILDEND        2
#define rtWORLDIMPORTPROGRESSBSPCOMPRESSSTART   3
#define rtWORLDIMPORTPROGRESSBSPCOMPRESSUPDATE  4
#define rtWORLDIMPORTPROGRESSBSPCOMPRESSEND     5

/****************************************************************************
 Global types
 */

/**
 * \inImportGroup rtimport
 * \see RtWorldImportVertexState
 */
typedef union RtWorldImportVertexState RtWorldImportVertexState;


/**
 * \inImportGroup rtimport
 * \see RtWorldImportVertex
 */
typedef struct RtWorldImportVertex RtWorldImportVertex;

typedef struct RtWorldImportWeldVertex RtWorldImportWeldVertex;

typedef struct RtWorldImportBuildVertex RtWorldImportBuildVertex;


/**
 * \inImportGroup rtimport
 * \union RtWorldImportVertexState
 * Internal use only
 */
union RtWorldImportVertexState
{
    RwInt32                    clipFlags;          /**< Internal use only */
    RwInt32                    forwardingAddress;  /**< Internal use only */
    RtWorldImportVertex       *vpVert;             /**< Internal use only */
    RtWorldImportWeldVertex   *vpWeldVert;         /**< Internal use only */
    RtWorldImportBuildVertex  *vpBuildVert;        /**< Internal use only */
    RwSList                   *slist;              /**< Internal use only */
};

/**
 * \inImportGroup rtimport
 * \struct RtWorldImportVertex
 * Holds data for each vertex in the import world.
 *
 * \see RtWorldImportVertex
 */
struct RtWorldImportVertex
{
    RwV3d           OC;         /**< World space vertex position */
    RwV3d           normal;     /**< World space vertex normal */
    RwRGBA          preLitCol;  /**< Vertex Pre-light color */
    RwTexCoords     texCoords[rwMAXTEXTURECOORDS];  
                                /**< Vertex texture coordinates */
    RtWorldImportVertexState state;  /**< Internal use only */
    RwInt32         matIndex;   /**< Vertex material index */
    void           *pUserdata;  /**< Pointer to unspecified per vertex user data */
};

/**
 * \inImportGroup rtimport
 * Holds data for each triangle in the import world.
 * \see RtWorldImportTriangle
 */
typedef struct RtWorldImportTriangle RtWorldImportTriangle;
/**
 * \inImportGroup rtimport
 * \struct RtWorldImportTriangle
 * Holds data for each triangle in the import world.
 * \see RtWorldImportTriangle
 */
struct RtWorldImportTriangle
{
    RwInt32             matIndex;       /**< Index into material list */
    RwInt32             vertIndex[3];   /**< Indices into vertex list */
    void               *pUserdata;      /**< Pointer to unspecified per triangle user data */
};

/**
 * \inImportGroup rtimport
 * \see RtWorldImportParameters
 */
typedef struct RtWorldImportParameters RtWorldImportParameters;

/**
 * \inImportGroup rtimport
 * \struct RtWorldImportParameters
 * Parameters used with \ref RtWorldImportCreateWorld.
 * They are initialized to default values using \ref RtWorldImportParametersInitialize.
 * \see RtWorldImportParameters
 */
struct RtWorldImportParameters
{
    /**The size of an atomic sector must be less than this value down
     *  each axis. */
    RwReal              worldSectorMaxSize;
    /** The maximum number of polygons in a world sector. */
    RwInt32             maxWorldSectorPolygons;
    /** The maximum number of polygons to check near a plane. */
    RwInt32             maxClosestCheck;
    /** Threshold for welding vertices. */
    RwReal              weldThreshold;
    /** Angular threshold for welding vertex normals */
    RwReal              angularThreshold;
    /** If TRUE then empty space is filled by an empty sector. */
    RwBool              spaceFillingSectors;
    /** If TRUE then importer creates normals. */
    RwBool              calcNormals;
    /** Total fraction of world sector overlap allowed. */
    RwReal              maxOverlapPercent;
    /** If TRUE don't allow alpha polygons in overlap. */
    RwBool              noAlphaInOverlap;
    /** If TRUE perform vertex welding and degenerate triangle removal.*/
    RwBool              conditionGeometry;
    /** If TRUE allows user to specify minimum bounding-box for the
     *  world using the userBBox parameter. */
    RwBool              userSpecifiedBBox;
    /** User specified world bounding-box if userSpecifiedBBox is TRUE.*/
    RwBBox              userBBox;
    /** If conditionGeometry is TRUE limit texture coordinates to this
     *  value. */
    RwReal              uvLimit;
    /** If TRUE then duplicate vertices with differing normals will not
     *  be merged. */
    RwBool              retainCreases;
    /** If TRUE then T-junctions are fixed in the geometry (slow). */
    RwBool              fixTJunctions;
    /**  OBSOLETE. This flag has no effect. Use
     *  \ref RpCollisionWorldBuildData to generate collision data. */
    RwBool              generateCollTrees;
    /** If TRUE then polygons are welded where possible to reduce the
     *  polygon count. */
    RwBool              weldPolygons;
    /** Conversion flags (see \ref RpWorldFlag). */
    RwInt32             flags;
    /** If rwTEXTUREADDRESSWRAP than weld vertices according to
     * mod(1) congruent texture coordinates */
    RwTextureAddressMode mode;
    /** If TRUE then polygons are sorted by their centroid */
    RwBool              sortPolygons;
    /** If TRUE then zero-area polygons are culled  */
    RwBool              cullZeroAreaPolygons;    
    /** The number of texture coordinate sets to use. If set to zero, then
     * the number is taken from the flags parameter which, for backward
     * compatibility, can include the rpWORLDTEXTURED or rpWORLDTEXTURED2
     * flags. These specify one or two sets respectively. */
    RwInt32             numTexCoordSets;
};

typedef struct RtWorldImport RtWorldImport;
/**
 * \inImportGroup rtimport
 * \struct RtWorldImport
 * World Import State Structure
 */
struct RtWorldImport
{
    RpMaterialList      matList;     /**< Material list */
    RtWorldImportVertex *vertices;   /**< Vertex array */
    RwInt32             numVertices; /**< Vertex count */

    RtWorldImportTriangle *polygons; /**< Triangle array */
    RwInt32             numPolygons; /**< Triangle count */

    
    RwSurfaceProperties surfaceProps; /**< The worlds surface 
                                           lighting properties */
};

/**
 * \inImportGroup rtimport
 * \ref RtWorldImportProgressCallBack is the type for the callback function supplied to
 * \ref RtWorldImportSetProgressCallBack.
 *
 * \param  msg   Message type corresponding to one of:-
 *      \li rtWORLDIMPORTPROGRESSBSPBUILDSTART -
 *          The BSP creation process is about to start.
 *          The argument value is equal to 0.0.
 *      \li rtWORLDIMPORTPROGRESSBSPBUILDUPDATE -
 *          The BSP creation process has finished processing a subsection of
 *          the world. The argument value is equal to the percentage of the
 *          world processed up to this point.
 *      \li rtWORLDIMPORTPROGRESSBSPBUILDEND -
 *          The BSP creation process has ended.
 *          The argument value is equal to 100.0.
 *      \li rtWORLDIMPORTPROGRESSBSPCOMPRESSSTART -
 *          The BSP compression process is about to start. The argument value
 *          is equal to 0.0.
 *      \li rtWORLDIMPORTPROGRESSBSPCOMPRESSUPDATE -
 *          The BSP compression has finished processing a subsection of the
 *          world. The argument value is equal to the percentage of the world
 *          processed up to this point.
 *      \li rtWORLDIMPORTPROGRESSBSPCOMPRESSEND -
 *          The BSP compression process has ended. The argument value is equal
 *          to 100.0.
 *
 * \param  value   The percentage of the progress made in either BSP
 *          building or BSP compression.
 *
 * \return TRUE to continue BSP processing, FALSE to abort.
 *
 * \see RtWorldImportSetProgressCallBack
 */
typedef RwBool (*RtWorldImportProgressCallBack)(RwInt32 msg, RwReal value);

typedef RwBool (*RtWorldImportDestroyVertexUserdataCallBack)(void **pUserdata);
typedef RwBool (*RtWorldImportCloneVertexUserdataCallBack)(void **pUserdataDst, void **pUserdataSrc);
typedef RwBool (*RtWorldImportInterpVertexUserdataCallBack)(void **pUserdataDst, void **pUserdata1, void **pUserdata2, RwReal delta);
typedef RwBool (*RtWorldImportDestroyPolygonUserdataCallBack)(void **pUserdata);
typedef RwBool (*RtWorldImportSplitPolygonUserdataCallBack)(void **pUserdataDst, void **pUserdataSrc);
typedef RwBool (*RtWorldImportSectorSetVertexUserdataCallBack)(void **pUserdata, RpWorldSector *sector, RwInt32 index);
typedef RwBool (*RtWorldImportSectorSetPolygonUserdataCallBack)(void **pUserdata, RpWorldSector *sector, RwInt32 index);


typedef struct RtWorldImportUserdataCallBacks RtWorldImportUserdataCallBacks;
/**
 * \inImportGroup rtimport
 * \struct RtWorldImportUserdataCallBacks
 * Bundle of callbacks
 */
struct RtWorldImportUserdataCallBacks
{
    RtWorldImportDestroyVertexUserdataCallBack destroyVertexUserdata;
        /**< Callback on vertex destruction */
    RtWorldImportCloneVertexUserdataCallBack cloneVertexUserdata;
        /**< Callback on vertex cloning */
    RtWorldImportInterpVertexUserdataCallBack interpVertexUserdata;
        /**< Callback on vertex interpolation */
    RtWorldImportDestroyPolygonUserdataCallBack destroyPolygonUserdata;
        /**< Callback on polygon destruction */
    RtWorldImportSplitPolygonUserdataCallBack splitPolygonUserdata;
        /**< Callback on polygon division */
    RtWorldImportSectorSetVertexUserdataCallBack sectorSetVertexUserdata;
        /**< Callback on setting vertex user data */
    RtWorldImportSectorSetPolygonUserdataCallBack sectorSetPolygonUserdata;
        /**< Callback on setting polygon user data */
};


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif /* __cplusplus */

/* Initializing the conversion structure */
extern RtWorldImportParameters *
RtWorldImportParametersInitialize(RtWorldImportParameters *
                                  conversionParams);

extern RpWorld *RtWorldImportCreateWorld(RtWorldImport *
                                         nohsworld,
                                         RtWorldImportParameters
                                         * conversionParams);

extern RpGeometry *RtWorldImportCreateGeometry(RtWorldImport *
                                               nohsworld,
                                               RtWorldImportParameters
                                               * conversionParams);

extern RtWorldImport *RtWorldImportCreate(void);

extern RwBool RtWorldImportDestroy(RtWorldImport * nohsworld);

extern RtWorldImport *RtWorldImportAddNumVertices(RtWorldImport *
                                                  nohsworld,
                                                  RwInt32
                                                  numNewVertices);

extern RtWorldImport *RtWorldImportAddNumTriangles(RtWorldImport *
                                                   nohsworld,
                                                   RwInt32
                                                   numNewTriangles);

extern RpMaterial *RtWorldImportGetMaterial(RtWorldImport *
                                            nohsworld,
                                            RwInt32 matInd);

extern RwInt32 RtWorldImportGetNumVertices(RtWorldImport * nohsworld);

extern RtWorldImportVertex *RtWorldImportGetVertices(RtWorldImport *
                                                     nohsworld);

extern RwInt32 RtWorldImportGetNumTriangles(RtWorldImport * nohsworld);

extern RtWorldImportTriangle *
RtWorldImportGetTriangles(RtWorldImport * nohsworld);

/* Surface lighting characteristics */
extern RtWorldImport *
RtWorldImportSetSurfaceProperties(RtWorldImport * world,
                                  RwSurfaceProperties *
                                  surface);

extern RwSurfaceProperties *
RtWorldImportGetSurfaceProperties(RtWorldImport * world);

/* Progress callbacks */
extern void
RtWorldImportSetProgressCallBack(RtWorldImportProgressCallBack CB);

extern void
_rtImportWorldSendProgressMessage(RwInt32 msgtype, RwReal value);

/* Reading and Writing */

extern RtWorldImport *RtWorldImportWrite(RtWorldImport * world,
                                         RwChar * filename);

extern RtWorldImport *RtWorldImportRead(RwChar * filename);

extern RwInt32 RtWorldImportAddMaterial(RtWorldImport * nohsworld,
                                        RpMaterial * material);

extern RwInt32 RtWorldImportGetMaterialIndex(RtWorldImport * nohsworld,
                                             RpMaterial * material);

extern RtWorldImport *RtWorldImportForAllMaterials(RtWorldImport *
                                                   nohsworld,
                                                   RpMaterialCallBack
                                                   fpCallBack,
                                                   void *pData);

extern void
RtWorldImportSetUserdataCallBacks(RtWorldImportDestroyVertexUserdataCallBack
                                    destroyVertexUserdataCB,
                                  RtWorldImportCloneVertexUserdataCallBack
                                    cloneVertexUserdataCB,
                                  RtWorldImportInterpVertexUserdataCallBack
                                    interpVertexUserdataCB,
                                  RtWorldImportSectorSetVertexUserdataCallBack
                                    sectorSetVertexUserdata,
                                  RtWorldImportDestroyPolygonUserdataCallBack
                                    destroyPolygonUserdataCB,
                                  RtWorldImportSplitPolygonUserdataCallBack
                                    splitPolygonUserdataCB,
                                  RtWorldImportSectorSetPolygonUserdataCallBack
                                    sectorSetPolygonUserdata);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#endif                          /* RTIMPORT_H */

