// ----------------------------------------------------------------------------
// Blitz-Irrlicht 1.8.3 Wrapper by Ed Musolino 2015
// Based off of Frank Dodd's Irrlicht 1.7 Freebasic Wrapper (2006-2010)
// ----------------------------------------------------------------------------

//  This software is provided 'as-is', without any express Or implied
//  warranty.  In no event will the authors be held liable For any damages
//  arising from the use of this software.

//  Permission is granted To anyone To use this software For any purpose,
//  including commercial applications, And To alter it And redistribute it
//  freely, subject To the following restrictions:

//  1. The Origin of this software must Not be misrepresented; you must not
//     claim that you wrote the original software. If you use this software
//     in a product, an acknowledgement in the product documentation would be
//     appreciated but is Not required.
//  2. Altered source versions must be clearly marked as such, And must Not be
//     misrepresented as being the original software.
//  3. This notice may Not be removed Or altered from any source distribution.
//
// /////////////////////////////////////////////////////////////////////////////

#include "bIrrlicht.h"


extern IrrlichtDevice*		device;
extern IVideoDriver*		driver;
extern ISceneManager*		smgr;
extern IGUIEnvironment*		guienv;


extern "C"
{
/*
FreeEntity EntityHandle
Parameters
EntityHandle - Handle returned by an Entity creating function such as CreateCube(), CreateLight(), LoadMesh() etc.  

Description
FreeEntity will free up the internal resources associated with a particular entity and remove it from the scene. 

This command will also free all children entities parented to the entity. 

Note that the variable holding the handle (and any variables referencing children handles) are not reset as it is up to the Blitz programmer to zero or ignore their contents following a call to FreeEntity().  
*/
DLL_EXPORT int BBCALL iFreeNode ( IAnimatedMeshSceneNode* node )
{
    // delete the node from the scene
//	if(smgr->getSceneNodeFromId((s32)node))
		node->remove();
	return 0;
}

/*
CopyEntity ( entity[,parent] )
Parameters
entity - Entity Handle 
parent (optional) - Entity that will act as Parent to the copy.  

Description
Creates a copy of an entity and returns the handle of the newly created copy. This is a new entity instance of an existing entity's mesh! Anything you do to the original Mesh (such as RotateMesh) will effect all the copies. Other properties (such as EntityColor, Position etc.) since they are 'Entity' properties, will be individual to the copy. 

If a parent entity is specified, the copied entity will be created at the parent entity's position. Otherwise, it will be created at 0,0,0.  
*/
DLL_EXPORT int* BBCALL iCopyNode ( ISceneNode* node, ISceneNode* parent = 0 )
{
    // copy a node
//	if(smgr->getSceneNodeFromId((s32)node))
		return (int*)node->clone(parent,0);
//	return 0;
}

/*
EntityColor entity,red#,green#,blue#
Parameters
entity - entity handle 
Red# - red value of entity 
Green# - green value of entity 
Blue# - blue value of entity  

Description
Sets the color of an entity. 

The Red, Green and Blue values should be in the range 0-255 with 0 being darkest and 255 brightest. The default entity color is 255,255,255 (White).  
*/
DLL_EXPORT void BBCALL iNodeColor( ISceneNode* node, int red, int green, int blue, int alpha )
{
	node->getMaterial(0).DiffuseColor.setRed(red);
	node->getMaterial(0).DiffuseColor.setGreen(green);
	node->getMaterial(0).DiffuseColor.setBlue(blue);
	node->getMaterial(0).DiffuseColor.setAlpha(alpha);
	node->getMaterial(0).AmbientColor.setRed(red);		//Maybe divide by 2
	node->getMaterial(0).AmbientColor.setGreen(green);	//Maybe divide by 2
	node->getMaterial(0).AmbientColor.setBlue(blue);	//Maybe divide by 2
	node->getMaterial(0).AmbientColor.setAlpha(alpha);	//Maybe divide by 2
	node->getMaterial(0).EmissiveColor.setRed(red);
	node->getMaterial(0).EmissiveColor.setGreen(green);
	node->getMaterial(0).EmissiveColor.setBlue(blue);
	node->getMaterial(0).EmissiveColor.setAlpha(alpha);
	node->getMaterial(0).SpecularColor.setRed(red);
	node->getMaterial(0).SpecularColor.setGreen(green);
	node->getMaterial(0).SpecularColor.setBlue(blue);
	node->getMaterial(0).SpecularColor.setAlpha(alpha);
}

/*
EntityAlpha entity,alpha#
Parameters
Entity - entity handle 
Alpha# - alpha level of entity  

Description
Sets the entity alpha level of an entity. 

The alpha# value should be in a floating point value in the range 0-1. The default entity alpha setting is 1. 

The alpha level is how transparent an entity is. A value of 1 will mean the entity is opaque. A value of 0 will mean the entity is completely transparent, i.e. invisible. Values between 0 and 1 will cause varying amount of transparency. This is useful for imitating the look of objects such as glass and other translucent materials. 

An EntityAlpha value of 0 is especially useful as Blitz3D will not render entities with such a value, but will still involve the entities in collision tests. This is unlike HideEntity, which doesn't involve entities in collisions.  
*/
DLL_EXPORT void BBCALL iNodeAlpha( ISceneNode* node, int alpha )
{
	//node->getMaterial(0).AmbientColor.setAlpha(alpha);
}

/*
EntityShininess Entity, Shininess#
Parameters
Entity - entity handle 
Shininess# - shininess of entity  

Description
Sets the specular shininess of an entity. 

The shininess# value should be a floting point number in the range 0-1. The default shininess setting is 0. 

Shininess is how much brighter certain areas of an object will appear to be when a light is shone directly at them. 

Setting a shininess value of 1 for a medium to high poly sphere, combined with the creation of a light shining in the direction of it, will give it the appearance of a shiny snooker ball.  
*/
DLL_EXPORT void BBCALL iNodeShininess( ISceneNode* node, float shininess )
{

}


/*
EntityTexture entity,texture[,frame][,index]
Parameters
entity - entity handle 
texture - texture handle 
frame (optional) - frame of texture. Defaults to 0. 
index (optional) - index number of texture. Should be in the range to 0-7. Defaults to 0.  

Description
Applies a texture to an entity. 

The optional frame parameter specifies which texture animation frame should be used as the texture. 

The optional index parameter specifies which index number should be assigned to the texture. Index numbers are used for the purpose of multitexturing. See TextureBlend. 

A little note about multitexturing and slowdown. Graphics cards support a maximum amount of textures per object, which can be used with very little, if any, slowdown. For most cards this is two, but for a GeForce3 it is four. However, once you use more than this amount, Blitz will emulate the effect itself by duplicating objects and textures. Obviously, this may then cause slowdown.  
*/
DLL_EXPORT void BBCALL iNodeTexture ( ISceneNode* node, ITexture *texture, int index = 0 )
{
    // apply a texture to the model
	//if(smgr->getSceneNodeFromId((s32)node))
	node->setMaterialTexture( index, texture );
}

/*
EntityBlend Entity, Blend
Parameters
Entity - Entity handle 

Blend - Blend mode of the entity. 
1: Alpha (default) 
2: Multiply 
3: Add  

Description
Sets the blending mode of an entity. This blending mode determines the way in which the new RGBA of the pixel being rendered is combined with the RGB of the background. 

To calculate the new RGBA of the pixel being rendered, the texture RGBA for the pixel (see TextureBlend for more information on how the texture RGBA is calculated) is taken, its alpha component multiplied by the entities/brushes (where applicable) alpha value and its color compentent multiplied by the entities/brushes colour. This is the RGBA which will then be blended into the background pixel, and how this is done depends on the EntityBlend value. 

Alpha: 
This blends the pixels according to the Alpha value. This is rougly done to the formula: 

Rr = ( An * Rn ) + ( ( 1.0 - An ) * Ro ) 
Gr = ( An * Gn ) + ( ( 1.0 - An ) * Go ) 
Br = ( An * Bn ) + ( ( 1.0 - An ) * Bo ) 

Where R = Red, G = Green, B = Blue, n = new pixel colour values, r = resultant colour values, o = old pixel colour values. 

Alpha blending is the default blending mode and is used with most world objects. 

Multiply: 
This blend mode will darken the underlying pixels. If you think of each RGB value as being on a scale from 0% to 100%, where 0 = 0% and 255 = 100%, the multiply blend mode will multiply the red, green and blue values individually together in order to get the new RGB value, roughly according to: 

Rr = ( ( Rn / 255.0 ) * ( Ro / 255.0 ) ) * 255.0 
Gr = ( ( Gn / 255.0 ) * ( Go / 255.0 ) ) * 255.0 
Br = ( ( Bn / 255.0 ) * ( Bo / 255.0 ) ) * 255.0 

The alpha value has no effect with multiplicative blending. Blending a RGB value of 255, 255, 255 will make no difference, while an RGB value of 128, 128, 128 will darken the pixels by a factor of 2 and an RGB value of 0, 0, 0 will completely blacken out the resultant pixels. An RGB value of 0, 255, 255 will remove the red component of the underlying pixel while leaving the other color values 
untouched. 

Multiply blending is most often used for lightmaps, shadows or anything else that needs to 'darken' the resultant pixels. 

Add: 
Additive blending will add the new color values to the old, roughly according to: 

Rr = ( Rn * An ) + Ro 
Gr = ( Gn * An ) + Go 
Br = ( Bn * An ) + Bo 

The resultant RGB values are clipped out at 255, meaning that multiple additive effects can quickly cause visible banding from smooth gradients. 

Additive blending is extremely useful for effects such as laser shots and fire. 
*/
DLL_EXPORT void BBCALL iNodeBlend( ISceneNode* node, int blend )
{

}


/*
EntityFX entity,fx
Parameters
entity - entity handle 

fx - 
0: nothing (default) 
1: full-bright 
2: use vertex colors instead of brush color 
4: flatshaded 
8: disable fog 
16: disable backface culling 
32: force alpha-blending  

Description
Sets miscellaneous effects for an entity. 

Flags can be added to combine two or more effects. For example, specifying a flag of 3 (1+2) will result in a full-bright and vertex-coloured brush. 

Flag 32, to force alpha-blending, must be used in order to enable vertex alpha (see VertexColor).  
*/
DLL_EXPORT void BBCALL iNodeFX( ISceneNode* node, int fx )
{

}


/*
EntityAutoFade entity,near#,far#
Parameters
entity - entity handle 
near# - distance in front of the camera at which entity's will start being faded 
far# - distance in front of the camera at which entity's will stop being faded (and will be invisible)  

Description
Enables auto fading for an entity. This will cause an entity's alpha level to be adjusted at distances between near and far to create a 'fade-in' effect.  
*/
DLL_EXPORT void BBCALL iNodeAutoFade( ISceneNode* node, float near, float far )
{

}


/*
PaintEntity entity,brush
Parameters
entity - entity handle 
brush - brush handle  

Description
Paints a entity with a brush. 

The reason for using PaintEntity to apply specific properties to a entity using a brush rather than just using EntityTexture, EntityColor, EntityShininess etc, is that you can pre-define one brush, and then paint entities over and over again using just the one command rather than lots of separate ones.  
*/
DLL_EXPORT void BBCALL iPaintNode( ISceneNode* node, int brush )
{

}


/*
EntityOrder entity,order
Parameters
entity - entity handle 
order - order that entity will be drawn in  

Description
Sets the drawing order for an entity. 

An order value of 0 will mean the entity is drawn normally. A value greater than 0 will mean that entity is drawn first, behind everything else. A value less than 0 will mean the entity is drawn last, in front of everything else. 

Setting an entity's order to non-0 also disables z-buffering for the entity, so should be only used for simple, convex entities like skyboxes, sprites etc. 

EntityOrder affects the specified entity but none of its child entities, if any exist.  
*/
DLL_EXPORT void BBCALL iNodeOrder( ISceneNode* node )
{

}


/*
ShowEntity entity
Parameters
entity - entity handle  

Description
Shows an entity. Very much the opposite of HideEntity. 

Once an entity has been hidden using HideEntity, use show entity to make it visible and involved in collisions again. Note that ShowEntity has no effect if the enitities parent object is hidden. 

Entities are shown by default after creating/loading them, so you should only need to use ShowEntity after using HideEntity. 

ShowEntity affects the specified entity only - child entities are not affected.  
*/
DLL_EXPORT void BBCALL iShowNode( ISceneNode* node )
{
    // set the speed of playback in the animation
	//if(smgr->getSceneNodeFromId((s32)node))
		node->setVisible( true );
}


/*
HideEntity entity
Parameters
entity - entity handle  

Description
Hides an entity, so that it is no longer visible, and is no longer involved in collisions. 

The main purpose of hide entity is to allow you to create entities at the beginning of a program, hide them, then copy them and show as necessary in the main game. This is more efficient than creating entities mid-game. 

If you wish to hide an entity so that it is no longer visible but still involved in collisions, then use EntityAlpha 0 instead. This will make an entity completely transparent. 

HideEntity affects the specified entity and all of its child entities, if any exist.  
*/
DLL_EXPORT void BBCALL iHideNode( ISceneNode* node )
{
    // set the speed of playback in the animation
	//if(smgr->getSceneNodeFromId((s32)node))
		node->setVisible( false );
}


/*
NameEntity entity,name$
Parameters
entity - entity handle 
name$ - name of entity  

Description
Sets an entity's name. 

See also: EntityName.  
*/
DLL_EXPORT void BBCALL iNameNode( ISceneNode* node, const c8 *name )
{
    node->setName(name);
}

DLL_EXPORT void BBCALL iIDNode( ISceneNode* node, int id )
{
    node->setID(id);
}

/*
EntityParent entity,parent[,global]
Parameters
entity - entity handle 
parent - parent entity handle 
global (optional) - true for the child entity to retain its global position and orientation. Defaults to true.  

Description
Attaches an entity to a parent. 

Parent may be 0, in which case the entity will have no parent.  
*/
DLL_EXPORT void BBCALL iNodeParent ( ISceneNode *node, ISceneNode *parent = 0 )
{
    parent->addChild(node);
}


/*
GetParent ( entity )
Parameters
entity - entity handle  

Description
Returns an entity's parent.  
*/
DLL_EXPORT int* BBCALL iGetParent ( ISceneNode *node )
{
   return (int*)node->getParent();
}

DLL_EXPORT float BBCALL iNodeXScale ( IAnimatedMeshSceneNode* node )		//ED MUSOLINO
{
    // get the scale of the node
    vector3df vect;
    vect = node->getScale();
    return vect.X;
}
DLL_EXPORT float BBCALL iNodeYScale ( IAnimatedMeshSceneNode* node )		//ED MUSOLINO
{
    // get the scale of the node
    vector3df vect;
    vect = node->getScale();
    return vect.Y;
}
DLL_EXPORT float BBCALL iNodeZScale ( IAnimatedMeshSceneNode* node )		//ED MUSOLINO
{
    // get the scale of the node
    vector3df vect;
    vect = node->getScale();
    return vect.Z;
}

/* ----------------------------------------------------------------------------
get a node that represents the position of a joint in a skeleton
*/
DLL_EXPORT IBoneSceneNode*  BBCALL iGetNodeJoint ( IAnimatedMeshSceneNode* node, const char* node_name )//ISceneNode *
{
    return node->getJointNode( node_name );
}




}