//
// Irrlicht Wrapper for Imperative Languages
// Frank Dodd (2006)
// Matrix wrapper by Michael Taupitz (2006)
//
// This wrapper DLL encapsulates a sub-set of the features of the powerful
// Irrlicht 3D Graphics Engine exposing the Object Oriented architecture and
// providing a functional 3D SDK for languages that are not object oriented.
//
// This source was created with the help of the great examples in the Irrlicht
// SDK and the excellent Irrlicht documentation. This software was developed
// using the GCC compiler and Code::Blocks IDE
//

/* ////////////////////////////////////////////////////////////////////////////
includes
*/
#include "irrlichtwrapper.h"


/* ////////////////////////////////////////////////////////////////////////////
global variables
*/

/* ////////////////////////////////////////////////////////////////////////////
external variables
*/
extern IrrlichtDevice *device;
extern IVideoDriver* driver;
extern ISceneManager* smgr;
extern IGUIEnvironment* guienv;


/* ////////////////////////////////////////////////////////////////////////////
Global Function Declarations

all of the below functions are declared as C functions and are exposed without
any mangled names so that they can be easily imported into imperative
languages like FreeBasic
*/
extern "C"
{

/* ////////////////////////////////////////////////////////////////////////////
MATRIX FUNCTIONS
*/
/* ----------------------------------------------------------------------------
get the Matrix
The Matrix is a 4x4 array of floats !
*/
/**
 * UNDOCUMENTED
IrrMatrixGetTransform( transformstate.l, *resMat.f )
#PBIMPORT:IrrMatrixGetTransform( transformstate.l, *resMat.f )
*/
STATIC_EXPORT void  DLL_EXPORT IrrMatrixGetTransform(  irr::video::E_TRANSFORMATION_STATE transformstate, float* resMat )
{
    matrix4 mat = driver->getTransform(transformstate);
//    memcpy(mat.M, resMat, 16*sizeof(f32));
    for (int ii=0; ii< 16; ii++)
//        resMat[ii] = mat.M[ii];
        resMat[ii] = mat[ii];


}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrMatrixMakeInverse( *inMat.f, *resMat.f )
*/

STATIC_EXPORT void  DLL_EXPORT IrrMatrixMakeInverse( float *inMat, float *resMat )
{
    matrix4 mat;
    for (int ii=0; ii< 16; ii++)
//        mat.M[ii] = inMat[ii];
        mat[ii] = inMat[ii];
//    memcpy(inMat, mat.M, 16*sizeof(f32));
    mat.makeInverse();
    for (int ii=0; ii< 16; ii++)
//        resMat[ii] = mat.M[ii];
        resMat[ii] = mat[ii];
//    memcpy(mat.M, resMat, 16*sizeof(f32));
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrMatrixMakeIdentity( *inMat.f, *resMat.f )
*/
STATIC_EXPORT void  DLL_EXPORT IrrMatrixMakeIdentity( float* inMat, float* resMat )
{
    matrix4 mat;
    for (int ii=0; ii< 16; ii++)
//        mat.M[ii] = inMat[ii];
        mat[ii] = inMat[ii];
//    memcpy(inMat, mat.M, 16*sizeof(f32));
    mat.makeIdentity();
//    memcpy(mat.M, resMat, 16*sizeof(f32));
    for (int ii=0; ii< 16; ii++)
//        resMat[ii] = mat.M[ii];
        resMat[ii] = mat[ii];

}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrMatrixGetTransposed( *inMat.f, *resMat.f )
*/
STATIC_EXPORT void  DLL_EXPORT IrrMatrixGetTransposed( float* inMat, float* resMat )
{
    matrix4 mat;
    for (int ii=0; ii< 16; ii++)
//        mat.M[ii] = inMat[ii];
        mat[ii] = inMat[ii];
//    memcpy(inMat, mat.M, 16*sizeof(f32));
    matrix4 mat2 = mat.getTransposed();
//    memcpy(mat2.M, resMat, 16*sizeof(f32));
    for (int ii=0; ii< 16; ii++)
//        resMat[ii] = mat.M[ii];
        resMat[ii] = mat[ii];
}

//Instead to make all calls through PureBasic....
/**
 * UNDOCUMENTED
#PBIMPORT:IrrMatrixGetWorldView( *resMat.f )
*/
STATIC_EXPORT void  DLL_EXPORT IrrMatrixGetWorldView( float* resMat )
{
    core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);
//    memcpy(worldViewProj.M, resMat, 16*sizeof(f32));

    for (int ii=0; ii< 16; ii++)
//        resMat[ii] = worldViewProj.M[ii];
        resMat[ii] = worldViewProj[ii];

}



/* ////////////////////////////////////////////////////////////////////////////
all of the above functions are declared as C functions and are exposed without
any mangled names
*/
}
