// ----------------------------------------------------------------------------
// 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.
//
// /////////////////////////////////////////////////////////////////////////////

#ifdef BUILD_DLL
    #define DLL_EXPORT extern "C" __declspec(dllexport)
	#define BBCALL _stdcall
#else
    #define DLL_EXPORT
	#define BBCALL
#endif

#define IRRKLANG_EXPORTS
#define IRRKLANG_STATIC
/* ////////////////////////////////////////////////////////////////////////////
includes
*/
#include <irrlicht.h>
#include <irrKlang.h>
#include "irrKlangSceneNode.h"
#include "XEffects.h"
//#include <IMeshCache.h>



/* ////////////////////////////////////////////////////////////////////////////
irrlicht namespaces
*/
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace irrklang;


/* ////////////////////////////////////////////////////////////////////////////
Constant Definitions
*/
#define MAX_ARCHIVED_EVENTS 256

#define INVERSE_WORLD				1
#define WORLD_VIEW_PROJECTION		2
#define CAMERA_POSITION				3
#define TRANSPOSED_WORLD			4


/* ////////////////////////////////////////////////////////////////////////////
Custom Functions
*/
wchar_t* ConvertCharToWChar(const char* BlitzText);

/* ////////////////////////////////////////////////////////////////////////////
structure and class declarations
*/

typedef struct tag_CUBIC_SPLINE
{
    unsigned int *spline_id;
    float a;
	float b;
	float c;
	float d;
	float e;
	float f;
	float g;
	float h;
	float i;
	float j;
	float k;
	float l;
}
CUBIC_SPLINE;

typedef struct tag_ARCHIVED_MOUSE_EVENT
{
    unsigned int uiaction;
    float fdelta;
    int ix;
    int iy;
}
ARCHIVED_MOUSE_EVENT;

typedef struct tag_ARCHIVED_KEY_EVENT
{
    unsigned int uikey;
    unsigned int uidirection;
    unsigned int uiflags;
}
ARCHIVED_KEY_EVENT;

typedef struct tag_ARCHIVED_GUI_EVENT
{
	s32		id;
	s32		event;
	s32		x;
	s32		y;
}
ARCHIVED_GUI_EVENT;

typedef struct tag_IRR_PARTICLE_EMITTER
{
    float min_box_x;
    float min_box_y;
    float min_box_z;

    float max_box_x;
    float max_box_y;
    float max_box_z;

    float direction_x;
    float direction_y;
    float direction_z;

    unsigned int min_paritlcles_per_second;
    unsigned int max_paritlcles_per_second;

    int min_start_color_red;
    int min_start_color_green;
    int min_start_color_blue;

    int max_start_color_red;
    int max_start_color_green;
    int max_start_color_blue;

    unsigned int min_lifetime;
    unsigned int max_lifetime;

    float min_start_sizeX;
    float min_start_sizeY;
    float max_start_sizeX;
    float max_start_sizeY;

    int max_angle_degrees;
}
IRR_PARTICLE_EMITTER;

// a vertex used in creating custom static mesh objects
typedef struct tag_IRR_VERT
{
    float x;                // The x position of the vertex
    float y;                // The y position of the vertex
    float z;                // The z position of the vertex
    float normal_x;         // The x normal of the vertex
    float normal_y;         // The y normal of the vertex
    float normal_z;         // The z normal of the vertex
    unsigned int vcolor;     // The 32bit ARGB color of the vertex
    float texture_x;        // the x co-ordinate of the vertex on the texture (0 to 1)
    float texture_y;        // the y co-ordinate of the vertex on the texture (0 to 1)
}
IRR_VERT;

typedef struct tag_IRR_VECTOR
{
    float x;
    float y;
    float z;
}
IRR_VECTOR;

/* storage for information pertaining to a shader constant
 */
typedef struct tConstant tConstant;
struct tConstant
{
	tConstant *		next;
	const char *	name;
	int				address;
	int				preset;
	const float *	data;
	int				count;
};

/*
This implementation of the Irrlicht event receiver receives events as they
happen and stores them in a circular buffer. the caller can then pop the
events out of the buffer at their convienence. if the events are unattended
and the buffer filled the oldest event is discarded
*/
class StackedEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(const SEvent& event);
};


/* ----------------------------------------------------------------------------
This class provides a generic callback response for setting shader constants
the values for these constants are setup ahead of rendering as label and pointer
pairs these are then passed to the GPU program during this callback to set
constant values in gpu programs
*/
class CIrrShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
	/* attributes */
	tConstant *vertex_constant_list;
	tConstant *pixel_constant_list;
	bool UseHighLevelShaders;
	core::matrix4 world;
	core::vector3df pos;

	/* operations */
	CIrrShaderCallBack();
	~CIrrShaderCallBack();
	void resolveConstantPreset( int preset, const float **values, int * count );
	virtual void OnSetConstants( video::IMaterialRendererServices* services, s32 id );
};


/* returned structure containing shader information
 */
typedef struct tShaderReply tShaderReply;
struct tShaderReply
{
	/* The number of the material type which can be set in
	SMaterial::MaterialType	to use the renderer */
	s32						material_type;

	/* the shader callback object */
	CIrrShaderCallBack *	irrShaderCallBack;
	tShaderReply *			next_shader;
};

