
extern "C" 
{
//------------------------------------------------------------------------------------
// irr::scene::ISkinnedMesh wrappers
//------------------------------------------------------------------------------------

	u32 IrrScene_ISkinnedMesh_getJointCount(ISkinnedMesh* mesh)
	{
		if (mesh) {
			return mesh->getJointCount();
		} else return 0;
	}
	
	const c8* IrrScene_ISkinnedMesh_getJointName(ISkinnedMesh* mesh, u32 number)
	{
		if (mesh) {
			return mesh->getJointName(number);
		} else return 0;
	}

	s32 IrrScene_ISkinnedMesh_getJointNumber(ISkinnedMesh* mesh, const c8* name)
	{
		if (mesh) {
			return mesh->getJointNumber(name);
		} else return -1;
	}
	
	bool IrrScene_ISkinnedMesh_useAnimationFrom(ISkinnedMesh* mesh, const ISkinnedMesh *other)
	{
		if (mesh) {
			return mesh->useAnimationFrom(other);
		} else return false;
	}
	
	void IrrScene_ISkinnedMesh_updateNormalsWhenAnimating(ISkinnedMesh* mesh, bool on)
	{
		if (mesh) {
			mesh->updateNormalsWhenAnimating(on);
		}
	}
	
	void IrrScene_ISkinnedMesh_setInterpolationMode(ISkinnedMesh* mesh, E_INTERPOLATION_MODE mode)
	{
		if (mesh) {
			mesh->setInterpolationMode(mode);
		}
	}
	
	void IrrScene_ISkinnedMesh_animateMesh(ISkinnedMesh* mesh, f32 frame, f32 blend)
	{
		if (mesh) {
			mesh->animateMesh(frame, blend);
		}
	}
	
	void IrrScene_ISkinnedMesh_skinMesh(ISkinnedMesh* mesh)
	{
		if (mesh) {
			mesh->skinMesh();
		}
	}
	
	void IrrScene_ISkinnedMesh_convertMeshToTangents(ISkinnedMesh* mesh)
	{
		if (mesh) {
			mesh->convertMeshToTangents();
		}
	}

	bool IrrScene_ISkinnedMesh_drop(ISkinnedMesh* unk)
	{
		if (unk)
			return unk->drop();
		else return 0;
	}
	
	const c8* IrrScene_ISkinnedMesh_getDebugName(ISkinnedMesh* unk)
	{
		if (unk)
			return unk->getDebugName();
		else return "";
	}
	
	void IrrScene_ISkinnedMesh_grab(ISkinnedMesh* unk)
	{
		if (unk)
			unk->grab();
	}

	bool IrrScene_ISkinnedMesh_setHardwareSkinning(ISkinnedMesh* mesh, bool on)
	{
		if (mesh)
			return mesh->setHardwareSkinning(on);
		else return false;
	}
	
	bool IrrScene_ISkinnedMesh_isStatic(ISkinnedMesh* mesh)
	{
		if (mesh)
			return mesh->isStatic();
		else return false;
	}

	void IrrScene_ISkinnedMesh_finalize(ISkinnedMesh* mesh)
	{
		if (mesh)
			mesh->finalize();
	}

	SSkinMeshBuffer* IrrScene_ISkinnedMesh_addMeshBuffer(ISkinnedMesh* mesh)
	{
		if (mesh)
			return mesh->addMeshBuffer();
		else return 0;
	}

	ISkinnedMesh::SJoint* IrrScene_ISkinnedMesh_addJoint(ISkinnedMesh* mesh, ISkinnedMesh::SJoint *parent=0)
	{
		if (mesh)
			return mesh->addJoint(parent);
		else return 0;
	}

	ISkinnedMesh::SWeight* IrrScene_ISkinnedMesh_addWeight(ISkinnedMesh* mesh, ISkinnedMesh::SJoint *joint)
	{
		if (mesh)
			return mesh->addWeight(joint);
		else return 0;
	}

	ISkinnedMesh::SPositionKey* IrrScene_ISkinnedMesh_addPositionKey(ISkinnedMesh* mesh, ISkinnedMesh::SJoint *joint)
	{
		if (mesh)
			return mesh->addPositionKey(joint);
		else return 0;
	}

	ISkinnedMesh::SScaleKey* IrrScene_ISkinnedMesh_addScaleKey(ISkinnedMesh* mesh, ISkinnedMesh::SJoint *joint)
	{
		if (mesh)
			return mesh->addScaleKey(joint);
		else return 0;
	}

	ISkinnedMesh::SRotationKey* IrrScene_ISkinnedMesh_addRotationKey(ISkinnedMesh* mesh, ISkinnedMesh::SJoint *joint)
	{
		if (mesh)
			return mesh->addRotationKey(joint);
		else return 0;
	}

	s32 IrrScene_ISkinnedMesh_getMeshBuffers(ISkinnedMesh* mesh, u32** outPtrs) 
	{
		if (mesh) {
			s32 size = mesh->getMeshBuffers().size();
			
			Irr_ptrarray_allocate(outPtrs, size);
			
			for (int i=0; i<size; i++) {	
				((u32*)*outPtrs)[i] = (u32)(mesh->getMeshBuffers()[i]);
			}

			return size;		
		} else return 0;			
	}

	s32 IrrScene_ISkinnedMesh_getAllJoints(ISkinnedMesh* mesh, u32** outPtrs) 
	{
		if (mesh) {
			s32 size = mesh->getAllJoints().size();
			
			Irr_ptrarray_allocate(outPtrs, size);
			
			for (int i=0; i<size; i++) {	
				((u32*)*outPtrs)[i] = (u32)(mesh->getAllJoints()[i]);
			}

			return size;		
		} else return 0;			
	}

//------------------------------------------------------------------------------------
// SPositionKey
//------------------------------------------------------------------------------------

	ISkinnedMesh::SPositionKey* IrrScene_ISkinnedMesh_SPositionKey_new()
	{
		return new ISkinnedMesh::SPositionKey();
	}

	void IrrScene_ISkinnedMesh_SPositionKey_del(ISkinnedMesh::SPositionKey* k) 
	{
		if (k) delete k;
	}
	
	f32 IrrScene_ISkinnedMesh_SPositionKey_getFrame(ISkinnedMesh::SPositionKey* k) 
	{
		if (k) {
			return k->frame;
		} else return 0.0;
	}
	
	void IrrScene_ISkinnedMesh_SPositionKey_setFrame(ISkinnedMesh::SPositionKey* k, f32 frame) 
	{
		if (k) {
			k->frame = frame;
		}
	}
	
	// dont delete
	vector3df* IrrScene_ISkinnedMesh_SPositionKey_getPosition(ISkinnedMesh::SPositionKey* k) 
	{
		if (k) {
			return &k->position;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SPositionKey_setPosition(ISkinnedMesh::SPositionKey* k, vector3df* position) 
	{
		if (k) {
			k->position = *position;
		}
	}

//------------------------------------------------------------------------------------
// SScaleKey
//------------------------------------------------------------------------------------

	ISkinnedMesh::SScaleKey* IrrScene_ISkinnedMesh_SScaleKey_new()
	{
		return new ISkinnedMesh::SScaleKey();
	}

	void IrrScene_ISkinnedMesh_SScaleKey_del(ISkinnedMesh::SScaleKey* k) 
	{
		if (k) delete k;
	}
	
	f32 IrrScene_ISkinnedMesh_SScaleKey_getFrame(ISkinnedMesh::SScaleKey* k) 
	{
		if (k) {
			return k->frame;
		} else return 0.0;
	}
	
	void IrrScene_ISkinnedMesh_SScaleKey_setFrame(ISkinnedMesh::SScaleKey* k, f32 frame) 
	{
		if (k) {
			k->frame = frame;
		}
	}
	
	// dont delete
	vector3df* IrrScene_ISkinnedMesh_SScaleKey_getScale(ISkinnedMesh::SScaleKey* k) 
	{
		if (k) {
			return &k->scale;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SScaleKey_setScale(ISkinnedMesh::SScaleKey* k, vector3df* scale) 
	{
		if (k) {
			k->scale = *scale;
		}
	}

//------------------------------------------------------------------------------------
// SRotationKey
//------------------------------------------------------------------------------------

	ISkinnedMesh::SRotationKey* IrrScene_ISkinnedMesh_SRotationKey_new()
	{
		return new ISkinnedMesh::SRotationKey();
	}

	void IrrScene_ISkinnedMesh_SRotationKey_del(ISkinnedMesh::SRotationKey* k) 
	{
		if (k) delete k;
	}
	
	f32 IrrScene_ISkinnedMesh_SRotationKey_getFrame(ISkinnedMesh::SRotationKey* k) 
	{
		if (k) {
			return k->frame;
		} else return 0.0;
	}
	
	void IrrScene_ISkinnedMesh_SRotationKey_setFrame(ISkinnedMesh::SRotationKey* k, f32 frame) 
	{
		if (k) {
			k->frame = frame;
		}
	}
	
	// dont delete
	quaternion* IrrScene_ISkinnedMesh_SRotationKey_getRotation(ISkinnedMesh::SRotationKey* k) 
	{
		if (k) {
			return &k->rotation;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SRotationKey_setRotation(ISkinnedMesh::SRotationKey* k, quaternion* rotation) 
	{
		if (k) {
			k->rotation = *rotation;
		}
	}
	
//------------------------------------------------------------------------------------
// SWeight
//------------------------------------------------------------------------------------
	ISkinnedMesh::SWeight* IrrScene_ISkinnedMesh_SWeight_new()
	{
		return new ISkinnedMesh::SWeight();
	}

	void IrrScene_ISkinnedMesh_SWeight_del(ISkinnedMesh::SWeight* w) 
	{
		if (w) delete w;
	}

	u16 IrrScene_ISkinnedMesh_SWeight_getBufferId(ISkinnedMesh::SWeight* w) 
	{
		if (w) {
			return w->buffer_id;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SWeight_setBufferId(ISkinnedMesh::SWeight* w, u16 buffer_id) {
		if (w) {
			w->buffer_id = buffer_id;
		}
	}

	u32 IrrScene_ISkinnedMesh_SWeight_getVertexId(ISkinnedMesh::SWeight* w) 
	{
		if (w) {
			return w->vertex_id;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SWeight_setVertexId(ISkinnedMesh::SWeight* w, u32 vertex_id) {
		if (w) {
			w->vertex_id = vertex_id;
		}
	}

	f32 IrrScene_ISkinnedMesh_SWeight_getStrength(ISkinnedMesh::SWeight* w) 
	{
		if (w) {
			return w->strength;
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SWeight_setStrength(ISkinnedMesh::SWeight* w, f32 strength) {
		if (w) {
			w->strength = strength;
		}
	}

//------------------------------------------------------------------------------------
// SJoint
//------------------------------------------------------------------------------------

	ISkinnedMesh::SJoint* IrrScene_ISkinnedMesh_SJoint_new()
	{
		return new ISkinnedMesh::SJoint();
	}

	void IrrScene_ISkinnedMesh_SJoint_del(ISkinnedMesh::SJoint* w) 
	{
		if (w) delete w;
	}

	const c8* IrrScene_ISkinnedMesh_SJoint_getName(ISkinnedMesh::SJoint* j) 
	{
		if (j) {
			return j->Name.c_str();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setName(ISkinnedMesh::SJoint* j, const c8* name) 
	{
		if (j) {
			j->Name = name;
		}
	}

	// must delete
	matrix4* IrrScene_ISkinnedMesh_SJoint_getLocalMatrix(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new matrix4(j->LocalMatrix);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setLocalMatrix(ISkinnedMesh::SJoint* j, matrix4* matrix)
	{
		if (j) {
			j->LocalMatrix = *matrix;
		}
	}

	// must delete
	matrix4* IrrScene_ISkinnedMesh_SJoint_getGlobalMatrix(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new matrix4(j->GlobalMatrix);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setGlobalMatrix(ISkinnedMesh::SJoint* j, matrix4* matrix)
	{
		if (j) {
			j->GlobalMatrix = *matrix;
		}
	}

	// must delete
	matrix4* IrrScene_ISkinnedMesh_SJoint_getGlobalAnimatedMatrix(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new matrix4(j->GlobalAnimatedMatrix);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setGlobalAnimatedMatrix(ISkinnedMesh::SJoint* j, matrix4* matrix)
	{
		if (j) {
			j->GlobalAnimatedMatrix = *matrix;
		}
	}

	// must delete
	matrix4* IrrScene_ISkinnedMesh_SJoint_getLocalAnimatedMatrix(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new matrix4(j->LocalAnimatedMatrix);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setLocalAnimatedMatrix(ISkinnedMesh::SJoint* j, matrix4* matrix)
	{
		if (j) {
			j->LocalAnimatedMatrix = *matrix;
		}
	}

	// must delete
	matrix4* IrrScene_ISkinnedMesh_SJoint_getGlobalInversedMatrix(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new matrix4(j->GlobalInversedMatrix);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setGlobalInversedMatrix(ISkinnedMesh::SJoint* j, matrix4* matrix)
	{
		if (j) {
			j->GlobalInversedMatrix = *matrix;
		}
	}

	// must delete
	vector3df* IrrScene_ISkinnedMesh_SJoint_getAnimatedposition(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new vector3df(j->Animatedposition);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setAnimatedposition(ISkinnedMesh::SJoint* j, vector3df* pos)
	{
		if (j) {
			j->Animatedposition = *pos;
		}
	}

	// must delete
	vector3df* IrrScene_ISkinnedMesh_SJoint_getAnimatedscale(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new vector3df(j->Animatedscale);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setAnimatedscale(ISkinnedMesh::SJoint* j, vector3df* scale)
	{
		if (j) {
			j->Animatedscale = *scale;
		}
	}

	// must delete
	quaternion* IrrScene_ISkinnedMesh_SJoint_getAnimatedrotation(ISkinnedMesh::SJoint* j)
	{
		if (j) {
			return new quaternion(j->Animatedrotation);
		}
	}
	
	void IrrScene_ISkinnedMesh_SJoint_setAnimatedrotation(ISkinnedMesh::SJoint* j, quaternion* rot)
	{
		if (j) {
			j->Animatedrotation = *rot;
		}
	}

	void IrrScene_ISkinnedMesh_SJoint_setPositionKeys(ISkinnedMesh::SJoint* j, ISkinnedMesh::SPositionKey** keys, u32 numKeys)
	{
		if (j) {
			j->PositionKeys.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->PositionKeys.push_back(*keys[i]);
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getPositionKeys(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j)	{			
			Irr_ptrarray_allocate(keysPtr, j->PositionKeys.size());

			for (s32 i = 0; i < j->PositionKeys.size(); i++) {
				((u32*)*keysPtr)[i]=(u32)&j->PositionKeys[i];
			}
	
			return j->PositionKeys.size();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setScaleKeys(ISkinnedMesh::SJoint* j, ISkinnedMesh::SScaleKey** keys, u32 numKeys)
	{
		if (j) {
			j->ScaleKeys.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->ScaleKeys.push_back(*keys[i]);
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getScaleKeys(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j)	{			
			Irr_ptrarray_allocate(keysPtr, j->ScaleKeys.size());

			for (s32 i = 0; i < j->ScaleKeys.size(); i++) {
				((u32*)*keysPtr)[i]=(u32)&j->ScaleKeys[i];
			}
	
			return j->ScaleKeys.size();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setRotationKeys(ISkinnedMesh::SJoint* j, ISkinnedMesh::SRotationKey** keys, u32 numKeys)
	{
		if (j) {
			j->RotationKeys.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->RotationKeys.push_back(*keys[i]);
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getRotationKeys(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j)	{			
			Irr_ptrarray_allocate(keysPtr, j->RotationKeys.size());

			for (s32 i = 0; i < j->RotationKeys.size(); i++) {
				((u32*)*keysPtr)[i]=(u32)&j->RotationKeys[i];
			}
	
			return j->RotationKeys.size();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setWeights(ISkinnedMesh::SJoint* j, ISkinnedMesh::SWeight** keys, u32 numKeys)
	{
		if (j) {
			j->Weights.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->Weights.push_back(*keys[i]);
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getWeights(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j)	{			
			Irr_ptrarray_allocate(keysPtr, j->Weights.size());

			for (s32 i = 0; i < j->Weights.size(); i++) {
				((u32*)*keysPtr)[i]=(u32)&j->Weights[i];
			}
	
			return j->Weights.size();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setChildren(ISkinnedMesh::SJoint* j, ISkinnedMesh::SJoint** keys, u32 numKeys)
	{
		if (j) {
			j->Children.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->Children.push_back(new ISkinnedMesh::SJoint(*keys[i]));
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getChildren(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j)	{			
			Irr_ptrarray_allocate(keysPtr, j->Children.size());

			for (s32 i = 0; i < j->Children.size(); i++) {
				((u32*)*keysPtr)[i]=(u32)j->Children[i];
			}
	
			return j->Children.size();
		} else return 0;
	}

	void IrrScene_ISkinnedMesh_SJoint_setAttachedMeshes(ISkinnedMesh::SJoint* j, u32* keys, u32 numKeys)
	{
		if (j) {
			j->AttachedMeshes.clear();
					
			for (int i=0; i<numKeys; i++) {	
				j->AttachedMeshes.push_back(keys[i]);
			}
		}
	}

	s32 IrrScene_ISkinnedMesh_SJoint_getAttachedMeshes(ISkinnedMesh::SJoint* j, u32** keysPtr)
	{
		if (j) {		
			*keysPtr = j->AttachedMeshes.pointer();
			return j->AttachedMeshes.size();
		} else return 0;
	}
}



