
//
// Irrlicht Wrapper for Imperative Languages
// Frank Dodd (2006) / Michael Taupitz
//
// 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 "CFadeMaterial .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"
{

/* ////////////////////////////////////////////////////////////////////////////
MATERIAL FUNCTIONS
*/

/* ----------------------------------------------------------------------------
Stt Lightning

*/
/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialLighting( *ptr2IrrlichtMaterial.l, bool.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialLighting( SMaterial* mat, bool lighting )
{
    if (mat)
        mat->Lighting = lighting;
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialLighting( *ptr2IrrlichtMaterial.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrGetMaterialLighting( SMaterial* mat )
{
    if (mat)
        return mat->Lighting;
    return false;

}

/* ----------------------------------------------------------------------------
Stt Lightning

*/
/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialTexture( *ptr2IrrlichtMaterial.l, id.l, *ptr2IrrlichtTexture.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialTexture( SMaterial* mat, int id, ITexture* tex )
{
    if (mat && id < irr::video::MATERIAL_MAX_TEXTURES)
        mat->TextureLayer[id].Texture = tex;
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialTexture( *ptr2IrrlichtMaterial.l, id.l )
*/
STATIC_EXPORT void* DLL_EXPORT IrrGetMaterialTexture( SMaterial* mat, u32 id )
{
    if (mat && id < irr::video::MATERIAL_MAX_TEXTURES)
        return (void*)mat->TextureLayer[id].Texture;
    return NULL;
}


/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialParam( *ptr2IrrlichtMaterial.l, paramter1.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialParam( SMaterial* mat, float fparam )
{
    if (mat)
        mat->MaterialTypeParam = fparam;
}

/**
 * UNDOCUMENTED    if (mat)

#PBIMPORT:IrrGetMaterialParam( *ptr2IrrlichtMaterial.l, paramter1.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialParam( SMaterial* mat, float& fparam )
{
    if (mat)
        fparam= mat->MaterialTypeParam;
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialParam2( *ptr2IrrlichtMaterial.l, paramter2.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialParam2( SMaterial* mat, float fparam )
{
    if (mat)
        mat->MaterialTypeParam2 = fparam;
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialParam2( *ptr2IrrlichtMaterial.l, *paramter2.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialParam2( SMaterial* mat, float& fparam )
{
    if (mat)
        fparam = mat->MaterialTypeParam2;
}


/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialDiffuseColor( *ptr2IrrlichtMaterial.l, alpha.l, red.l, green.l, blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialDiffuseColor( SMaterial* mat, s32 alpha, s32 red, s32 green, s32 blue )
{
    if (mat)
        mat->DiffuseColor=SColor(alpha,red,green,blue);
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialDiffuseColor( *ptr2IrrlichtMaterial.l, *alpha.l, *red.l, *green.l, *blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialDiffuseColor( SMaterial* mat, u32& alpha, u32& red, u32& green, u32& blue )
{
    if (mat)
    {
        alpha = mat->DiffuseColor.getAlpha();
        red = mat->DiffuseColor.getRed();
        green = mat->DiffuseColor.getGreen();
        blue = mat->DiffuseColor.getBlue();
    }
}


/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialSpecularColor( *ptr2IrrlichtMaterial.l, alpha.l, red.l, green.l, blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialSpecularColor( SMaterial* mat, s32 alpha, s32 red, s32 green, s32 blue )
{
    if (mat)
        mat->SpecularColor=SColor(alpha,red,green,blue);
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialSpecularColor( *ptr2IrrlichtMaterial.l, *alpha.l, *red.l, *green.l, *blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialSpecularColor( SMaterial* mat, u32& alpha, u32& red, u32& green, u32& blue )
{
    if (mat)
    {
        alpha = mat->SpecularColor.getAlpha();
        red = mat->SpecularColor.getRed();
        green = mat->SpecularColor.getGreen();
        blue = mat->SpecularColor.getBlue();
    }
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialAmbientColor( *ptr2IrrlichtMaterial.l, alpha.l, red.l, green.l, blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialAmbientColor( SMaterial* mat, s32 alpha, s32 red, s32 green, s32 blue )
{
    if (mat)
        mat->AmbientColor=SColor(alpha,red,green,blue);
}
/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialAmbientColor( *ptr2IrrlichtMaterial.l, *alpha.l, *red.l, *green.l, *blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialAmbientColor( SMaterial* mat, u32& alpha, u32& red, u32& green, u32& blue )
{
    if (mat)
    {
        alpha = mat->AmbientColor.getAlpha();
        red = mat->AmbientColor.getRed();
        green = mat->AmbientColor.getGreen();
        blue = mat->AmbientColor.getBlue();
    }
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialEmissiveColor( *ptr2IrrlichtMaterial.l, alpha.l, red.l, green.l, blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialEmissiveColor( SMaterial* mat, s32 alpha, s32 red, s32 green, s32 blue )
{
    if (mat)
        mat->EmissiveColor=SColor(alpha,red,green,blue);
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialEmissiveColor( *ptr2IrrlichtMaterial.l, *alpha.l, *red.l, *green.l, *blue.l )
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialEmissiveColor( SMaterial* mat, u32& alpha, u32& red, u32& green, u32& blue )
{
    if (mat)
    {
        alpha = mat->EmissiveColor.getAlpha();
        red = mat->EmissiveColor.getRed();
        green = mat->EmissiveColor.getGreen();
        blue = mat->EmissiveColor.getBlue();
    }
}





/* Here are the experimental Material... */
STATIC_EXPORT void * DLL_EXPORT IrrSetFadeMaterialToNode( ISceneNode* node, f32 factor)
{
	if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
		!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
	{
		device->getLogger()->log("WARNING: (FadeMesh) Pixel shaders disabled "\
			"because of missing driver/hardware support.");
		return NULL;
	}

	if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
		!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
	{
		device->getLogger()->log("WARNING: (FadeMesh)  Vertex shaders disabled "\
			"because of missing driver/hardware support.");
		return NULL;
	}


    CFadeMaterial* fadeMaterial = new CFadeMaterial();
    if (fadeMaterial)
    {
        fadeMaterial->init(smgr, driver);
        node->setMaterialType((video::E_MATERIAL_TYPE)fadeMaterial->getFadeMaterial());
        fadeMaterial->setFadeFactor(factor);

        return (void*)fadeMaterial;
    }
    return NULL;
}

STATIC_EXPORT void DLL_EXPORT IrrSetFadeMaterialFactor( CFadeMaterial* fadeMaterial, f32 factor)
{
    if (fadeMaterial)
    {
        fadeMaterial->setFadeFactor(factor);
    } else { printf("Problem in IrrSetFadeMaterialFactor\n"); }
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrSetMaterialThickness( *ptr2IrrlichtMaterial.l, Thickness.f )
*/
STATIC_EXPORT void DLL_EXPORT IrrSetMaterialThickness( SMaterial* mat, f32 Thickness )
{
    if (mat)
        mat->Thickness = Thickness;
}

/**
 * UNDOCUMENTED
#PBIMPORT:IrrGetMaterialThickness( *ptr2IrrlichtMaterial.l, *Thickness.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetMaterialThickness( SMaterial* mat, f32& Thickness )
{
    if (mat)
        Thickness = mat->Thickness;

}


/**
 * UNDOCUMENTED
#PBIMPORT:IrrPackBlend( srcFact.l, dstFact.l, modulate.l, *result.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrPackBlend( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate, f32& factor )
{
    factor = pack_texureBlendFunc(srcFact, dstFact, modulate);

}

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