// ----------------------------------------------------------------------------
// 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"
#include "CSceneNodeAnimatorFade.h"


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




extern "C"
{

/* ----------------------------------------------------------------------------
Animates the mesh based on the position of the joints, this should be used at
the end of any manual joint operations including blending and joints animated
using IRR_JOINT_MODE_CONTROL and IrrSetNodeRotation on a bone node
*/
DLL_EXPORT void BBCALL iAnimateJoints ( IAnimatedMeshSceneNode* node )
{
    // perform the bone animation
    node->animateJoints();
}

/* ----------------------------------------------------------------------------
Sets the animation mode of joints in a node

IRR_JOINT_MODE_NONE will result in no animation of the model based on bones
IRR_JOINT_MODE_READ will result in automatic animation based upon
IRR_JOINT_MODE_CONTROL will allow the position of the bones to be set through code

When using the control mode IrrAnimateJoints must be called before IrrDrawScene
*/
DLL_EXPORT void BBCALL iSetJointMode ( IAnimatedMeshSceneNode* node, unsigned int mode )
{
	E_JOINT_UPDATE_ON_RENDER jointMode[] = {
		EJUOR_NONE,
		EJUOR_READ,
		EJUOR_CONTROL
	};

    // perform the bone animation
    node->setJointMode( jointMode[mode] );
}

/* ////////////////////////////////////////////////////////////////////////////
ANIMATOR FUNCTIONS
*/
/* ----------------------------------------------------------------------------
add a collision animator to a node
*/
DLL_EXPORT int * BBCALL iCollisionAnimator(
                                        ITriangleSelector* selector,
                                        ISceneNode* node,
                                        float radiusx, float radiusy, float radiusz,
                                        float gravityx, float gravityy, float gravityz,
                                        float offsetx, float offsety, float offsetz )
{
    scene::ISceneNodeAnimator* anim = NULL;

    if ( node )
    {
        node->setTriangleSelector(selector);

        anim = smgr->createCollisionResponseAnimator(
            selector, node, core::vector3df(radiusx,radiusy,radiusz),
            core::vector3df(gravityx,gravityy,gravityz),
            core::vector3df(offsetx,offsety,offsetz));
        if ( anim )
        {
            node->addAnimator(anim);
            anim->drop();
        }
        else
        {
            printf( "Could not create animator\n" );
        }
    }
    else
    {
        printf( "No node supplied\n" );
    }
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a deletion animator to a node
*/
DLL_EXPORT int * BBCALL iDeleteAnimator( ISceneNode* node, int delete_after )
{
    scene::ISceneNodeAnimator* anim = smgr->createDeleteAnimator( delete_after );
	node->addAnimator(anim);
	anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a fly-in-circle animator to a node
*/
DLL_EXPORT int * BBCALL iFlyCircleAnimator(
                                        ISceneNode* node,
                                        float x, float y, float z,
                                        float radius, float speed )
{
    scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(
            core::vector3df(x,y,z), radius, speed );
	node->addAnimator(anim);
	anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a fly-straight animator to a node
*/
DLL_EXPORT int * BBCALL iFlyStraightAnimator(
                                        ISceneNode* node,
                                        float sx, float sy, float sz,
                                        float ex, float ey, float ez,
                                        unsigned int uitime, bool loop )
{
    scene::ISceneNodeAnimator* anim = smgr->createFlyStraightAnimator(
            core::vector3df(sx,sy,sz),
            core::vector3df(ex,ey,ez),
            uitime,
            loop
    );
	node->addAnimator(anim);
	anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a rotation animator to a node
*/
DLL_EXPORT int * BBCALL iRotationAnimator( ISceneNode* node, float x, float y, float z )
{
    scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
            core::vector3df(x,y,z));
	node->addAnimator(anim);
	anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a spline animator to a node
*/
DLL_EXPORT int * BBCALL iSplineAnimator( ISceneNode* node, int iPoints,
                                    float *x, float *y, float *z,
                                    int time, float speed, float tightness )
{
    core::array<core::vector3df> points;
    for ( int loop = 0; loop < iPoints; loop++ )
    {
        points.push_back(core::vector3df(x[loop], y[loop], z[loop]));
    }

    scene::ISceneNodeAnimator* anim = smgr->createFollowSplineAnimator(
            time, points, speed, tightness);
    node->addAnimator(anim);
    anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
add a fade animator to a node
*/
DLL_EXPORT int * BBCALL iFadeAnimator( ISceneNode* node, int delete_after, f32 scale )
{
	scene::ISceneNodeAnimator* anim = new CSceneNodeAnimatorFade(
			smgr, device->getTimer()->getTime(), delete_after, scale );

	node->addAnimator(anim);
	anim->drop();
	return (int *)anim;
}

/* ----------------------------------------------------------------------------
remove an animator from a node
*/
DLL_EXPORT void BBCALL iFreeAnimator( ISceneNode* node, ISceneNodeAnimator *  anim )
{
    node->removeAnimator ( anim );
}









}


