//********************************************************************
// 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: Control.cpp
//********************************************************************

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

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

	#include "..\..\Codes\CShaderCallback.h"

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

	extern IrrlichtDevice*          device;
	extern IVideoDriver*            driver;
	extern ISceneManager*           SceneManager;
	extern IGUIEnvironment*         guienv;
	extern IGPUProgrammingServices* gpu;

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

extern "C"
{

	/*====================================================================
	Asigna un nombre a la entidad*/

	DLL_EXPORT void DLL_APIENTRY NameEntity(ISceneNode* Entity,const char* Name)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in NameEntity: The entity does not exist.",ELL_ERROR );

		Entity->setName(Name);
	}

	/*====================================================================
	Borra la entidad del espacio 3D y de la memoria*/

	DLL_EXPORT void DLL_APIENTRY DeleteEntity(ISceneNode* Entity)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in DeleteEntity: The entity does not exist.",ELL_ERROR );

			Entity->remove();
	}

	/*====================================================================
	Emparenta la entidad a otra entidad*/

	DLL_EXPORT void DLL_APIENTRY EntityParent(ISceneNode* Entity,ISceneNode* Parent)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in EntityParent: The entity does not exist.",ELL_ERROR );

		if(!Parent)
			device->getLogger()->log( "ERROR in EntityParent: The parent does not exist.",ELL_ERROR );

		Entity->setParent(Parent);
	}

	/*====================================================================
	Muestra la entidad*/

	DLL_EXPORT void DLL_APIENTRY ShowEntity(ISceneNode* Entity)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in ShowEntity: The entity does not exist.",ELL_ERROR );

		Entity->setVisible(true);
	}

	/*====================================================================
	Oculta la entidad*/

	DLL_EXPORT void DLL_APIENTRY HideEntity(ISceneNode* Entity)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in HideEntity: The entity does not exist.",ELL_ERROR );

		Entity->setVisible(false);
	}

	/*====================================================================
	Hace una copia de la entidad*/

	DLL_EXPORT void* DLL_APIENTRY CopyEntity(ISceneNode* entity)
	{
		return (void*)entity->clone(0,SceneManager);
	}

	/*====================================================================
	Luminosidad de la malla*/

	DLL_EXPORT void DLL_APIENTRY EntityShininess(ISceneNode* Entity,float Shininess)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in EntityShininess: The entity does not exist.",ELL_ERROR );

		for(unsigned int i = 0;i<Entity->getMaterialCount();i++)
			Entity->getMaterial(i).Shininess = Shininess;

	}

	/*====================================================================
	Cambia la transparencia de la entidad*/

	DLL_EXPORT void DLL_APIENTRY EntityAlpha(ISceneNode* Entity,unsigned int A)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in EntityAlpha: The entity does not exist.",ELL_ERROR );

		for(unsigned int i = 0;i<Entity->getMaterialCount();i++)
		{
			Entity->getMaterial(i).AmbientColor.setAlpha(A);
			Entity->getMaterial(i).DiffuseColor.setAlpha(A);
			Entity->getMaterial(i).SpecularColor.setAlpha(A);
		}
	}

	/*====================================================================
	Aplica una textura a la entidad*/

	DLL_EXPORT void DLL_APIENTRY EntityTexture(ISceneNode* Entity,ITexture* Texture,unsigned int Index)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in EntityTexture: The entity does not exist.",ELL_ERROR );

		if(!Texture)
			device->getLogger()->log( "ERROR in EntityTexture: The texture does not exist.",ELL_ERROR );

		Entity->setMaterialTexture(Index,Texture);
	}

	/*====================================================================
	Cambia de color la entidad*/

	DLL_EXPORT void DLL_APIENTRY EntityColor(ISceneNode* Entity,unsigned int R,unsigned int G,unsigned int B)
	{
		if(!Entity)
			device->getLogger()->log( "ERROR in EntityColor: The entity does not exist.",ELL_ERROR );

		for(unsigned int i = 0;i<Entity->getMaterialCount();i++)
		{
			unsigned int A = Entity->getMaterial(i).DiffuseColor.getAlpha();
			Entity->getMaterial(i).DiffuseColor.set(A,R,G,B);
			Entity->getMaterial(i).AmbientColor.set(A,R,G,B);
			Entity->getMaterial(i).SpecularColor.set(A,R,G,B);
		}
	}

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

	DLL_EXPORT void DLL_APIENTRY EntityType(ISceneNode* Entity,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->setMaterialType(mode[Type]);

		for(unsigned int i = 0;i<Entity->getMaterialCount();i++)
		{
			if(Entity->getMaterial(i).MaterialTypeParam == 0)
			{
				driver->makeNormalMapTexture(Entity->getMaterial(i).getTexture(1),9.0f);
				Entity->getMaterial(i).MaterialTypeParam = 0.035f;
			}
		}
	}

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

	DLL_EXPORT void DLL_APIENTRY EntityFlag(ISceneNode* Entity,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 };

		for(unsigned int i = 0;i<Entity->getMaterialCount();i++)
		{
			Entity->getMaterial(i).setFlag(MaterialTable[ Flag ],Mode);
		}
	}

}