//
// Irrlicht Wrapper for Imperative Languages
// Frank Dodd (2006)
//
// Additional Work
// 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"
#include "CCTTexture.h"

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

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


/* ////////////////////////////////////////////////////////////////////////////
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"
{

/****f* 2D/IrrTextureGetPitch
* NAME
*    IrrTextureGetPitch - Returns pitch of texture in bytes.
* SYNOPSIS
*    pitch.l = IrrTextureGetPitch(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns pitch of texture (in bytes).
*
*   The pitch is the amount of bytes used for a row of pixels in a texture.
*
* RESULT
*    Returns pitch of texture in bytes.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureGetPitch(*Texture)
*/

STATIC_EXPORT int DLL_EXPORT  IrrTextureGetPitch( ITexture *tex)
{
    if (tex)
    {
        return tex->getPitch();
    }
    else
        return -1;
}

/****f* 2D/IrrTextureGetColorFormat
* NAME
*    IrrTextureGetColorFormat - Returns the color format of texture.
* SYNOPSIS
*    colorformat.l = IrrTextureGetColorFormat(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns the color format of texture.
*
* Possible values :
*
*   #IRR_ECF_A1R5G5B5 - 16 bit color format used by the software driver, and thus preferred by all other irrlicht engine video drivers. There are 5 bits for every color component, and a single bit is left for alpha information.
*   #IRR_ECF_R5G6B5 - Standard 16 bit color format.
*   #IRR_ECF_R8G8B8 - 24 bit color, no alpha channel, but 8 bit for red, green and blue.
*   #IRR_ECF_A8R8G8B8 - Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
*
*   If you want to manipulate a Texture, you have to know the 'size' of each Pixel.
*
* RESULT
*   Returns the color format of texture.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureGetColorFormat(*Texture)
*/

STATIC_EXPORT int DLL_EXPORT  IrrTextureGetColorFormat( ITexture *tex)
{
    if (tex)
    {
        return tex->getColorFormat();
    }
    else
        return -1;
}

/****f* 2D/IrrTextureGetDriverType
* NAME
*    IrrTextureGetDriverType - Returns driver type of texture.
* SYNOPSIS
*    drivertype.l = IrrTextureGetDriverType(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns driver type of texture.
*
*   This is the driver, which created the texture. This method is used internally by the
*   video devices, to check, if they may use a texture because textures may be
*   incompatible between different devices.
*
*   See at IrrStart() for the List of possible Drivers.
*
* RESULT
*   Returns driver type of texture.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureGetDriverType(*Texture)
*/

STATIC_EXPORT int DLL_EXPORT  IrrTextureGetDriverType( ITexture *tex)
{
    if (tex)
    {
        return tex->getDriverType();
    }
    else
        return -1;
}

/****f* 2D/IrrTextureGetName
* NAME
*    IrrTextureGetName - Returns name of texture.
* SYNOPSIS
*    *name = IrrTextureGetName(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns name of texture.
*
* RESULT
*   Returns name of texture.
*
* NOTES
*   You have to use PeekS() to get the name from the Pointer !
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureGetName(*Texture)
*/

STATIC_EXPORT const char* DLL_EXPORT  IrrTextureGetName( ITexture *tex)
{
    if (tex)
    {
        return tex->getName().c_str();
    }
    else
        return NULL;
}


/****f* 2D/IrrTextureOriginalWidth
* NAME
*    IrrTextureOriginalWidth - Returns original width of the Texture.
* SYNOPSIS
*    width.l = IrrTextureOriginalWidth(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns original width of the Texture
*
* RESULT
*   Returns original width of the Texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureOriginalWidth(*Texture)
*/

STATIC_EXPORT s32 DLL_EXPORT  IrrTextureOriginalWidth( ITexture *tex)
{
    if (tex)
    {
        dimension2d<s32> dim = tex->getOriginalSize();
        return dim.Width;
    }
    else
        return -1;
}

/****f* 2D/IrrTextureOriginalHeight
* NAME
*    IrrTextureOriginalHeight - Returns original height of the Texture.
* SYNOPSIS
*    height.l = IrrTextureOriginalHeight(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns original height of the Texture
*
* RESULT
*   Returns original height of the Texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureOriginalHeight(*Texture)
*/

STATIC_EXPORT s32 DLL_EXPORT  IrrTextureOriginalHeight( ITexture *tex)
{
    if (tex)
    {
        dimension2d<s32> dim = tex->getOriginalSize();
        return dim.Height;
    }
    else
        return -1;
}

/****f* 2D/IrrTextureWidth
* NAME
*    IrrTextureWidth - Returns width of the Texture.
* SYNOPSIS
*    width.l = IrrTextureWidth(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns width of the Texture
*
* RESULT
*   Returns width of the Texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureWidth(*Texture)
*/

STATIC_EXPORT s32 DLL_EXPORT  IrrTextureWidth( ITexture *tex)
{
    if (tex)
    {
        dimension2d<s32> dim = tex->getSize();
        return dim.Width;
    }
    else
        return -1;
}

/****f* 2D/IrrTextureHeight
* NAME
*    IrrTextureHeight - Returns height of the Texture.
* SYNOPSIS
*    height.l = IrrTextureHeight(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns height of the Texture
*
* RESULT
*   Returns height of the Texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureHeight(*Texture)
*/

STATIC_EXPORT s32 DLL_EXPORT  IrrTextureHeight( ITexture *tex)
{
    if (tex)
    {
        dimension2d<s32> dim = tex->getSize();
        return dim.Height;
    }
    else
        return -1;
}
/*
STATIC_EXPORT void* DLL_EXPORT  IrrTextureTransformation( ITexture *tex)
{
    if (tex)
    {
        return tex->getTransformation();
    }
    else
        return NULL;
}
*/

/****f* 2D/IrrTextureHasMipMaps
* NAME
*    IrrTextureHasMipMaps - Returns whether the texture has MipMaps.
* SYNOPSIS
*    hasMipMaps.l = IrrTextureHasMipMaps(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Returns whether the texture has MipMaps.
*
* RESULT
*   Returns #True if texture has MipMaps, else #False.
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureHasMipMaps(*Texture)
*/
STATIC_EXPORT bool DLL_EXPORT  IrrTextureHasMipMaps( ITexture *tex)
{
    if (tex)
    {
        return tex->hasMipMaps();
    }
    else
        return false;
}

/****f* 2D/IrrTextureRegenerateMipMaps
* NAME
*    IrrTextureRegenerateMipMaps - Regenerates the mip map levels of the texture.
* SYNOPSIS
*   IrrTextureRegenerateMipMaps(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Regenerates the mip map levels of the texture.
*   Useful after locking and modifying the texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureRegenerateMipMaps(*Texture)
*/
STATIC_EXPORT void DLL_EXPORT  IrrTextureRegenerateMipMaps( ITexture *tex)
{
    if (tex)
    {
        tex->regenerateMipMapLevels();
    }
}


/****f* 2D/IrrTextureLock
* NAME
*    IrrTextureLock - Lock function.
* SYNOPSIS
*   IrrTextureLock(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Lock function.
*   Locks the Texture and returns a pointer to access the pixels. After IrrTextureLock() has been
*   called and all operations on the pixels are done, you must call IrrTextureUnlock().
*
*   Returns a pointer to the pixel data. The format of the pixel can be determinated by using
*   IrrTextureGetColorFormat(). #Null is returned, if the texture cannot be locked.
*
* RESULT
*   A Pointer to the Texture-Data if success, otherwise #Null
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureLock(*Texture)
*/

STATIC_EXPORT void* DLL_EXPORT  IrrTextureLock( ITexture *tex)
{
    if (tex)
    {
        return tex->lock();
    }
    else
        return NULL;
}


/****f* 2D/IrrTextureUnlock
* NAME
*    IrrTextureUnlock - Unlock function.
* SYNOPSIS
*   IrrTextureUnlock(*Texture)
* INPUTS
*   *Texture            - A Pointer to a Texture
* FUNCTION
*   Unlock function.
*   Must be called after a IrrTextureLock() to the texture
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrTextureUnlock(*Texture)
*/
STATIC_EXPORT void DLL_EXPORT  IrrTextureUnlock( ITexture *tex)
{
    if (tex)
    {
        tex->unlock();
    }
}


/****f* 2D/IrrLoadCellTabledTexture
* NAME
*    IrrLoadCellTabledTexture - Load a Cell-Tabled Texture
* SYNOPSIS
*   *celltabledmanager = IrrLoadCellTabledTexture(filename.s, horiCellRes.l, vertCellRes.l, tableWidth.l, tableHeight.l)
* INPUTS
*   filename.s - filename of the texture to load
*   horiCellRes.l - Width of a Cell
*   vertCellRes.l - Height of a Cell
*   tableWidth.l  - how many celly in a row
*   tableHeight.l - how many rows
*
* FUNCTION
*   Load a Cell-Tabled Texture. Use IrrGetCellTabledTexture() to get
*   a specific Texture from it.
*   Plese note  - this function returns a pointer to the 'Manager' of the
*   CellTabledTextur, and not a  pointer to a Texture !!!
*
* RESULT
*   pointer to a manager of the CellTabledTexture if success, otherwise
*   #Null.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrLoadCellTabledTexture(filename.p-ascii, horiCellRes.l=512, vertCellRes.l=512, tableWidth.l=2, tableHeight.l=2)
*/
STATIC_EXPORT void * DLL_EXPORT  IrrLoadCellTabledTexture( const c8* filename, u32 horiCellRes=512, u32 vertCellRes=512, u32 tableWidth=2, u32 tableHeight=2)
{

    IImage* img = driver->createImageFromFile(filename);
    if (img)
    {
        CCTTexture* cctt = new CCTTexture(driver, img, horiCellRes, vertCellRes, tableWidth, tableHeight);
        if (cctt)
            return cctt;
        else

            if (logger)
                logger->log("could not use cell tabled texture with ",filename ,ELL_ERROR);
    }
    else
    {
        if (logger)
            logger->log("could not load image",filename ,ELL_ERROR);
    }
    return NULL;


}

/****f* 2D/IrrGetCellTabledTexture
* NAME
*    IrrGetCellTabledTexture - Get a Texture from a Cell-Tabled Texture
* SYNOPSIS
*   *texture = IrrGetCellTabledTexture(*celltabledmanager, iX.l, iY.l)
* INPUTS
*   **celltabledmanager - pointer to a CellTableManager (created prior with IrrLoadCellTabledTexture())
*   iX.l    - X-Pos of the wanted Cell
*   iY.l    - Y-Pos of the wanted Cell
*
* FUNCTION
*   Get a Texture from a CellTabledTexture.
* RESULT
*   pointer to a texture if success, otherwise
*   #Null.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetCellTabledTexture(*celltabledmanager, iX.l, iY.l)
*/

STATIC_EXPORT void * DLL_EXPORT  IrrGetCellTabledTexture(CCTTexture* cctt , int iX, int iY)
{
    if (cctt)
        return (void*)cctt->getCell(iX,iY);
    return NULL;

}

/****f* 2D/IrrRemoveCellTabledTexture
* NAME
*    IrrRemoveCellTabledTexture - Removes a Cell-Tabled Texture
* SYNOPSIS
*   *texture = IrrRemoveCellTabledTexture(*celltabledmanager)
* INPUTS
*   **celltabledmanager - pointer to a CellTableManager (created prior with IrrLoadCellTabledTexture())
* FUNCTION
*  Removes / deletes a CellTabledTexture.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrRemoveCellTabledTexture(*celltabledmanager)
*/
STATIC_EXPORT void DLL_EXPORT  IrrRemoveCellTabledTexture(CCTTexture* cctt )
{
    if (cctt)
        delete cctt;

}




}
