//********************************************************************
// This source file is part of Ninfa3D Engine
// 
// Copyright (C) 2008-2009 Viz_fuerte.
// All rights reserved.
// 
// LIMITED WARRANTY
// This software is provided "as-is", without any express or implied warranty.
// In no event shall the author be held liable for any damages arising from the use of this software.
// This is a contract. By accepting the Ninfa3D Engine (the SOFTWARE), 
// you (either an individual or a single entity, the LICENSEE) accept the terms and conditions of this licensing agreement.
// 
// If the LICENSEE does not accept the terms and conditions, then LICENSEE must not accept the SOFTWARE.
// If at a later time the LICENSEE decides not to continue licensing the SOFTWARE under these terms and 
// conditions, then the LICENSEE must delete permanently all files constituting the SOFTWARE.
//
// File: Material.cpp
//********************************************************************

/*--------------------------------------------------------------------
Includos*/

	#include "..\..\Header Files\Ninfa3D.h"

/*--------------------------------------------------------------------
Variables externas*/

	extern IrrlichtDevice* device;
	extern IVideoDriver* driver;
	extern ISceneManager* SceneManager;
	extern IGUIEnvironment* guienv;
	extern IGPUProgrammingServices* gpu;
	extern IFileSystem* filesy;
	extern NewtonWorld* nWorld;

/*--------------------------------------------------------------------
Declaracion global de funciones*/

extern "C"
{

/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	MATERIAL FOR MESH
*/

	/*====================================================================
	Luminosidad del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialShininess(ISceneNode* Entity,unsigned int Num,float Shininess)
	{
		Entity->getMaterial(Num).Shininess = Shininess;
	}

	/*====================================================================
	Cambia la transparencia del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialAlpha(ISceneNode* Entity,unsigned int Num,unsigned int A)
	{
		Entity->getMaterial(Num).MaterialType = EMT_TRANSPARENT_VERTEX_ALPHA;

		Entity->getMaterial(Num).AmbientColor.setAlpha(A);
		Entity->getMaterial(Num).DiffuseColor.setAlpha(A);
		Entity->getMaterial(Num).SpecularColor.setAlpha(A);
		if(A==255)
			Entity->getMaterial(Num).MaterialType = EMT_SOLID;
	}

	/*====================================================================
	Cambia de color del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialColor(ISceneNode* Entity,unsigned int Num,unsigned int R,unsigned int G,unsigned int B)
	{
		Entity->getMaterial(Num).DiffuseColor.setRed(R);
		Entity->getMaterial(Num).DiffuseColor.setGreen(G);
		Entity->getMaterial(Num).DiffuseColor.setBlue(B);

		Entity->getMaterial(Num).AmbientColor.setRed(R);
		Entity->getMaterial(Num).AmbientColor.setGreen(G);
		Entity->getMaterial(Num).AmbientColor.setBlue(B);

		Entity->getMaterial(Num).SpecularColor.setRed(R);
		Entity->getMaterial(Num).SpecularColor.setGreen(G);
		Entity->getMaterial(Num).SpecularColor.setBlue(B);
	}

			/*====================================================================
	Aplica un emissive efecto al material*/
	
	DLL_EXPORT void DLL_APIENTRY MaterialEmissiveColor(ISceneNode* Entity,unsigned int Num,unsigned int R,unsigned int G,unsigned int B)
	{
		Entity->getMaterial(Num).EmissiveColor.setRed(R);
		Entity->getMaterial(Num).EmissiveColor.setGreen(G);
		Entity->getMaterial(Num).EmissiveColor.setBlue(B);

	}
	/*====================================================================
	Aplica un efecto al material*/

	DLL_EXPORT void DLL_APIENTRY MaterialType(ISceneNode* entity,unsigned int Num,int Type)
	{
		E_MATERIAL_TYPE mode[] = { EMT_SOLID,
								   EMT_LIGHTMAP_ADD,
								   EMT_DETAIL_MAP,
								   EMT_SPHERE_MAP,
								   EMT_REFLECTION_2_LAYER,
								   EMT_TRANSPARENT_ADD_COLOR,
								   EMT_TRANSPARENT_ALPHA_CHANNEL,
								   EMT_NORMAL_MAP_SOLID,
								   EMT_PARALLAX_MAP_SOLID };

		entity->getMaterial(Num).MaterialType = mode[ Type ];
		entity->getMaterial(Num).MaterialTypeParam = 0.035f;
	}

	/*====================================================================
	Aplica un efecto al material*/

	DLL_EXPORT void DLL_APIENTRY MaterialFlag(ISceneNode* Entity,unsigned int Num,int Flag,bool Mode)
	{
		E_MATERIAL_FLAG MaterialTable[] = { EMF_WIREFRAME,
											EMF_POINTCLOUD,
											EMF_GOURAUD_SHADING,				
											EMF_LIGHTING,
											EMF_ZBUFFER,
											EMF_ZWRITE_ENABLE,
											EMF_BACK_FACE_CULLING,
											EMF_FRONT_FACE_CULLING,
											EMF_FOG_ENABLE,
											EMF_NORMALIZE_NORMALS };

		Entity->getMaterial(Num).setFlag(MaterialTable[ Flag ],Mode);
	}

	/*====================================================================
	Devuelve la textura que esta utilizando el material*/

	DLL_EXPORT void* DLL_APIENTRY TextureMaterial(ISceneNode* Entity,unsigned int Num,unsigned int Index)
	{
		return (void*)Entity->getMaterial(Num).getTexture(Index);
	}

	/*====================================================================
	Devuelve el numero total de materiales*/

	DLL_EXPORT unsigned int DLL_APIENTRY MaterialCount(ISceneNode* Entity)
	{
		return Entity->getMaterialCount();
	}

	/*====================================================================
	Aplica una textura a un material*/

	DLL_EXPORT void DLL_APIENTRY MaterialTexture(ISceneNode* Entity,unsigned int Num,ITexture* Texture,unsigned int Index)
	{
		Entity->getMaterial(Num).setTexture(Index,Texture);
	}

	/*====================================================================
	Cambia la posicion de la textura dentro del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialTextureUV(ISceneNode* Entity,unsigned int Num,unsigned int Index,float X,float Y)
	{
		Entity->getMaterial(Num).getTextureMatrix(Index).setTextureTranslate(X,Y);
	}

	/*====================================================================
	Cambia el angulo de la textura dentro del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialTextureAngle(ISceneNode* Entity,unsigned int Num,unsigned int Index,float radAngle)
	{
		Entity->getMaterial(Num).getTextureMatrix(Index).setTextureRotationCenter(radAngle);
	}

	/*====================================================================
	Cambia de tamaņo la textura dentro del material*/

	DLL_EXPORT void DLL_APIENTRY MaterialTextureScale(ISceneNode* Entity,unsigned int Num,unsigned int Index,float SX,float SY)
	{
		Entity->getMaterial(Num).getTextureMatrix(Index).setTextureScaleCenter(SX,SY);
	}

/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	MATERIAL FOR BODY
*/

	/*====================================================================
	Crea un cuerpo con forma de cilindro*/

	DLL_EXPORT int DLL_APIENTRY CreateMaterial()
	{
		return NewtonMaterialCreateGroupID(nWorld);
	}

	/*====================================================================
	Crea un cuerpo con forma de cilindro*/

	DLL_EXPORT void DLL_APIENTRY MaterialElasticity(int matID1,int matID2,float Elasticity)
	{
		NewtonMaterialSetDefaultElasticity(nWorld,matID1,matID2,Elasticity);
	}

	/*====================================================================
	Crea un cuerpo con forma de cilindro*/

	DLL_EXPORT void DLL_APIENTRY MaterialFriction(int matID1,int matID2,float StaticFriction,float KineticFriction)
	{
		NewtonMaterialSetDefaultFriction(nWorld,matID1,matID2,StaticFriction,KineticFriction);
	}

	/*====================================================================
	Crea un cuerpo con forma de cilindro*/

	DLL_EXPORT void DLL_APIENTRY MaterialSoftness(int matID1,int matID2,float Softness)
	{
		NewtonMaterialSetDefaultSoftness(nWorld,matID1,matID2,Softness);
	}

	/*====================================================================
	Crea un cuerpo con forma de cilindro*/

	DLL_EXPORT void DLL_APIENTRY MaterialCollidable(int matID1,int matID2,int Mode)
	{
		NewtonMaterialSetDefaultCollidable(nWorld,matID1,matID2,Mode);
	}

}