%module(directors="1") "IrrlichtNet"
//■警告を無視
#pragma SWIG nowarn=312
#pragma SWIG nowarn=516
%warnfilter(312) irr::scene::quake3::IQ3Shader;
%warnfilter(312) irr::IEventReceiver;
%warnfilter(312) irr::core::irrList;
%warnfilter(312) irr::core::irrMap;
%warnfilter(312) irr::scene::ISkinnedMesh;
%warnfilter(312) irr::video::SExposedVideoData;

//■C++側ラッパで必要なヘッダのインクルード
//独自定義したヘッダも入れる
%{
#include <Windows.h>
#include "Irrlicht.h"
#include "driverChoice.h"
#include "..\My.h"
#include "..\MySkinnedMesh.h"
#include "..\ISceneNode_ForInheritance.h"
#include "..\ConstStringArray.h"
#include "..\StaticStringArray.h"
#include "..\IFileReadCallBack_ForInheritance.h"
#include "..\IFileSystem_ForInheritance.h"
#include "..\IReadFile_ForInheritance.h"
#include "..\IWriteFile_ForInheritance.h"
#include "..\ISceneNodeAnimator_ForInheritance.h"

#include "..\Iterator.h"
#include "..\IGUIElement_forInheritance.h"

using namespace irr;
using namespace core;
using namespace video;
using namespace gui;
using namespace scene;
%}

//■C#側で継承するクラス
%feature("director") irr::IEventReceiver;
%feature("director") ISceneNode_ForInheritance;
%feature("director") irr::video::IShaderConstantSetCallBack;
%feature("director") irr::scene::IMeshLoader;
%feature("director") ISceneNodeAnimator_ForInheritance;
%feature("director") irr::scene::ILightManager;
%feature("director") irr::scene::IAnimationEndCallBack;
%feature("director") irr::gui::IGUIElement_ForInheritance;

//■wchar_t*をstringに変換
%include "wchar.i"
//■
%include "arrays_csharp.i"
//■
%include "carrays.i"
//■
%include "typemaps.i"
//■
%include "CustomTypemap.i"

//■wchar_t*のdirector対策
%typemap(directorout) wchar_t* %{ $result = ($1_ltype)$input; %};
%typemap(directorin) wchar_t* "$input = (wchar_t*)$1;";
%typemap(csdirectorout) wchar_t* "Marshal.StringToHGlobalUni($cscall)";
%typemap(csdirectorin) wchar_t* "Marshal.PtrToStringUni($iminput)";

//■戻り値が自前でDeleteが必要なメソッド
%newobject createDevice;
%newobject irr::createDevice;
%newobject irr::createDeviceEX;
%newobject irr::scene::ISceneManager::createRotationAnimator;
%newobject irr::scene::ISceneManager::createFlyCircleAnimator;
%newobject irr::scene::ISceneManager::createFlyStraightAnimator;
%newobject irr::scene::ISceneManager::createTextureAnimator;
%newobject irr::scene::ISceneManager::createDeleteAnimator;
%newobject irr::scene::ISceneManager::createCollisionResponseAnimator;
%newobject irr::scene::ISceneManager::createFollowSplineAnimator;
%newobject irr::scene::ISceneManager::createTriangleSelector;
%newobject irr::scene::ISceneManager::createTriangleSelectorFromBoundingBox;
%newobject irr::scene::ISceneManager::createOctreeTriangleSelector;
%newobject irr::scene::ISceneManager::createMetaTriangleSelector;
%newobject irr::scene::ISceneManager::createTerrainTriangleSelector;
%newobject irr::scene::IParticleSystemSceneNode::createAnimatedMeshSceneNodeEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createBoxEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createCylinderEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createMeshEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createPointEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createRingEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createSphereEmitter;
%newobject irr::scene::IParticleSystemSceneNode::createAttractionAffector;
%newobject irr::scene::IParticleSystemSceneNode::createScaleParticleAffector;
%newobject irr::scene::IParticleSystemSceneNode::createFadeOutParticleAffector;
%newobject irr::scene::IParticleSystemSceneNode::createGravityAffector;
%newobject irr::scene::IParticleSystemSceneNode::createRotationAffector;
%newobject irr::io::IFileArchive::createAndOpenFile;
%newobject irr::io::IArchiveLoader::createArchive;
%newobject irr::io::IFileSystem::createAndOpenFile;
%newobject irr::io::IFileSystem::createMemoryReadFile;
%newobject irr::io::IFileSystem::createLimitReadFile;
%newobject irr::io::IFileSystem::createMemoryWriteFile;
%newobject irr::io::IFileSystem::createAndWriteFile;
%newobject irr::io::IFileSystem::createFileList;
%newobject irr::io::IFileSystem::createEmptyFileList;
%newobject irr::io::IFileSystem::createXMLReader;
%newobject irr::io::IFileSystem::createXMLReaderUTF8;
%newobject irr::io::IFileSystem::createXMLWriter;
%newobject irr::io::IFileSystem::createEmptyAttributes;
%newobject irr::scene::IMeshManipulator::createMeshCopy;
%newobject irr::scene::IMeshManipulator::createMeshWithTangents;
%newobject irr::scene::IMeshManipulator::createMeshWith2TCoords;
%newobject irr::scene::IMeshManipulator::createMeshWith1TCoords;
%newobject irr::scene::IMeshManipulator::createMeshUniquePrimitives;
%newobject irr::scene::IMeshManipulator::createMeshWelded;
%newobject irr::scene::IMeshManipulator::createAnimatedMesh;
%newobject irr::video::IVedeoDriver::createImageFromFile;
%newobject irr::video::IVedeoDriver::createImageFromData;
%newobject irr::video::IVedeoDriver::createImage;
%newobject irr::video::IVedeoDriver::createAttributesFromMaterial;
%newobject irr::video::IVedeoDriver::createScreenShot;
%newobject irr::gui::IGUIEnvironment::createSkin;
%newobject irr::gui::IGUIEnvironment::createImageList;
%newobject irr::scene::IGeometryCreator::createCubeMesh;
%newobject irr::scene::IGeometryCreator::createHillPlaneMesh;
%newobject irr::scene::IGeometryCreator::createPlaneMesh;
%newobject irr::scene::IGeometryCreator::createTerrainMesh;
%newobject irr::scene::IGeometryCreator::createArrowMesh;
%newobject irr::scene::IGeometryCreator::createSphereMesh;
%newobject irr::scene::IGeometryCreator::createCylinderMesh;
%newobject irr::scene::IGeometryCreator::createConeMesh;
%newobject irr::scene::IGeometryCreator::createVolumeLightMesh;
%newobject irr::scene::IMeshLoader::IMeshLoader;
%newobject irr::io::createReadFile;
%newobject irr::io::createLimitReadFile;
%newobject irr::io::createMemoryReadFile;
%newobject irr::io::createIrrXMLReader;
%newobject irr::io::createIrrXMLReaderUTF16;
%newobject irr::io::createIrrXMLReaderUTF32;
%newobject irr::scene::ISceneNodeAnimator::createClone;
%newobject irr::scene::ISceneNodeAnimatorFactory::createSceneNodeAnimator;
%newobject irr::scene::ICeneUserDataSerializer::createUserData;
%newobject irr::io::createWriteFile;

//■C#の予約語とかぶるクラス・メソッドを名前変更
//%rename(IrrString) string;
%rename(IrrStringc) irr::core::string<char>;
%rename(IrrStringw) irr::core::string<wchar_t>;
%rename(Lock) lock;
//■operatorはラッパ化されないので別の名称に変更
%rename(equalTo) operator==;
%rename(notEqualTo) operator!=;
%rename(lessThan) operator<;
%rename(lessEqual) operator<=;
%rename(graterThan) operator>;
%rename(graterEqual) operator>=;
%rename(getItem) operator[];
%rename(add) operator+;
%rename(sub) operator-;
%rename(mul) operator*;
%rename(div) operator/;
%ignore operator=;
%ignore operator();
%ignore operator+=;
%ignore operator-=;
%ignore operator*=;
%ignore operator/=;
%ignore irr::core::array::operator==;
%ignore irr::core::array::operator!=;
%ignore irr::core::array::operator<=;
%ignore irr::core::array::operator>=;
%ignore irr::core::array::operator<;
%ignore irr::core::array::operator>;
//%ignore irr::core::array::sort;
//%ignore irr::core::array::binary_search;
//%ignore irr::core::array::binary_search_const;
//%ignore irr::core::array::linear_search;
%ignore irr::core::array::linear_search;
%ignore irr::core::array::linear_reverse_search;
//%ignore irr::core::array::erase;
//%ignore irr::core::array::binary_search_multi;

//■要素間の比較ができないのでビルドエラーになるメソッドを無効化
%ignore irr::core::array<irr::scene::quake3::SVariable>::sort;
%ignore irr::core::array<irr::scene::quake3::SVariable>::binary_search;
%ignore irr::core::array<irr::scene::quake3::SVariable>::binary_search_const;
%ignore irr::core::array<irr::scene::quake3::SVariable>::binary_search_multi;
%ignore irr::core::array<irr::scene::quake3::SVarGroup>::sort;
%ignore irr::core::array<irr::scene::quake3::SVarGroup>::binary_search;
%ignore irr::core::array<irr::scene::quake3::SVarGroup>::binary_search_const;
%ignore irr::core::array<irr::scene::quake3::SVarGroup>::binary_search_multi;
%ignore irr::core::array<irr::scene::SMD3Vertex>::sort;
%ignore irr::core::array<irr::scene::SMD3Vertex>::binary_search;
%ignore irr::core::array<irr::scene::SMD3Vertex>::binary_search_const;
%ignore irr::core::array<irr::scene::SMD3Vertex>::binary_search_multi;
%ignore irr::core::array<irr::scene::SMD3TexCoord>::sort;
%ignore irr::core::array<irr::scene::SMD3TexCoord>::binary_search;
%ignore irr::core::array<irr::scene::SMD3TexCoord>::binary_search_const;
%ignore irr::core::array<irr::scene::SMD3TexCoord>::binary_search_multi;
//%ignore irr::core::array<irr::scene::SMD3QuaterionTag>::sort;
//%ignore irr::core::array<irr::scene::SMD3QuaterionTag>::binary_search;
//%ignore irr::core::array<irr::scene::SMD3QuaterionTag>::binary_search_const;
//%ignore irr::core::array<irr::scene::SMD3QuaterionTag>::binary_search_multi;
%ignore irr::core::array<irr::gui::SGUISpriteFrame>::sort;
%ignore irr::core::array<irr::gui::SGUISpriteFrame>::binary_search;
%ignore irr::core::array<irr::gui::SGUISpriteFrame>::binary_search_const;
%ignore irr::core::array<irr::gui::SGUISpriteFrame>::binary_search_multi;
%ignore irr::core::array<MyIrrlicht::SPositionKey>::sort;
%ignore irr::core::array<MyIrrlicht::SPositionKey>::binary_search;
%ignore irr::core::array<MyIrrlicht::SPositionKey>::binary_search_const;
%ignore irr::core::array<MyIrrlicht::SPositionKey>::binary_search_multi;
%ignore irr::core::array<MyIrrlicht::SJoint>::sort;
%ignore irr::core::array<MyIrrlicht::SJoint>::binary_search;
%ignore irr::core::array<MyIrrlicht::SJoint>::binary_search_const;
%ignore irr::core::array<MyIrrlicht::SJoint>::binary_search_multi;
%ignore irr::core::array<MyIrrlicht::SRotationKey>::sort;
%ignore irr::core::array<MyIrrlicht::SRotationKey>::binary_search;
%ignore irr::core::array<MyIrrlicht::SRotationKey>::binary_search_const;
%ignore irr::core::array<MyIrrlicht::SRotationKey>::binary_search_multi;
%ignore irr::core::array<MyIrrlicht::SWeight>::sort;
%ignore irr::core::array<MyIrrlicht::SWeight>::binary_search;
%ignore irr::core::array<MyIrrlicht::SWeight>::binary_search_const;
%ignore irr::core::array<MyIrrlicht::SWeight>::binary_search_multi;
%ignore irr::core::array<MyIrrlicht::SScaleKey>::sort;
%ignore irr::core::array<MyIrrlicht::SScaleKey>::binary_search;
%ignore irr::core::array<MyIrrlicht::SScaleKey>::binary_search_const;
%ignore irr::core::array<MyIrrlicht::SScaleKey>::binary_search_multi;
%ignore irr::core::array<irr::gui::SGUISprite>::sort;
%ignore irr::core::array<irr::gui::SGUISprite>::binary_search;
%ignore irr::core::array<irr::gui::SGUISprite>::binary_search_const;
%ignore irr::core::array<irr::gui::SGUISprite>::binary_search_multi;
%ignore irr::core::array<irr::SJoystickInfo>::sort;
%ignore irr::core::array<irr::SJoystickInfo>::binary_search;
%ignore irr::core::array<irr::SJoystickInfo>::binary_search_const;
%ignore irr::core::array<irr::SJoystickInfo>::binary_search_multi;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer>::sort;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer>::binary_search;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer>::binary_search_const;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer>::binary_search_multi;
%ignore irr::core::array<irr::video::IRenderTarget>::sort;
%ignore irr::core::array<irr::video::IRenderTarget>::binary_search;
%ignore irr::core::array<irr::video::IRenderTarget>::binary_search_const;
%ignore irr::core::array<irr::video::IRenderTarget>::binary_search_multi;

%ignore irr::core::array::set_sorted;
%ignore irr::gui::IGUIElement::OnEvent;
%ignore irr::scene::ICameraSceneNode::OnEvent;
%ignore irr::scene::ISceneNodeAnimator::OnEvent;
%ignore irr::core::list::begin;
%ignore irr::core::list::end;
%ignore irr::core::list::getLast;
%ignore irr::core::list::insert_after;
%ignore irr::core::list::insert_before;
%ignore irr::core::list::erase;
%ignore irr::scene::quake3::irrEmptyStringc;
%ignore irr::scene::CIndexBuffer::Indices;
%ignore irr::scene::CVertexBuffer::CSpecificVertexList;
%ignore irr::scene::CVertexBuffer::IVertexList;
%ignore irr::scene::CVertexBuffer::Indices;
%ignore irr::scene::CIndexBuffer::IIndexList;
%ignore irr::scene::CIndexBuffer::CSpecificIndexList;

//■実装が無いため無効化
%ignore irr::io::createReadFile;
%ignore irr::io::createLimitReadFile;
%ignore irr::io::createMemoryReadFile;
%ignore irr::io::createWriteFile;

//■signed intを超える値で初期化されているenumを再定義
enum E_DEBUG_SCENE_TYPE
{
	//! No Debug Data ( Default )
	EDS_OFF = 0,

	//! Show Bounding Boxes of SceneNode
	EDS_BBOX = 1,

	//! Show Vertex Normals
	EDS_NORMALS = 2,

	//! Shows Skeleton/Tags
	EDS_SKELETON = 4,

	//! Overlays Mesh Wireframe
	EDS_MESH_WIRE_OVERLAY = 8,

	//! Temporary use transparency Material Type
	EDS_HALF_TRANSPARENCY = 16,

	//! Show Bounding Boxes of all MeshBuffers
	EDS_BBOX_BUFFERS = 32,

	//! EDS_BBOX | EDS_BBOX_BUFFERS
	EDS_BBOX_ALL = EDS_BBOX | EDS_BBOX_BUFFERS,

	//! Show all debug infos
	EDS_FULL = 0x7fffffff
};
%ignore E_DEBUG_SCENE_TYPE;


//■全クラスをpartialにする
%typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public partial class"


//■SWIGで正しく変換できないenumの初期化処理を再定義
#define CREATEID(c0,c1,c2,c3) ((c3 * 256 + c2) * 256 +c1)*256 + c0

enum EMESH_WRITER_TYPE
{
	//! Irrlicht Native mesh writer, for static .irrmesh files.
	EMWT_IRR_MESH     = CREATEID(0x69, 0x72, 0x72, 0x6D), //'i', 'r', 'r', 'm'

	//! COLLADA mesh writer for .dae and .xml files
	EMWT_COLLADA      = CREATEID(0x63, 0x6F, 0x6C, 0x6c), //'c', 'o', 'l' 'l'

	//! STL mesh writer for .stl files
	EMWT_STL          = CREATEID(0x73, 0x74, 0x6C, 0),    //'s', 't', 'l', 0

	//! OBJ mesh writer for .obj files
	EMWT_OBJ          = CREATEID(0x6F, 0x62, 0x6A, 0)     //'o', 'b', 'j', 0
};
%ignore EMESH_WRITER_TYPE;

enum ESCENE_NODE_TYPE
{
	//! simple cube scene node
	ESNT_CUBE           = CREATEID(0x63,0x75,0x62,0x65),  // 'c','u','b','e'

	//! Sphere scene node
	ESNT_SPHERE         = CREATEID(0x73,0x70,0x68,0x72),  // 's','p','h','r'

	//! Text Scene Node
	ESNT_TEXT           = CREATEID(0x74,0x65,0x78,0x74),  // 't','e','x','t'

	//! Water Surface Scene Node
	ESNT_WATER_SURFACE  = CREATEID(0x77,0x61,0x74,0x72),  // 'w','a','t','r'

	//! Terrain Scene Node
	ESNT_TERRAIN        = CREATEID(0x74,0x65,0x72,0x72),  // 't','e','r','r'

	//! Sky Box Scene Node
	ESNT_SKY_BOX        = CREATEID(0x73,0x6B,0x79,0x5F),  // 's','k','y','_'
	
	//! Sky Dome Scene Node
	ESNT_SKY_DOME       = CREATEID(0x73,0x6B,0x79,0x64),	//'s','k','y','d'

	//! Shadow Volume Scene Node
	ESNT_SHADOW_VOLUME  = CREATEID(0x73,0x68,0x64,0x77),  // 's','h','d','w'

	//! OctTree Scene Node
	ESNT_OCT_TREE       = CREATEID(0x6F,0x63,0x74,0x74),  // 'o','c','t','t'

	//! Mesh Scene Node
	ESNT_MESH           = CREATEID(0x6D,0x65,0x73,0x68),  // 'm','e','s','h'

	//! Light Scene Node
	ESNT_LIGHT          = CREATEID(0x6C,0x67,0x68,0x74),  // 'l','g','h','t'

	//! Empty Scene Node
	ESNT_EMPTY          = CREATEID(0x65,0x6D,0x74,0x79),  // 'e','m','t','y'

	//! Dummy Transformation Scene Node
	ESNT_DUMMY_TRANSFORMATION = CREATEID(0x64,0x6D,0x6D,0x79),  // 'd','m','m','y'

	//! Camera Scene Node
	ESNT_CAMERA         = CREATEID(0x63,0x61,0x6D,0x5F),  // 'c','a','m','_'

	//! Billboard Scene Node
	ESNT_BILLBOARD      = CREATEID(0x62,0x69,0x6C,0x6C),  // 'b','i','l','l'

	//! Animated Mesh Scene Node
	ESNT_ANIMATED_MESH  = CREATEID(0x61,0x6D,0x73,0x68),  // 'a','m','s','h'

	//! Particle System Scene Node
	ESNT_PARTICLE_SYSTEM = CREATEID(0x70,0x74,0x63,0x6C),  // 'p','t','c','l'

	//! Quake3 Shader Scene Node
	ESNT_Q3SHADER_SCENE_NODE  = CREATEID(0x71,0x33,0x73,0x68),	//'q','3','s','h'

	//! Quake3 Model Scene Node ( has tag to link to )
	ESNT_MD3_SCENE_NODE  = CREATEID(0x6D,0x64,0x33,0x5F),  // 'm','d','3','_'

	//! Volume Light Scene Node
	ESNT_VOLUME_LIGHT  = CREATEID(0x76,0x7F,0x6C,0x6C),	//'v','o','l','l'

	//! Maya Camera Scene Node
	//! Legacy, for loading version <= 1.4.x .irr files
	ESNT_CAMERA_MAYA    = CREATEID(0x63,0x61,0x6D,0x6D),  // 'c','a','m','M'

	//! First Person Shooter Camera
	//! Legacy, for loading version <= 1.4.x .irr files
	ESNT_CAMERA_FPS     = CREATEID(0x63,0x61,0x6D,0x46),  // 'c','a','m','F'

	//! Unknown scene node
	ESNT_UNKNOWN        = CREATEID(0x75,0x6E,0x6B,0x6E),  // 'u','n','k','n'

	//! Will match with any scene node when checking types
	ESNT_ANY            = CREATEID(0x61,0x6E,0x79,0x5F)  // 'a','n','y','_'
};
%ignore ESCENE_NODE_TYPE;

#define _MAKE_IRR_ID(c0, c1, c2, c3) ((c0) | (c1 << 8) | (c2 << 16) | (c3 << 24 ))

enum E_FILE_ARCHIVE_TYPE
{
	//! A PKZIP archive
	EFAT_ZIP     = _MAKE_IRR_ID(0x5A, 0x49, 0x50, 0),		//'Z','I','P', 0

	//! A gzip archive
	EFAT_GZIP    = _MAKE_IRR_ID(0x67, 0x7A, 0x69, 0x70),		//'g','z','i','p'

	//! A virtual directory
	EFAT_FOLDER  = _MAKE_IRR_ID(0x66, 0x6C, 0x64, 0x72),		//'f','l','d','r'

	//! An ID Software PAK archive
	EFAT_PAK     = _MAKE_IRR_ID(0x50, 0x41, 0x4B, 0),		//'P','A','K', 0

	//! A Tape ARchive
	EFAT_TAR     = _MAKE_IRR_ID(0x54, 0x41, 0x52, 0),		//'T','A','R', 0

	//! The type of this archive is unknown
	EFAT_UNKNOWN = _MAKE_IRR_ID(0x75, 0x6E, 0x6B, 0x6E)		//'u','n','k','n'
};
%ignore E_FILE_ARCHIVE_TYPE;

//■初期化が失敗するenumを再定義
enum E_TRANSFORMATION_STATE_3
{
	ETS_VIEW_PROJECTION_3 = 2 + 1,   //video::ETS_PROJECTION + 1
	ETS_VIEW_MODEL_INVERSE_3,
	ETS_CURRENT_3,
	ETS_COUNT_3
};
%ignore E_TRANSFORMATION_STATE_3;

//■dropメソッドを持つクラスならdrop()を呼び出すようにDispose()を変更
//Dispose()
%typemap(csdestruct, methodname="Dispose", methodmodifiers="public") SWIGTYPE {
    lock(this) {
      if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn)
      {
        if(WrapperObjectDisposer.IsNeedDrop(this))
        {
          WrapperObjectDisposer.Drop(this);
          swigCMemOwn = false;
        }
        else
        {
          swigCMemOwn = false;
          $imcall;
        }
      }
      swigCPtr = new HandleRef(null, IntPtr.Zero);
      GC.SuppressFinalize(this);
    }
  }
//■継承先のDispose()はベースクラスでdrop()を呼ぶ
%typemap(csdestruct_derived, methodname="Dispose", methodmodifiers="public") SWIGTYPE {
    lock(this) {
      base.Dispose();
      if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
        swigCMemOwn = false;
        //$imcall;
      }
      swigCPtr = new HandleRef(null, IntPtr.Zero);
      GC.SuppressFinalize(this);
    }
  }

// 本来のDispose()
// %typemap(csdestruct, methodname="Dispose", methodmodifiers="public") SWIGTYPE {
//     lock(this) {
//       if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
//         swigCMemOwn = false;
//         $imcall;
//       }
//       swigCPtr = new HandleRef(null, IntPtr.Zero);
//       GC.SuppressFinalize(this);
//     }
//   }
// 本来の継承先のDispose()
// %typemap(csdestruct_derived, methodname="Dispose", methodmodifiers="public") SWIGTYPE {
//     lock(this) {
//       if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
//         swigCMemOwn = false;
//         $imcall;
//       }
//       swigCPtr = new HandleRef(null, IntPtr.Zero);
//       GC.SuppressFinalize(this);
//       base.Dispose();
//     }
//   }

//■grab()、drop()は外部から呼び出せないようにする。
%csmethodmodifiers grab "internal";
%csmethodmodifiers drop "internal";

//■IReferenceCountedにisSameObjectメソッドを追加
%typemap(cscode) irr::IReferenceCounted "public bool isSameObject(IReferenceCounted obj){ return obj!=null ? swigCPtr.Handle==obj.swigCPtr.Handle : false;}"


//■キャストメソッドを追加
%define EXTEND_CAST(fromType, toType)
%extend toType {
    static toType *cast(fromType *original) {
        return (toType *)(original);
    }
};
%enddef

EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIButton );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUICheckBox );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIColorSelectDialog );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIComboBox );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIContextMenu );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIEditBox );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIFileOpenDialog );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIImage );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIInOutFader );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIListBox );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIMeshViewer );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIScrollBar );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUISpinBox );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIStaticText );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUITab );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUITabControl );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUITable );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIToolBar );
EXTEND_CAST(irr::gui::IGUIElement, irr::gui::IGUIWindow );
EXTEND_CAST(irr::scene::ISceneNodeAnimator , irr::scene::ISceneNodeAnimatorCameraFPS );
EXTEND_CAST(irr::scene::ISceneNodeAnimator , irr::scene::ISceneNodeAnimatorCameraMaya );
EXTEND_CAST(irr::scene::ISceneNodeAnimator , irr::scene::ISceneNodeAnimatorCollisionResponse );
EXTEND_CAST(irr::gui::IGUIFont , irr::gui::IGUIFontBitmap );
EXTEND_CAST(irr::scene::IParticleAffector , irr::scene::IParticleAttractionAffector );
EXTEND_CAST(irr::scene::IParticleAffector , irr::scene::IParticleFadeOutAffector );
EXTEND_CAST(irr::scene::IParticleAffector , irr::scene::IParticleGravityAffector );
EXTEND_CAST(irr::scene::IParticleAffector , irr::scene::IParticleRotationAffector );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleAnimatedMeshSceneNodeEmitter );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleBoxEmitter );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleCylinderEmitter );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleMeshEmitter );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleRingEmitter );
EXTEND_CAST(irr::scene::IParticleEmitter , irr::scene::IParticleSphereEmitter );
EXTEND_CAST(irr::scene::ISceneNode , irr::scene::IAnimatedMeshSceneNode );
EXTEND_CAST(irr::scene::ISceneNode , irr::scene::IBillboardSceneNode );
EXTEND_CAST(irr::scene::ISceneNode , irr::scene::IBillboardTextSceneNode );
EXTEND_CAST(irr::scene::IBillboardSceneNode, irr::scene::IBillboardTextSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IBoneSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::ICameraSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IDummyTransformationSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::ILightSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IMeshSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IParticleSystemSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IShadowVolumeSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::ITerrainSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::ITextSceneNode );
EXTEND_CAST(irr::scene::ISceneNode ,  irr::scene::IVolumeLightSceneNode );
EXTEND_CAST(irr::scene::IIndexBuffer , irr::scene::CIndexBuffer );
EXTEND_CAST(irr::scene::IMesh , irr::scene::IAnimatedMesh );
EXTEND_CAST(irr::scene::IMesh , irr::scene::IAnimatedMeshMD2 );
EXTEND_CAST(irr::scene::IMesh , irr::scene::IAnimatedMeshMD3 );
EXTEND_CAST(irr::scene::IMesh , irr::scene::IQ3LevelMesh );
EXTEND_CAST(irr::scene::IMesh , irr::scene::ISkinnedMesh );
EXTEND_CAST(irr::scene::IMesh , irr::scene::SAnimatedMesh );
EXTEND_CAST(irr::scene::IMesh , irr::scene::SMesh );
EXTEND_CAST(irr::scene::IAnimatedMesh , irr::scene::IAnimatedMeshMD2 );
EXTEND_CAST(irr::scene::IAnimatedMesh , irr::scene::IAnimatedMeshMD3 );
EXTEND_CAST(irr::scene::IAnimatedMesh , irr::scene::IQ3LevelMesh );
EXTEND_CAST(irr::scene::IAnimatedMesh , irr::scene::ISkinnedMesh );
EXTEND_CAST(irr::scene::IAnimatedMesh , irr::scene::SAnimatedMesh );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::CMeshBuffer<T> );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::IDynamicMeshBuffer );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::CDynamicMeshBuffer );
EXTEND_CAST(irr::scene::IDynamicMeshBuffer , irr::scene::CDynamicMeshBuffer );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::SSharedMeshBuffer );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::SSkinMeshBuffer );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::CMeshBuffer<irr::video::S3DVertex> );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::CMeshBuffer<irr::video::S3DVertex2TCoords> );
EXTEND_CAST(irr::scene::IMeshBuffer , irr::scene::CMeshBuffer<irr::video::S3DVertexTangents> );
EXTEND_CAST(irr::scene::ITriangleSelector , irr::scene::IMetaTriangleSelector );
EXTEND_CAST(irr::scene::IVertexBuffer , irr::scene::CVertexBuffer );
EXTEND_CAST(IFileReadCallBack_ForInheritance , irr::io::IFileReadCallBack );
EXTEND_CAST(irr::io::IFileSystem_ForInheritance , irr::io::IFileSystem );
EXTEND_CAST(irr::io::IReadFile_ForInheritance , irr::io::IReadFile );
EXTEND_CAST(irr::io::IWriteFile_ForInheritance , irr::io::IWriteFile );

//■コピーメソッドを追加
%define EXTEND_COPY_FROM(type)
%extend type {
    void CopyFrom(type *from) {
        *self = *from;
    }
};
%enddef

EXTEND_COPY_FROM(irr::video::SMaterial);
EXTEND_COPY_FROM(irr::video::SColor);

//■インデクサを追加
%define EXTEND_INDEXER(class, type)
%extend class{
    type getValue(unsigned int index)
    {
        return (*self)[index];
    }
    void setValue(unsigned int index, const type val)
    {
        (*self)[index] = val;
    }
};
%enddef

EXTEND_INDEXER(irr::scene::IVertexBuffer, irr::video::S3DVertex&);
EXTEND_INDEXER(irr::scene::CVertexBuffer, irr::video::S3DVertex&);
//EXTEND_INDEXER(irr::scene::SMD3QuaterionTagList, SMD3QuaterionTag&);
EXTEND_INDEXER(irr::core::array<int>, int);
EXTEND_INDEXER(irr::core::array<rectInt>, rectInt&);
EXTEND_INDEXER(irr::core::array<irr::core::stringc>, irr::core::stringc);
EXTEND_INDEXER(irr::core::array<irr::core::stringw>, irr::core::stringw);
EXTEND_INDEXER(irr::core::array<irr::core::vector3df>, irr::core::vector3df&);
EXTEND_INDEXER(irr::core::array<irr::gui::SGUISpriteFrame>, irr::gui::SGUISpriteFrame&);
EXTEND_INDEXER(irr::core::array<irr::gui::SGUISprite>, irr::gui::SGUISprite&);
EXTEND_INDEXER(irr::core::array<irr::scene::quake3::SShader>, irr::scene::quake3::SShader&);
EXTEND_INDEXER(irr::core::array<irr::scene::quake3::SVarGroup>, irr::scene::quake3::SVarGroup&);
EXTEND_INDEXER(irr::core::array<irr::scene::quake3::SVariable>, irr::scene::quake3::SVariable&);
//EXTEND_INDEXER(irr::core::array<irr::scene::SMD3QuaterionTag>, irr::scene::SMD3QuaterionTag&);
EXTEND_INDEXER(irr::core::array<irr::scene::SMD3TexCoord>, irr::scene::SMD3TexCoord&);
EXTEND_INDEXER(irr::core::array<irr::scene::SMD3Vertex>, irr::scene::SMD3Vertex&);
EXTEND_INDEXER(irr::core::array<irr::SJoystickInfo>, irr::SJoystickInfo&);
EXTEND_INDEXER(irr::core::array<irr::video::S3DVertex2TCoords>, irr::video::S3DVertex2TCoords&);
EXTEND_INDEXER(irr::core::array<irr::video::S3DVertexTangents>, irr::video::S3DVertexTangents&);
EXTEND_INDEXER(irr::core::array<irr::video::S3DVertex>, irr::video::S3DVertex&);
EXTEND_INDEXER(irr::core::array<unsigned char>, unsigned char);
EXTEND_INDEXER(irr::core::array<unsigned int>, unsigned int);
EXTEND_INDEXER(irr::core::array<unsigned short>, unsigned short);
EXTEND_INDEXER(irr::core::array<MyIrrlicht::SJoint>, MyIrrlicht::SJoint&);
EXTEND_INDEXER(irr::core::array<MyIrrlicht::SRotationKey>, MyIrrlicht::SRotationKey&);
EXTEND_INDEXER(irr::core::array<MyIrrlicht::SScaleKey>, MyIrrlicht::SScaleKey&);
EXTEND_INDEXER(irr::core::array<MyIrrlicht::SPositionKey>, MyIrrlicht::SPositionKey&);
EXTEND_INDEXER(irr::core::array<MyIrrlicht::SWeight>, MyIrrlicht::SWeight&);
EXTEND_INDEXER(irr::core::array<irr::scene::quake3::IEntity>, irr::scene::quake3::IEntity&);
EXTEND_INDEXER(irr::core::CMatrix4<float>, float);
EXTEND_INDEXER(irr::core::array<irr::video::IRenderTarget>, irr::video::IRenderTarget&);
EXTEND_INDEXER(irr::core::array<irr::core::position2di>, irr::core::position2di&);
EXTEND_INDEXER(irr::core::array<float>, float);

//インデクサを作ったことにより不要なメソッドを削除
//%ignore irr::core::array<int>::getItem;
//%ignore irr::core::array<int>::getLast;
//%ignore irr::core::array<int>::pointer;
//%ignore irr::core::array<int>::const_pointer;
//%ignore irr::core::array<unsigned int>::getItem;
//%ignore irr::core::array<unsigned int>::getLast;
//%ignore irr::core::array<unsigned int>::pointer;
//%ignore irr::core::array<unsigned int>::const_pointer;
//%ignore irr::core::array<unsigned short>::getItem;
//%ignore irr::core::array<unsigned short>::getLast;
//%ignore irr::core::array<unsigned short>::pointer;
//%ignore irr::core::array<unsigned short>::const_pointer;
//%ignore irr::core::CMatrix4<float>::getItem;

//■子要素がポインタの場合のインデクサ
%define EXTEND_POINTER_INDEXER(class, type)
%extend class{
    type getValue(unsigned int index)
    {
        return (*self)[index];
    }
    void setValue(unsigned int index, type val)
    {
        (*self)[index] = val;
    }
};
%enddef

EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::IMeshBuffer*>, irr::scene::IMeshBuffer*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::video::ITexture*>, irr::video::ITexture*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::SMD3MeshBuffer*>, irr::scene::SMD3MeshBuffer*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::IMesh*>, irr::scene::IMesh*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::ISceneNode*>, irr::scene::ISceneNode*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::SSkinMeshBuffer*>, irr::scene::SSkinMeshBuffer*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::scene::ILightSceneNode*>, irr::scene::ILightSceneNode*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::video::S3DVertex2TCoords*>, irr::video::S3DVertex2TCoords*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::video::S3DVertexTangents*>, irr::video::S3DVertexTangents*);
EXTEND_POINTER_INDEXER(irr::core::array<irr::video::S3DVertex*>, irr::video::S3DVertex*);


//■void*引数を配列にする
%ignore irr::scene::IMeshBuffer::append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices);
%extend irr::scene::IMeshBuffer {
    void append(const irr::video::S3DVertex* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
    {
        self->append((void*)vertices, numVertices, indices, numIndices);
    }
    void append(const irr::video::S3DVertex2TCoords* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
    {
        self->append((void*)vertices, numVertices, indices, numIndices);
    }
    void append(const irr::video::S3DVertexTangents* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
    {
        self->append((void*)vertices, numVertices, indices, numIndices);
    }
};

//■void*引数を配列にする
%ignore irr::video::IVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
				const void* indexList, u32 primCount,
				E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType);
%extend irr::video::IVideoDriver {
    void drawVertexPrimitiveList(const irr::video::S3DVertex* vertices, u32 vertexCount,
								const int* indexList, u32 primCount,
								irr::video::E_VERTEX_TYPE vType, irr::scene::E_PRIMITIVE_TYPE pType, 
								irr::video::E_INDEX_TYPE iType)
    {
        self->drawVertexPrimitiveList((void*)vertices, vertexCount, (void*)indexList, primCount, 
        vType, pType, iType);
    }
    void drawVertexPrimitiveList(const irr::video::S3DVertex2TCoords* vertices, u32 vertexCount,
								const int* indexList, u32 primCount,
								irr::video::E_VERTEX_TYPE vType, irr::scene::E_PRIMITIVE_TYPE pType, 
								irr::video::E_INDEX_TYPE iType)
    {
        self->drawVertexPrimitiveList((void*)vertices, vertexCount, (void*)indexList, primCount, 
        vType, pType, iType);
    }
    void drawVertexPrimitiveList(const irr::video::S3DVertexTangents* vertices, u32 vertexCount,
								const int* indexList, u32 primCount,
								irr::video::E_VERTEX_TYPE vType, irr::scene::E_PRIMITIVE_TYPE pType, 
								irr::video::E_INDEX_TYPE iType)
    {
        self->drawVertexPrimitiveList((void*)vertices, vertexCount, (void*)indexList, primCount, 
        vType, pType, iType);
    }
};

//■void*引数を配列にする
%extend irr::io::IAttributes {
    void addBinary(const c8* attributeName, unsigned char* data, s32 dataSizeInBytes)
    {
        self->addBinary(attributeName, data, dataSizeInBytes);
    }
}
%ignore irr::io::IAttributes::addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes);

//■void*引数を配列にする
%extend irr::io::IAttributes {
    void setAttribute(const c8* attributeName, unsigned char* data, s32 dataSizeInBytes )
    {
        self->setAttribute(attributeName, data, dataSizeInBytes);
    }
}
%ignore irr::io::IAttributes::setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes );

//■void*引数を配列にする
%extend irr::io::IAttributes {
    void getAttributeAsBinaryData(const c8* attributeName, unsigned char* outData, s32 maxSizeInBytes)
    {
        self->setAttribute(attributeName, outData, maxSizeInBytes);
    }
}
%ignore irr::io::IAttributes::getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes);

//■void*引数を配列にする
%extend irr::io::IAttributes {
    void getAttributeAsBinaryData(s32 index, unsigned char* outData, s32 maxSizeInBytes)
    {
        self->getAttributeAsBinaryData(index, outData, maxSizeInBytes);
    }
}
%ignore irr::io::IAttributes::getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes);

//■void*引数を配列にする
%extend irr::video::IVideoDriver {
    void createImageFromData(ECOLOR_FORMAT format,
			const core::dimension2d<u32>& size, unsigned char *data,
			bool ownForeignMemory=false,
			bool deleteMemory = true)
    {
        self->createImageFromData(format, size, data, ownForeignMemory, deleteMemory);
    }
}
%ignore irr::video::IVideoDriver::createImageFromData(ECOLOR_FORMAT format,
			const core::dimension2d<s32>& size, void *data,
			bool ownForeignMemory=false,
			bool deleteMemory = true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::IMesh*> {
    void set_pointer(irr::core::array<irr::scene::IMesh*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::IMesh*>::set_pointer(irr::scene::IMesh** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::IMeshBuffer*> {
    void set_pointer(irr::core::array<irr::scene::IMeshBuffer*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::IMeshBuffer*>::set_pointer(irr::scene::IMeshBuffer** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::ISceneNode*> {
    void set_pointer(irr::core::array<irr::scene::ISceneNode*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::ISceneNode*>::set_pointer(irr::scene::ISceneNode** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::SMD3MeshBuffer*> {
    void set_pointer(irr::core::array<irr::scene::SMD3MeshBuffer*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::SMD3MeshBuffer*>::set_pointer(irr::scene::SMD3MeshBuffer** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::video::ITexture*> {
    void set_pointer(irr::core::array<irr::video::ITexture*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::video::ITexture*>::set_pointer(irr::video::ITexture** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);

//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::SSkinMeshBuffer*> {
    void set_pointer(irr::core::array<irr::scene::SSkinMeshBuffer*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::SSkinMeshBuffer*>::set_pointer(irr::scene::SSkinMeshBuffer** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);


//■ポインタの配列をarray<T>で渡すように変更する(typemapを変更しないとINPUT[]ではポインタの配列を渡せないため)
%extend irr::core::array<irr::scene::ILightSceneNode*> {
    void set_pointer(irr::core::array<irr::scene::ILightSceneNode*>* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
    {
        self->set_pointer(newPointer->pointer(), size, _is_sorted, _free_when_destroyed);
    }
}
%ignore irr::core::array<irr::scene::ILightSceneNode*>::set_pointer(irr::scene::ILightSceneNode** newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true);


//■引数を参照渡しにする
%apply int &INOUT { int& srcFact };
%apply int &INOUT { int& dstFact };
%apply int &INOUT { int& modulo };
%apply unsigned int &INOUT { u32& alphaSource };
%apply int &INOUT { int& last};

//■enumの参照渡しを一度intに変換してから行う。
void _unpack_texureBlendFunc ( int &srcFact, int &dstFact, int &modulo, u32& alphaSource, const f32 param );
%{
void _unpack_texureBlendFunc ( int &srcFact, int &dstFact, int &modulo, u32& alphaSource, const f32 param )
{
	E_BLEND_FACTOR srcFactOrg = (E_BLEND_FACTOR)srcFact;
	E_BLEND_FACTOR dstFactOrg = (E_BLEND_FACTOR)dstFact;
	E_MODULATE_FUNC moduloOrg = (E_MODULATE_FUNC)modulo;

	irr::video::unpack_texureBlendFunc ( srcFactOrg, dstFactOrg, moduloOrg, alphaSource, param );
	
	srcFact = (int)srcFactOrg;
	dstFact = (int)dstFactOrg;
	modulo = (int)moduloOrg;
}
%}
%ignore irr::video::unpack_texureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact, E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param );


//■？
%extend irr::scene::ICameraSceneNode
{
	bool OnEvent2(const SEvent& event)
	{
		return self->OnEvent(event);
	}
}

//■void*の戻り値を型変換
%extend irr::scene::IVertexBuffer
{
	irr::video::S3DVertex2TCoords* getDataS3DVertex2TCoords();
}
%{
irr::video::S3DVertex2TCoords* irr_scene_IVertexBuffer_getDataS3DVertex2TCoords(irr::scene::IVertexBuffer* self)
{
	return (irr::video::S3DVertex2TCoords*)self->getData();
}
%}


//■void*のメンバ変数を型変換
%extend irr::SIrrlichtCreationParameters
{
	int ButtonHandle;
}
%{
int irr_SIrrlichtCreationParameters_ButtonHandle_get(irr::SIrrlichtCreationParameters* self) {
    return (int)self->WindowId;
}
void irr_SIrrlichtCreationParameters_ButtonHandle_set(irr::SIrrlichtCreationParameters* self, int val) {
    self->WindowId = (void*)val;
}
%}

//■ネストクラスなので無効化→ラッパ定義
%ignore irr::SEvent::SGUIEvent;
%ignore irr::SEvent::SMouseInput;
%ignore irr::SEvent::SKeyInput;
%ignore irr::SEvent::SJoystickEvent;
%ignore irr::SEvent::SLogEvent;
%ignore irr::SEvent::SUserEvent;
%ignore Irrlicht::SJoystickEvent::Axis;

%extend irr::SEvent
{
	struct MyIrrlicht::SGUIEvent getGUIEvent();
	struct MyIrrlicht::SMouseInput getMouseInput();
	struct MyIrrlicht::SKeyInput getKeyInput();
	struct MyIrrlicht::SJoystickEvent getJoystickEvent();
	struct MyIrrlicht::SLogEvent getLogEvent();
	struct MyIrrlicht::SUserEvent getUserEvent();
}

%{
MyIrrlicht::SGUIEvent irr_SEvent_getGUIEvent(SEvent* self)
{
	MyIrrlicht::SGUIEvent result(self);
	return result;
}

MyIrrlicht::SMouseInput irr_SEvent_getMouseInput(SEvent* self)
{
	MyIrrlicht::SMouseInput result(self);
	return result;
}

MyIrrlicht::SKeyInput irr_SEvent_getKeyInput(SEvent* self)
{
	MyIrrlicht::SKeyInput result(self);
	return result;
}

MyIrrlicht::SJoystickEvent irr_SEvent_getJoystickEvent(SEvent* self)
{
	MyIrrlicht::SJoystickEvent result(self);
	return result;
}

MyIrrlicht::SLogEvent irr_SEvent_getLogEvent(SEvent* self)
{
	MyIrrlicht::SLogEvent result(self);
	return result;
}

MyIrrlicht::SUserEvent irr_SEvent_getUserEvent(SEvent* self)
{
	MyIrrlicht::SUserEvent result(self);
	return result;
}
%}

//■ネスト構造体のため無効化→ラッパ作成
%ignore irr::scene::ISkinnedMesh::SWeight;
%ignore irr::scene::ISkinnedMesh::SPositionKey;
%ignore irr::scene::ISkinnedMesh::SScaleKey;
%ignore irr::scene::ISkinnedMesh::SRotationKey;
%ignore irr::scene::ISkinnedMesh::SJoint;
%ignore irr::scene::ISkinnedMesh::getAllJoints;
%ignore irr::scene::ISkinnedMesh::addJoint;
%ignore irr::scene::ISkinnedMesh::addWeight;
%ignore irr::scene::ISkinnedMesh::addPositionKey;
%ignore irr::scene::ISkinnedMesh::addScaleKey;
%ignore irr::scene::ISkinnedMesh::addRotationKey;
//コンストラクタには元のクラスが含まれるため無効化
%ignore MyIrrlicht::SJoint::SJoint;
%ignore MyIrrlicht::SPositionKey::SPositionKey;
%ignore MyIrrlicht::SRotationKey::SRotationKey;
%ignore MyIrrlicht::SScaleKey::SScaleKey;
%ignore MyIrrlicht::SWeight::SWeight;

%extend irr::scene::ISkinnedMesh
{
	core::array<MyIrrlicht::SJoint> getAllJoints2();
	MyIrrlicht::SJoint addJoint2(MyIrrlicht::SJoint *parent=0);
	MyIrrlicht::SWeight addWeight2(MyIrrlicht::SJoint *joint);
	MyIrrlicht::SPositionKey addPositionKey2(MyIrrlicht::SJoint *joint);
	MyIrrlicht::SScaleKey addScaleKey2(MyIrrlicht::SJoint *joint);
	MyIrrlicht::SRotationKey addRotationKey2(MyIrrlicht::SJoint *joint);
}

%{
core::array<MyIrrlicht::SJoint> irr_scene_ISkinnedMesh_getAllJoints2(ISkinnedMesh* self)
{
	core::array<ISkinnedMesh::SJoint*>& originalList = self->getAllJoints();
	core::array<MyIrrlicht::SJoint> list;
	for(int i = 0; i < originalList.size(); i++)
	{
		list.push_back(MyIrrlicht::SJoint(originalList[i]));
	}
	return list;
}

MyIrrlicht::SJoint irr_scene_ISkinnedMesh_addJoint2(ISkinnedMesh* self, MyIrrlicht::SJoint *parent=0)
{
	ISkinnedMesh::SJoint* original =  self->addJoint(parent->origin);
	MyIrrlicht::SJoint result(original);
	return result;
}
MyIrrlicht::SWeight irr_scene_ISkinnedMesh_addWeight2(ISkinnedMesh* self, MyIrrlicht::SJoint *joint)
{
	ISkinnedMesh::SWeight* original =  self->addWeight(joint->origin);
	MyIrrlicht::SWeight result(original);
	return result;
}
MyIrrlicht::SPositionKey irr_scene_ISkinnedMesh_addPositionKey2(ISkinnedMesh* self, MyIrrlicht::SJoint *joint)
{
	ISkinnedMesh::SPositionKey* original =  self->addPositionKey(joint->origin);
	MyIrrlicht::SPositionKey result(original);
	return result;
}
MyIrrlicht::SScaleKey irr_scene_ISkinnedMesh_addScaleKey2(ISkinnedMesh* self, MyIrrlicht::SJoint *joint)
{
	ISkinnedMesh::SScaleKey* original =  self->addScaleKey(joint->origin);
	MyIrrlicht::SScaleKey result(original);
	return result;
}
MyIrrlicht::SRotationKey irr_scene_ISkinnedMesh_addRotationKey2(ISkinnedMesh* self, MyIrrlicht::SJoint *joint)
{
	ISkinnedMesh::SRotationKey* original =  self->addRotationKey(joint->origin);
	MyIrrlicht::SRotationKey result(original);
	return result;
}
%}

//■配列引数の定義
%apply unsigned short INPUT[] {unsigned short* indices}
%apply unsigned short INPUT[] {unsigned short* indexList}
%apply int OUTPUT[] {int* outBegin}
%apply int OUTPUT[] {int* outEnd}
%apply int OUTPUT[] {int* outFPS}
%apply int INPUT[] {int* newPointer}
%apply float INPUT[] {const float* floats}
%apply float INPUT[] {const float* data}
%apply float OUTPUT[] {float *out}
%apply float OUTPUT[] {float *matrix}
%apply float OUTPUT[] {float *array}
%apply unsigned int INPUT[] { unsigned int* newPointer}	//領域が壊れないか要チェック
%apply unsigned short INPUT[] { unsigned short* newPointer}	//領域が壊れないか要チェック
%apply unsigned char INPUT[] {unsigned char* newPointer}	//領域が壊れないか要チェック
%apply unsigned char OUTPUT[] { unsigned char* dest}
%apply int INPUT[] { int* indexList}
%apply unsigned char INPUT[]{ unsigned char* data}
%apply unsigned char OUTPUT[] {unsigned char* outData}

//■？配列クラスの定義(INPUT[]はプリミティブ型のみなので)
%array_class(irr::SKeyMap, SKeyMapArray);
%array_class(vector3df, vector3dfArray);
%array_class(irr::video::S3DVertex, S3DVertexArray);
%array_class(irr::video::S3DVertex2TCoords, S3DVertex2TCoordsArray);
%array_class(irr::video::S3DVertexTangents, S3DVertexTangentsArray);
%array_class(irr::core::triangle3df, triangle3dfArray);

//■refの引数
%apply int &INOUT { int& outBegin };
%apply int &INOUT { int& outEnd };
%apply int &INOUT { int& outFPS };
%apply bool &INOUT { bool& outFalling };
%apply double &INOUT { double& outdistance };
%apply float &INOUT {float &angle};
%apply unsigned int *INOUT {unsigned int * MHz};
%apply unsigned int *INOUT {unsigned int * Total};
%apply unsigned int *INOUT {unsigned int * Avail};
%apply unsigned int &INOUT {unsigned int & pos};

%apply unsigned int &INOUT { unsigned int& state };
%apply unsigned int &INOUT { unsigned int& startPos };
%apply int &INOUT { int& outTriangleCount };

%apply float &INOUT { float& red };
%apply float &INOUT { float& green };
%apply float &INOUT { float& blue };
%apply float &INOUT { float& brightness };
%apply float &INOUT { float& contrast };

%apply float &INOUT { float& start};
%apply float &INOUT { float& end};
%apply float &INOUT { float& density};
%apply bool &INOUT { bool& pixelFog};
%apply bool &INOUT { bool& rangeFog};

//■引数がenumのref、out引数の場合対応
%define EnumOutParameter(typeCpp, typeCSharp, parametername)
%apply int &OUTPUT {typeCpp parametername};
%typemap(cstype) typeCpp parametername "out typeCSharp"		//C#側の引数の型
%typemap(csin) typeCpp parametername "out $csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(imtype) typeCpp parametername "out typeCSharp"		//中間ラッパの型
%typemap(ctype) typeCpp parametername "int*"			//C++側の引数の型
%enddef

%define EnumRefParameter(typeCpp, typeCSharp, parametername)
%apply int &INOUT {typeCpp parametername};
%typemap(cstype) typeCpp parametername "ref typeCSharp"		//C#側の引数の型
%typemap(csin) typeCpp parametername "ref $csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(imtype) typeCpp parametername "ref typeCSharp"		//中間ラッパの型
%typemap(ctype) typeCpp parametername "int*"			//C++側の引数の型
%enddef

EnumOutParameter(E_FOG_TYPE&, E_FOG_TYPE, fogType);


//■戻り値が配列の場合の変換
%define RETURN_POINTER_TO_ARRAY(returnType, methodName, arrayCount)
//%apply float OUTPUT[] {returnType* methodName}
%typemap(csout, excode=SWIGEXCODE) returnType * methodName
{
    IntPtr cPtr = $imcall;
    returnType [] ret = new returnType [ arrayCount ];
    int size = Marshal.SizeOf( typeof(returnType ));
    for(int i = 0; i < ret.Length; i++)
    {
        ret[i] = ( returnType )Marshal.PtrToStructure((IntPtr)((int)cPtr + size * i), typeof( returnType ));
    }
    return ret;
}
%typemap(cstype) returnType * methodName "returnType[]"
%typemap(out) returnType * methodName %{ $result = ( returnType *)$1; %} 
%enddef

RETURN_POINTER_TO_ARRAY(float, irr::core::CMatrix4<float>::pointer, 16);

/*
%typemap(cstype, out="byte[]") void * data "byte[]"
%typemap(csin) void * data "$*csclassname.getCPtr($csinput)" 
*/
//■？
%typemap(out) float * %{ $result = (float *)$1; %} 

//%typemap(cstype, out="uint") unsigned int * MHz "ref uint"
//%typemap(cstype, out="uint") unsigned int * Total "ref uint"
//%typemap(cstype, out="uint") unsigned int * Avail "ref uint"
//%typemap(cstype, out="bool") bool& outFalling "ref bool"
//%typemap(csin,
//         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);",
//         post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
//              " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
//         cshin="ref $csinput"
//        ) CDate *
//         "$csclassname.getCPtr(temp$csinput)"

//%typemap(cstype) (int (*)(int,int)) "EventHandler"
//%typemap(csin) (int (*)(int,int)) "$&csclassname.getCPtr($csinput)"

//■void*戻り値をIntPtrにする
%define VoidToIntPtr(MethodName)
%typemap(ctype) void * MethodName "void *"
%typemap(imtype) void * MethodName "IntPtr"
%typemap(cstype) void * MethodName "IntPtr"
%typemap(csout, excode=SWIGEXCODE) void * MethodName 
{
    IntPtr cPtr = $imcall;
    return cPtr;
}
%enddef
VoidToIntPtr(lock())
VoidToIntPtr(getAttributeAsUserPointer)
VoidToIntPtr(getCellData)
VoidToIntPtr(getData)


//■変数をプロパティに変換
%typemap(csin) void* WindowId "$csinput"	//C#側から中間ラッパへ渡す際の引数
//C#側で中間ラッパから受け取る変数
%typemap(csout, excode=SWIGEXCODE) void* WindowId
{
    $imcall;
}
%typemap(imtype) void * WindowId "IntPtr"
%typemap(cstype) void * WindowId "IntPtr"		//C#側の引数の型
%typemap(ctype) void * WindowId "void *"		//C++側の引数の型
%typemap(csvarin, excode=SWIGEXCODE2) void * WindowId
%{
    set {
        $imcall;
    }
%}
%typemap(csvarout, excode=SWIGEXCODE2) void * WindowId
%{
    get {
        return $imcall;$excode
    } 
%}


//■void*引数をIntPtrに変換
%typemap(csin) void* userPointer "$csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(cstype) void * userPointer "IntPtr"		//C#側の引数の型
%typemap(ctype) void * userPointer "void *"			//C++側の引数の型
%typemap(imtype) void * userPointer "IntPtr"		//中間ラッパの型


%typemap(csin) void* windowId "$csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(cstype) void * windowId "IntPtr"		//C#側の引数の型
%typemap(ctype) void * windowId "void *"			//C++側の引数の型
%typemap(imtype) void * windowId "IntPtr"		//中間ラッパの型


%typemap(csin) void* data "$csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(cstype) void * data "IntPtr"		//C#側の引数の型
%typemap(ctype) void * data "void *"			//C++側の引数の型
%typemap(imtype) void * data "IntPtr"		//中間ラッパの型

%typemap(csin) void* Window "$csinput"	//C#側から中間ラッパへ渡す際の引数
%typemap(cstype) void * Window "IntPtr"		//C#側の引数の型
%typemap(ctype) void * Window "void *"			//C++側の引数の型
%typemap(imtype) void * Window "IntPtr"		//中間ラッパの型

//■.NETのGUIイベント(KeyDownやKeyUp)→ウィンドウメッセージ変換の際に使用
char ToAsciiFromKeyCode(unsigned int keyCode);

%{
BYTE _keystate[256];
char ToAsciiFromKeyCode(unsigned int keyCode)
{
	WORD keyResult;
    GetKeyboardState(_keystate);
	int result = ToAscii(keyCode, MapVirtualKey(keyCode, 0), _keystate, &keyResult,0);
	if(result)
	{
		keyResult = keyResult & 0x00ff;
	}
	else
	{
		keyResult = 0;
	}
	return (char)keyResult;
}
%}

//■？char*メンバ変数はstringに変換されない？
%extend irr::scene::SMD3Header {
    char* _fileName;
}
%{
char* irr_scene_SMD3Header__fileName_get(irr::scene::SMD3Header* self) {
    return (char*)self->fileName;
}
void irr_scene_SMD3Header__fileName_set(irr::scene::SMD3Header* self, char* val) {
    strncpy_s(self->fileName, (char*)val, 68);
}
%}
%ignore irr::scene::SMD3Header::fileName;

//■文字列配列(char**)の引数対応
%extend irr::io::IAttributes {
    void _addEnum(const c8* attributeName, s32 enumValue, ConstStringArray* enumerationLiterals)
    {
        self->addEnum(attributeName, enumValue, enumerationLiterals->GetPointer());
    }
    void _setAttribute(const c8* attributeName, const c8* enumValue, ConstStringArray* enumerationLiterals)
    {
    	self->setAttribute(attributeName, enumValue, enumerationLiterals->GetPointer());
    }
    void _setAttribute(s32 index, const c8* enumValue, ConstStringArray* enumerationLiterals)
    {
    	self->setAttribute(index, enumValue, enumerationLiterals->GetPointer());
    }
    int _getAttributeAsEnumeration(const c8* attributeName, ConstStringArray* enumerationLiteralsToUse)
    {
    	return self->getAttributeAsEnumeration(attributeName, enumerationLiteralsToUse->GetPointer());
    }
    int _getAttributeAsEnumeration(s32 index, ConstStringArray* enumerationLiteralsToUse)
    {
        return self->getAttributeAsEnumeration(index, enumerationLiteralsToUse->GetPointer());
    }
}
%ignore irr::io::IAttributes::addEnum(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals);
%ignore irr::io::IAttributes::addEnum(const c8* attributeName, s32 enumValue, const c8* const* enumerationLiterals);
%ignore irr::io::IAttributes::setAttribute(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals);
%ignore irr::io::IAttributes::setAttribute(s32 index, const c8* enumValue, const c8* const* enumerationLiterals);
%ignore irr::io::IAttributes::getAttributeAsEnumeration(const c8* attributeName, const c8* const* enumerationLiteralsToUse);
%ignore irr::io::IAttributes::getAttributeAsEnumeration(s32 index, const c8* const* enumerationLiteralsToUse); 

//■呼び出し側でキャストする戻り値を先にキャストしておく
%define AddGetVerticesMethod(ClassName, MethodName1, MethodName2, MethodName3)
%extend ClassName {
	irr::core::array<irr::video::S3DVertex*> MethodName1()
	{
		irr::core::array<irr::video::S3DVertex*> arr;
		irr::video::S3DVertex* p = (irr::video::S3DVertex*)self->getVertices();
		for(unsigned int i = 0; i < self->getVertexCount(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
	irr::core::array<irr::video::S3DVertex2TCoords*> MethodName2()
	{
		irr::core::array<irr::video::S3DVertex2TCoords*> arr;
		irr::video::S3DVertex2TCoords* p = (irr::video::S3DVertex2TCoords*)self->getVertices();
		for(unsigned int i = 0; i < self->getVertexCount(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
	irr::core::array<irr::video::S3DVertexTangents*> MethodName3()
	{
		irr::core::array<irr::video::S3DVertexTangents*> arr;
		irr::video::S3DVertexTangents* p = (irr::video::S3DVertexTangents*)self->getVertices();
		for(unsigned int i = 0; i < self->getVertexCount(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
}
%enddef

AddGetVerticesMethod(irr::scene::IDynamicMeshBuffer, _getVerticesAsS3DVertex, _getVerticesAsS3DVertex2TCoords, _getVerticesAsS3DVertexTangents);
AddGetVerticesMethod(irr::scene::IMeshBuffer, _getVerticesAsS3DVertex, _getVerticesAsS3DVertex2TCoords, _getVerticesAsS3DVertexTangents);
AddGetVerticesMethod(irr::scene::SSharedMeshBuffer, _getVerticesAsS3DVertex, _getVerticesAsS3DVertex2TCoords, _getVerticesAsS3DVertexTangents);
AddGetVerticesMethod(irr::scene::SSkinMeshBuffer, _getVerticesAsS3DVertex, _getVerticesAsS3DVertex2TCoords, _getVerticesAsS3DVertexTangents);
%ignore irr::scene::IDynamicMeshBuffer::getVertices;
%ignore irr::scene::IMeshBuffer::getVertices;
%ignore irr::scene::SSharedMeshBuffer::getVertices;
%ignore irr::scene::SSkinMeshBuffer::getVertices; 


//■呼び出し側でキャストする戻り値を先にキャストしておく
%extend irr::scene::IVertexBuffer {
	irr::core::array<irr::video::S3DVertex*> _getDataAsS3DVertex()
	{
		irr::core::array<irr::video::S3DVertex*> arr;
		irr::video::S3DVertex* p = (irr::video::S3DVertex*)self->getData();
		for(unsigned int i = 0; i < self->size(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
	irr::core::array<irr::video::S3DVertex2TCoords*> _getDataAsS3DVertex2TCoords()
	{
		irr::core::array<irr::video::S3DVertex2TCoords*> arr;
		irr::video::S3DVertex2TCoords* p = (irr::video::S3DVertex2TCoords*)self->getData();
		for(unsigned int i = 0; i < self->size(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
	irr::core::array<irr::video::S3DVertexTangents*> _getDataAsS3DVertexTangents()
	{
		irr::core::array<irr::video::S3DVertexTangents*> arr;
		irr::video::S3DVertexTangents* p = (irr::video::S3DVertexTangents*)self->getData();
		for(unsigned int i = 0; i < self->size(); i++)
		{
			arr.push_back(p);
			p++;
		}
		return arr;
	}
}
%ignore irr::scene::IVertexBuffer::getData();


//■呼び出し側でキャストする戻り値を先にキャストしておく
%extend irr::scene::IIndexBuffer {
	irr::core::array<int> _getData()
	{
		irr::core::array<int> arr;
		int* p = (int*)self->getData();
		for(unsigned int i = 0; i < self->size(); i++)
		{
			arr.push_back(*p);
			p++;
		}
		return arr;
	}
	irr::core::array<int> _pointer()
	{
		irr::core::array<int> arr;
		int* p = (int*)self->pointer();
		for(unsigned int i = 0; i < self->size(); i++)
		{
			arr.push_back(*p);
			p++;
		}
		return arr;
	}
}
%ignore irr::scene::IIndexBuffer::getData();
%ignore irr::scene::IIndexBuffer::pointer();

//■プリミティブ型配列の戻り値をarray<T>に変換して返す
%define AddGetIndicesMethod(ClassName)
%extend ClassName {
	irr::core::array<unsigned short> _getIndices()
	{
		irr::core::array<unsigned short> arr;
		unsigned short* p = (unsigned short*)self->getIndices();
		for(unsigned int i = 0; i < self->getIndexCount(); i++)
		{
			arr.push_back(*p);
			p++;
		}
		return arr;
	}
}
%enddef
AddGetIndicesMethod(irr::scene::IDynamicMeshBuffer);
AddGetIndicesMethod(irr::scene::IMeshBuffer);
AddGetIndicesMethod(irr::scene::SSharedMeshBuffer);
AddGetIndicesMethod(irr::scene::SSkinMeshBuffer);
%ignore irr::scene::IDynamicMeshBuffer::getIndices;	// arrayUShort
%ignore irr::scene::IMeshBuffer::getIndices;			// arrayUShort
%ignore irr::scene::SSharedMeshBuffer::getIndices;	// arrayUShort
%ignore irr::scene::SSkinMeshBuffer::getIndices;		// arrayUShort

//■配列メンバ変数を変換
%define AddIndexerMathod(ClassName, Method, Type, GetMethod, SetMethod, Count)
%extend ClassName {
	Type GetMethod(int index)
	{
		if(index < 0 || Count <= index)
		{
			return 0;
		}
		return self->Method[index];
	}
	void SetMethod(int index, Type value)
	{
		if(index < 0 || Count <= index)
		{
			return;
		}
		self->Method[index] = value;
	}
}
%enddef
AddIndexerMathod(irr::scene::SMD3Face, Index, int, _getIndex, _setIndex, 3);
AddIndexerMathod(irr::scene::SMD3Vertex, position, short, _getposition, _setposition, 3);
AddIndexerMathod(irr::scene::SMD3Vertex, normal, unsigned char, _getnormal, _setnormal, 2);
%ignore irr::scene::SMD3Face::Index;					// int[3]
%ignore irr::scene::SMD3Vertex::position;				// short[3]
%ignore irr::scene::SMD3Vertex::normal;					// unsigned char[2]

//■FILE*をStreamに変換
irr::io::IrrXMLReader* _createIrrXMLReader(int handle);
%{
#include<stdio.h>
#include<io.h>
#include<stdlib.h>
#include <fcntl.h>
irr::io::IrrXMLReader* _createIrrXMLReader(int handle)
{
	int CrtFileHandle;
	FILE *stream;

	if ( (CrtFileHandle=_open_osfhandle(handle,_O_RDONLY))==-1){
		printf(  "_open_osfhandle Failed");
		return NULL;
	}
	if( (stream = _fdopen( CrtFileHandle, "r" )) == NULL ) {
		printf(  "_fdopen Failed");
		return NULL;
	}
	return irr::io::createIrrXMLReader(stream);
}
%}
%ignore irr::io::createIrrXMLReader(FILE* file);


//■C#側で継承するクラス
%feature("director") IFileReadCallBack_ForInheritance;
%ignore irr::io::IFileReadCallBack::read(void* buffer, int sizeToRead);


//■C#側で継承するクラス
%feature("director") irr::io::IFileSystem_ForInheritance;
%ignore irr::io::IFileSystem::createMemoryReadFile(void* memory, s32 len, const path& fileName, bool deleteMemoryWhenDropped=false);
%ignore irr::io::IFileSystem::createMemoryWriteFile(void* memory, s32 len, const path& fileName, bool deleteMemoryWhenDropped=false);


//■C#側で継承するクラス
%feature("director") irr::io::IReadFile_ForInheritance;
%ignore irr::io::IReadFile::read(void* buffer, u32 sizeToRead);

//■C#側で継承するクラス
%feature("director") irr::io::IWriteFile_ForInheritance;
%ignore irr::io::IWriteFile::write(const void* buffer, u32 sizeToWrite);

//■？
%ignore irr::video::sBuiltInMaterialTypeNames;
%ignore irr::video::aTextureClampNames;
%ignore irr::video::sBuiltInVertexTypeNames;
%ignore irr::scene::AutomaticCullingNames;
%ignore irr::gui::GUIAlignmentNames;
%ignore irr::gui::GUIElementTypeNames;
%ignore irr::scene::BoneAnimationModeNames;
%ignore irr::video::VERTEX_SHADER_TYPE_NAMES;
%ignore irr::video::PIXEL_SHADER_TYPE_NAMES;
%ignore irr::gui::GUIButtonStateNames;
%ignore irr::gui::GUISkinTypeNames;
%ignore irr::gui::GUISkinColorNames;
%ignore irr::gui::GUISkinSizeNames;
%ignore irr::gui::GUISkinTextNames;
%ignore irr::gui::GUISkinIconNames;
%ignore irr::gui::GUISkinFontNames;
%ignore irr::gui::GUIColumnOrderingNames;
%ignore irr::gui::GUIOrderingModeNames;
%ignore irr::video::LightTypeNames;
%ignore irr::scene::ParticleAffectorTypeNames;
%ignore irr::scene::ParticleEmitterTypeNames;
%ignore irr::video::GEOMETRY_SHADER_TYPE_NAMES;
%ignore irr::video::FogTypeNames;


//■？
%ignore ConstStringArray::ConstStringArray(char** list, int size);
%ignore ConstStringArray::ConstStringArray(const char* const* list);
%ignore ConstStringArray::ConstStringArray(char** list);
%ignore ConstStringArray::ConstStringArray(const char* const* list, int size);
%ignore ConstStringArray::GetPointer;

//■IrrlichtML用メソッドのvoid*の変換
%include "IGUIEnvironment.i"

//■list<T>のイテレータ定義
%define LIST_ITERATOR(ClassName, TemplateArg)
%extend ClassName
{
	Iterator2<ClassName, ClassName::Iterator, TemplateArg> begin()
	{
		Iterator2<ClassName, ClassName::Iterator, TemplateArg> it2(*self);
		return it2;
	}
}
%enddef


LIST_ITERATOR(irr::core::list<irr::gui::IGUIElement*>, irr::gui::IGUIElement*);
LIST_ITERATOR(irr::core::list<irr::scene::ISceneNodeAnimator*>, irr::scene::ISceneNodeAnimator*);
LIST_ITERATOR(irr::core::list<irr::scene::ISceneNode*>, irr::scene::ISceneNode*);

%include "Iterator.h"

//■使えないメソッドor使わないメソッドを無効化
%ignore irr::core::array<int>::const_pointer;
%ignore irr::core::array<int>::operator[];
%ignore irr::core::array<int>::getLast;
%ignore irr::core::array<int>::pointer;
%ignore irr::core::array<unsigned char>::const_pointer;
%ignore irr::core::array<unsigned char>::operator[];
%ignore irr::core::array<unsigned char>::getLast;
%ignore irr::core::array<unsigned char>::pointer;
%ignore irr::core::array<irr::scene::IMesh*>::const_pointer;
%ignore irr::core::array<irr::scene::IMesh*>::pointer;
%ignore irr::core::array<irr::scene::IMeshBuffer*>::const_pointer;
%ignore irr::core::array<irr::scene::IMeshBuffer*>::pointer;
%ignore irr::core::array<irr::scene::ISceneNode*>::const_pointer;
%ignore irr::core::array<irr::scene::ISceneNode*>::pointer;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer*>::const_pointer;
%ignore irr::core::array<irr::scene::SSkinMeshBuffer*>::pointer;
%ignore irr::core::array<irr::scene::SMD3MeshBuffer*>::const_pointer;
%ignore irr::core::array<irr::scene::SMD3MeshBuffer*>::pointer;
%ignore irr::core::array<irr::video::ITexture*>::const_pointer;
%ignore irr::core::array<irr::video::ITexture*>::pointer;
%ignore irr::core::array<irr::scene::ILightSceneNode*>::const_pointer;
%ignore irr::core::array<irr::scene::ILightSceneNode*>::pointer;
%ignore irr::core::array<unsigned int>::const_pointer;
%ignore irr::core::array<unsigned int>::operator[];
%ignore irr::core::array<unsigned int>::getLast;
%ignore irr::core::array<unsigned int>::pointer;
%ignore irr::core::array<unsigned int>::Last;
%ignore irr::core::array<unsigned short>::const_pointer;
%ignore irr::core::array<unsigned short>::operator[];
%ignore irr::core::array<unsigned short>::getLast;
%ignore irr::core::array<unsigned short>::pointer;
%ignore irr::core::array<unsigned short>::Last;
%ignore irr::core::CMatrix4<float>::operator[];
%ignore irr::scene::IDynamicMeshBuffer::append;
%ignore irr::video::IImage::copyToScaling;
%ignore irr::io::IIrrXMLReader<unsigned long,irr::io::IXMLBase>;
%ignore irr::io::IIrrXMLReader<unsigned short,irr::io::IXMLBase>;
%ignore irr::io::createIrrXMLReaderUTF16;
%ignore irr::io::createIrrXMLReaderUTF32;
%ignore irr::core::fast_atof_move;
%ignore irr::core::fast_atof_table;
%ignore irr::scene::quake3::getAsStringList;
%ignore irr::scene::quake3::isEqual;
%ignore irr::core::strtof10;
%ignore irr::core::strtol10;
%ignore irr::core::string<char>::operator[];
%ignore irr::core::string<wchar_t>::operator[];
%ignore MyIrrlicht::SJoint::origin;
%ignore MyIrrlicht::SWeight::origin;
%ignore irr::scene::SSharedMeshBuffer::append;
%ignore irr::scene::SSkinMeshBuffer::append;

%ignore irr::core::array<irr::video::S3DVertex*>::pointer;
%ignore irr::core::array<irr::video::S3DVertex*>::const_pointer;
%ignore irr::core::array<irr::video::S3DVertex*>::set_pointer;
%ignore irr::core::array<irr::video::S3DVertex2TCoords*>::pointer;
%ignore irr::core::array<irr::video::S3DVertex2TCoords*>::const_pointer;
%ignore irr::core::array<irr::video::S3DVertex2TCoords*>::set_pointer;
%ignore irr::core::array<irr::video::S3DVertexTangents*>::pointer;
%ignore irr::core::array<irr::video::S3DVertexTangents*>::const_pointer;
%ignore irr::core::array<irr::video::S3DVertexTangents*>::set_pointer;

%ignore irr::video::IVideoDriver::drawVertexPrimitiveList;
%ignore irr::video::IVideoDriver::draw2DVertexPrimitiveList;


//■？
IrrlichtDevice* createDevice(
	video::E_DRIVER_TYPE deviceType = video::EDT_SOFTWARE,
	// parantheses are necessary for some compilers
	const core::dimension2d<u32>& windowSize = (core::dimension2d<u32>(640,480)),
	u32 bits = 16,
	bool fullscreen = false,
	bool stencilbuffer = false,
	bool vsync = false,
	IEventReceiver* receiver = 0);

%ignore irr::createDevice;


//■引数でオブジェクトを返すパターン
struct _ResultGetCollisionPoint
{
	bool result;
	const ISceneNode* outNode;
};

%{
struct _ResultGetCollisionPoint
{
	bool result;
	const ISceneNode* outNode;
};
%}

%extend irr::scene::ISceneCollisionManager
{
	_ResultGetCollisionPoint _getCollisionPoint(const core::line3d<f32>& ray,
		ITriangleSelector* selector, core::vector3df& outCollisionPoint,
		core::triangle3df& outTriangle)
	{
		_ResultGetCollisionPoint result;
		result.result = self->getCollisionPoint(ray, selector, outCollisionPoint, 
			outTriangle, result.outNode);
		return result;
	}
}


//■配列メンバの変換
DefineCustomArray(arraySMaterialLayer, irr::video::SMaterialLayer, SMaterialLayer);
CustomArray(irr::video::SMaterialLayer TextureLayer[irr::video::MATERIAL_MAX_TEXTURES], arraySMaterialLayer, irr::video::SMaterialLayer, SMaterialLayer);

//■C#側ラッパにインデクサを追加
%define SET_ARRAY_INDEXER(arrayType, arrayCppType, itemType)
%typemap(cscode) arrayCppType
%{
        public itemType this[uint index]
        {
            get
            {
                if (index < 0 || size() < index)
                {
                    throw new System.IndexOutOfRangeException();
                }
                return getValue(index);
            }
            set
            {
                if (index < 0 || size() < index)
                {
                    throw new System.IndexOutOfRangeException();
                }
                setValue(index, value);
            }
        }
        public static implicit operator arrayType(itemType[] other)
        {
            var arr = new arrayType((uint)other.Length);
            for (uint i = 0; i < other.Length; i++)
            {
                arr.push_back(other[i]);
            }
            return arr;
        }
        public itemType[] ToArray()
        {
            var arr = new itemType[size()];
            for (uint i = 0; i < size(); i++)
            {
                arr[i] = this.getValue(i);
            }
            return arr;
        }
%}
%enddef
SET_ARRAY_INDEXER(arrayByte, irr::core::array<unsigned char>, byte);
SET_ARRAY_INDEXER(arrayInt, irr::core::array<int>, int);
SET_ARRAY_INDEXER(arrayRectInt, irr::core::array<rectInt>, recti);
SET_ARRAY_INDEXER(arrayStringc, irr::core::array<irr::core::stringc>, IrrStringc);
SET_ARRAY_INDEXER(arrayStringw, irr::core::array<irr::core::stringw>, IrrStringw);
SET_ARRAY_INDEXER(arrayVector3df, irr::core::array<irr::core::vector3df>, vector3df);
SET_ARRAY_INDEXER(arraySGUISpriteFrame, irr::core::array<irr::gui::SGUISpriteFrame>, SGUISpriteFrame);
SET_ARRAY_INDEXER(arraySGUISprite, irr::core::array<irr::gui::SGUISprite>, SGUISprite);
SET_ARRAY_INDEXER(arrayMeshBuffer, irr::core::array<irr::scene::IMeshBuffer*>, IMeshBuffer);
SET_ARRAY_INDEXER(arrayMesh, irr::core::array<irr::scene::IMesh*>, IMesh);
SET_ARRAY_INDEXER(arraySceneNode, irr::core::array<irr::scene::ISceneNode*>, ISceneNode);
SET_ARRAY_INDEXER(arrayQuake3SVarGroup, irr::core::array<irr::scene::quake3::SVarGroup>, SVarGroup);
SET_ARRAY_INDEXER(arrayQuake3SVariable, irr::core::array<irr::scene::quake3::SVariable>, SVariable);
SET_ARRAY_INDEXER(arraySMD3MeshBuffer, irr::core::array<irr::scene::SMD3MeshBuffer*>, SMD3MeshBuffer);
SET_ARRAY_INDEXER(arraySMD3TexCoord, irr::core::array<irr::scene::SMD3TexCoord>, SMD3TexCoord);
SET_ARRAY_INDEXER(arraySMD3Vertex, irr::core::array<irr::scene::SMD3Vertex>, SMD3Vertex);
SET_ARRAY_INDEXER(arraySJoystickInfo, irr::core::array<irr::SJoystickInfo>, SJoystickInfo);
SET_ARRAY_INDEXER(arrayTexture, irr::core::array<irr::video::ITexture*>, ITexture);
SET_ARRAY_INDEXER(arrayS3DVertex2TCoords, irr::core::array<irr::video::S3DVertex2TCoords>, S3DVertex2TCoords);
SET_ARRAY_INDEXER(arrayS3DVertexTangents, irr::core::array<irr::video::S3DVertexTangents>, S3DVertexTangents);
SET_ARRAY_INDEXER(arrayS3DVertex, irr::core::array<irr::video::S3DVertex>, S3DVertex);
SET_ARRAY_INDEXER(arrayUInt, irr::core::array<unsigned int>, uint);
SET_ARRAY_INDEXER(arrayUShort, irr::core::array<unsigned short>, ushort);
SET_ARRAY_INDEXER(arraySJoint, irr::core::array<MyIrrlicht::SJoint>, SJoint);
SET_ARRAY_INDEXER(arraySRotationKey, irr::core::array<MyIrrlicht::SRotationKey>, SRotationKey);
SET_ARRAY_INDEXER(arraySScaleKey, irr::core::array<MyIrrlicht::SScaleKey>, SScaleKey);
SET_ARRAY_INDEXER(arraySPositionKey, irr::core::array<MyIrrlicht::SPositionKey>, SPositionKey);
SET_ARRAY_INDEXER(arraySWeight, irr::core::array<MyIrrlicht::SWeight>, SWeight);
SET_ARRAY_INDEXER(arraySSkinMeshBuffer, irr::core::array<irr::scene::SSkinMeshBuffer*>, SSkinMeshBuffer);
SET_ARRAY_INDEXER(_arrayPS3DVertex2TCoords, irr::core::array<irr::video::S3DVertex2TCoords*>, S3DVertex2TCoords);
SET_ARRAY_INDEXER(_arrayPS3DVertexTangents, irr::core::array<irr::video::S3DVertexTangents*>, S3DVertexTangents);
SET_ARRAY_INDEXER(_arrayPS3DVertex, irr::core::array<irr::video::S3DVertex*>, S3DVertex);
SET_ARRAY_INDEXER(arrayPosition2di, irr::core::array<irr::core::position2di>, position2di);
SET_ARRAY_INDEXER(arrayLightSceneNode, irr::core::array<irr::scene::ILightSceneNode*>, ILightSceneNode);
SET_ARRAY_INDEXER(arrayRenderTarget, irr::core::array<irr::video::IRenderTarget>, IRenderTarget);
SET_ARRAY_INDEXER(arrayFloat, irr::core::array<float>, float);


%include"IrrCompileConfig.h"
%include"irrTypes.h"
%include"irrMath.h"
%include"vector3d.h"
%include"plane3d.h"
%include"line3d.h"
%include"aabbox3d.h"
%include"IReferenceCounted.h"
%include"SColor.h"
%include"dimension2d.h"
%include"vector2d.h"
%include"position2d.h"
%include"rect.h"
%include"irrAllocator.h"
%include"irrString.h"
%include"matrix4.h"
%include"heapsort.h"
%include"irrArray.h"
%include"EMaterialTypes.h"
%include"EMaterialFlags.h"
%include"SMaterialLayer.h"
%include"SMaterial.h"
%include"S3DVertex.h"
%include"SVertexIndex.h"
%include"EHardwareBufferFlags.h"
%include"EPrimitiveTypes.h"
%include"IMeshBuffer.h"
%include"IVertexBuffer.h"
%include"IIndexBuffer.h"
%include"IDynamicMeshBuffer.h"
%include"CVertexBuffer.h"
%include"CIndexBuffer.h"
%include"CDynamicMeshBuffer.h"
%include"CMeshBuffer.h"
%include"path.h"
%include"coreutil.h"
%include"EDriverTypes.h"
%include"driverChoice.h"
%include"EAttributes.h"
%include"ECullingTypes.h"
%include"EDebugSceneTypes.h"
%include"EDeviceTypes.h"
%include"EDriverFeatures.h"
%include"EGUIAlignment.h"
%include"EGUIElementTypes.h"
%include"EMeshWriterEnums.h"
%include"EMessageBoxFlags.h"
%include"ESceneNodeAnimatorTypes.h"
%include"ESceneNodeTypes.h"
%include"EShaderTypes.h"
%include"ETerrainElements.h"
%include"fast_atof.h"
%include"IMesh.h"
%include"IAnimatedMesh.h"
%include"IAnimatedMeshMD2.h"
%include"irrXML.h"
%include"IXMLReader.h"
%include"IReadFile.h"
%include"IFileList.h"
%include"IFileArchive.h"
%include"IFileSystem.h"
%include"IImage.h"
%include"ITexture.h"
%include"triangle3d.h"
%include"SExposedVideoData.h"
%include"IVideoDriver.h"
%include"IQ3Shader.h"
%include"quaternion.h"
%include"IAnimatedMeshMD3.h"
%include"IAttributeExchangingObject.h"
%include"ILogger.h"
%include"Keycodes.h"
%include"IEventReceiver.h"
%include"ISceneNodeAnimator.h"
%include"ITriangleSelector.h"
%include"irrList.h"
%include"line2d.h"
%include"IAttributes.h"
%include"ISceneNode.h"
%include"IBoneSceneNode.h"
%include"IAnimatedMeshSceneNode.h"
%include"IBillboardSceneNode.h"
%include"IBillboardTextSceneNode.h"
%include"ICameraSceneNode.h"
%include"ICursorControl.h"
%include"IDummyTransformationSceneNode.h"
%include"IGeometryCreator.h"
%include"IGPUProgrammingServices.h"
%include"IGUIElement.h"
%include"IGUIButton.h"
%include"IGUICheckBox.h"
%include"IGUIColorSelectDialog.h"
%include"IGUIComboBox.h"
%include"IGUIContextMenu.h"
%include"IGUIEditBox.h"
%include"IGUIElementFactory.h"
%include"IGUISkin.h"
%include"IGUIEnvironment.h"
%include"IGUIFileOpenDialog.h"
%include"IGUIFont.h"
%include"IGUIFontBitmap.h"
%include"IGUIImage.h"
%include"IGUIImageList.h"
%include"IGUIInOutFader.h"
%include"IGUIListBox.h"
%include"IGUIMeshViewer.h"
%include"IGUIScrollBar.h"
%include"IGUISpinBox.h"
%include"IGUISpriteBank.h"
%include"IGUIStaticText.h"
%include"IGUITabControl.h"
%include"IGUITable.h"
%include"IGUIToolbar.h"
%include"IGUITreeView.h"
%include"IGUIWindow.h"
%include"IImageLoader.h"
%include"IImageWriter.h"
%include"ILightManager.h"
%include"SLight.h"
%include"ILightSceneNode.h"
%include"IMaterialRenderer.h"
%include"IMaterialRendererServices.h"
%include"IMeshCache.h"
%include"IMeshLoader.h"
%include"SVertexManipulator.h"
%include"IMeshManipulator.h"
%include"IMeshSceneNode.h"
%include"IMeshWriter.h"
%include"IMetaTriangleSelector.h"
%include"IOSOperator.h"
%include"SParticle.h"
%include"IParticleAffector.h"
%include"IParticleEmitter.h"
%include"IParticleAnimatedMeshSceneNodeEmitter.h"
%include"IParticleAttractionAffector.h"
%include"IParticleBoxEmitter.h"
%include"IParticleCylinderEmitter.h"
%include"IParticleFadeOutAffector.h"
%include"IParticleGravityAffector.h"
%include"IParticleMeshEmitter.h"
%include"IParticleRingEmitter.h"
%include"IParticleRotationAffector.h"
%include"IParticleSphereEmitter.h"
%include"IParticleSystemSceneNode.h"
%include"IQ3LevelMesh.h"
%include"IVideoModeList.h"
%include"ITimer.h"
%include"IrrlichtDevice.h"
%include"irrMap.h"
%include"ISceneCollisionManager.h"
%include"SceneParameters.h"
%include"SSkinMeshBuffer.h"
%include"ISkinnedMesh.h"
%include"ISceneManager.h"
%include"ISceneNodeAnimatorCameraFPS.h"
%include"ISceneNodeAnimatorCameraMaya.h"
%include"ISceneNodeAnimatorCollisionResponse.h"
%include"ISceneNodeAnimatorFactory.h"
%include"ISceneNodeFactory.h"
%include"ISceneUserDataSerializer.h"
%include"IShaderConstantSetCallBack.h"
%include"IShadowVolumeSceneNode.h"
%include"ITerrainSceneNode.h"
%include"ITextSceneNode.h"
%include"IVolumeLightSceneNode.h"
%include"IWriteFile.h"
%include"IXMLWriter.h"
%include"SAnimatedMesh.h"
%include"SIrrCreationParameters.h"
%include"SKeyMap.h"
%include"SMesh.h"
%include"SMeshBuffer.h"
%include"SMeshBufferLightMap.h"
%include"SMeshBufferTangents.h"
%include"SSharedMeshBuffer.h"
%include"SViewFrustum.h"
%include"irrlicht.h"


%include "my.h"
%include "MySkinnedMesh.h"
%include "ISceneNode_ForInheritance.h"
%include "ConstStringArray.h"
%include "StaticStringArray.h"
%include "IFileReadCallBack_ForInheritance.h"
%include "IReadFile_ForInheritance.h"
%include "IWriteFile_ForInheritance.h"
%include "IFileSystem_ForInheritance.h"
%include "IGUIElement_ForInheritance.h"

//■テンプレートを展開
%template(aabbox3df) irr::core::aabbox3d<float>;
%template(arrayInt) irr::core::array<int>;
%template(arrayRectInt) irr::core::array<rectInt>;
%template(arrayStringc) irr::core::array<irr::core::stringc>;
%template(arrayStringw) irr::core::array<irr::core::stringw>;
%template(arrayVector3df) irr::core::array<irr::core::vector3df>;
%template(arraySGUISpriteFrame) irr::core::array<irr::gui::SGUISpriteFrame>;
%template(arraySGUISprite) irr::core::array<irr::gui::SGUISprite>;
%template(arrayMeshBuffer) irr::core::array<irr::scene::IMeshBuffer*>;
%template(arrayMesh) irr::core::array<irr::scene::IMesh*>;
%template(arraySceneNode) irr::core::array<irr::scene::ISceneNode*>;
//%template(arraySkinnedMeshSjoint) irr::core::array<irr::scene::ISkinnedMesh::SJoint*>;
//%template(arraySkinnedMeshSPositionKey) irr::core::array<irr::scene::ISkinnedMesh::SPositionKey>;
//%template(arraySkinnedMeshSRotationKey) irr::core::array<irr::scene::ISkinnedMesh::SRotationKey>;
//%template(arraySkinnedMeshSScaleKey) irr::core::array<irr::scene::ISkinnedMesh::SScaleKey>;
//%template(arraySkinnedMeshSWeight) irr::core::array<irr::scene::ISkinnedMesh::SWeight>;
//%template(arrayQuake3SShader) irr::core::array<irr::scene::quake3::SShader>;
%template(arrayQuake3SVarGroup) irr::core::array<irr::scene::quake3::SVarGroup>;
%template(arrayQuake3SVariable) irr::core::array<irr::scene::quake3::SVariable>;
%template(arraySMD3MeshBuffer) irr::core::array<irr::scene::SMD3MeshBuffer*>;
//%template(arraySMD3QuaterionTag) irr::core::array<irr::scene::SMD3QuaterionTag>;
%template(arraySMD3TexCoord) irr::core::array<irr::scene::SMD3TexCoord>;
%template(arraySMD3Vertex) irr::core::array<irr::scene::SMD3Vertex>;
%template(arraySJoystickInfo) irr::core::array<irr::SJoystickInfo>;
%template(arrayTexture) irr::core::array<irr::video::ITexture*>;
%template(arrayS3DVertex2TCoords) irr::core::array<irr::video::S3DVertex2TCoords>;
%template(arrayS3DVertexTangents) irr::core::array<irr::video::S3DVertexTangents>;
%template(arrayS3DVertex) irr::core::array<irr::video::S3DVertex>;
%template(arrayUInt) irr::core::array<unsigned int>;
%template(arrayUShort) irr::core::array<unsigned short>;
%template(arraySJoint) irr::core::array<MyIrrlicht::SJoint>;
%template(arraySRotationKey) irr::core::array<MyIrrlicht::SRotationKey>;
%template(arraySScaleKey) irr::core::array<MyIrrlicht::SScaleKey>;
%template(arraySPositionKey) irr::core::array<MyIrrlicht::SPositionKey>;
%template(arraySWeight) irr::core::array<MyIrrlicht::SWeight>;
%template(arraySSkinMeshBuffer) irr::core::array<irr::scene::SSkinMeshBuffer*>;
%template(CMatrix4f) irr::core::CMatrix4<float>;
%template(dimension2df) irr::core::dimension2d<float>;
%template(dimension2di) irr::core::dimension2d<int>;
%template(dimension2dui) irr::core::dimension2d<unsigned int>;
%template(line2df) irr::core::line2d<float>;
%template(line3df) irr::core::line3d<float>;
%template(listGUIElement) irr::core::list<irr::gui::IGUIElement*>;
%template(listSceneNodeAnimator) irr::core::list<irr::scene::ISceneNodeAnimator*>;
%template(listSceneNode) irr::core::list<irr::scene::ISceneNode*>;
%template(plane3df) irr::core::plane3d<float>;
%template(position2df) irr::core::position2d<float>;
%template(position2di) irr::core::position2d<int>;
%template(rectf) irr::core::rect<float>;
%template(recti) irr::core::rect<int>;
//%template(IrrStringc) irr::core::string<char>;
//%template(IrrStringw) irr::core::string<wchar_t>;
%template(triangle3df) irr::core::triangle3d<float>;
%template(vector2df) irr::core::vector2d<float>;
%template(vector2du) irr::core::vector2d<unsigned int>;
%template(vector3df) irr::core::vector3d<float>;
%template(IIrrXMLReaderCXMLBase) irr::io::IIrrXMLReader<char,irr::io::IXMLBase>;
%template(IIrrXMLReaderCReferenceCounted) irr::io::IIrrXMLReader<char,irr::IReferenceCounted>;
%template(IIrrXMLReaderLXMLBase) irr::io::IIrrXMLReader<unsigned long,irr::io::IXMLBase>;
%template(IIrrXMLReaderUSXMLBase) irr::io::IIrrXMLReader<unsigned short,irr::io::IXMLBase>;
%template(IIrrXMLReaderReferenceCounted) irr::io::IIrrXMLReader<wchar_t, irr::IReferenceCounted>;
//%template(IrrXMLReader) irr::io::IIrrXMLReader<char,irr::io::IXMLBase>;
//%template(IXMLReaderUTF8) irr::io::IIrrXMLReader<char,irr::IReferenceCounted>;
//%template(IrrXMLReaderUTF32) irr::io::IIrrXMLReader<unsigned long,irr::io::IXMLBase>;
//%template(IrrXMLReaderUTF16) irr::io::IIrrXMLReader<wchar_t,irr::io::IXMLBase>;
//%template(IXMLReaderWChar) irr::io::IIrrXMLReader<wchar_t, irr::IReferenceCounted>;
%template(_arrayPS3DVertex2TCoords) irr::core::array<irr::video::S3DVertex2TCoords*>;
%template(_arrayPS3DVertexTangents) irr::core::array<irr::video::S3DVertexTangents*>;
%template(_arrayPS3DVertex) irr::core::array<irr::video::S3DVertex*>;
%template(arrayByte) irr::core::array<unsigned char>;
%template(SMeshBuffer) irr::scene::CMeshBuffer<irr::video::S3DVertex>;
%template(SMeshBufferLightMap) irr::scene::CMeshBuffer<irr::video::S3DVertex2TCoords>;
%template(SMeshBufferTangents) irr::scene::CMeshBuffer<irr::video::S3DVertexTangents>;
%template(arrayPosition2di) irr::core::array<irr::core::position2di>;
%template(arrayLightSceneNode) irr::core::array<irr::scene::ILightSceneNode*>;
%template(tQ3EntityList) irr::core::array<irr::scene::quake3::IEntity>;
%template(arrayRenderTarget) irr::core::array<irr::video::IRenderTarget>;
%template(arrayFloat) irr::core::array<float>;

%template(IteratorGUIElement) Iterator2< irr::core::list<irr::gui::IGUIElement*>, irr::core::list<irr::gui::IGUIElement*>::Iterator, irr::gui::IGUIElement* >;
%template(IteratorSceneNodeAnimator) Iterator2< irr::core::list<irr::scene::ISceneNodeAnimator*>, irr::core::list<irr::scene::ISceneNodeAnimator*>::Iterator, irr::scene::ISceneNodeAnimator* >;
%template(IteratorSceneNode) Iterator2< irr::core::list<irr::scene::ISceneNode*>, irr::core::list<irr::scene::ISceneNode*>::Iterator,irr::scene::ISceneNode*>;

%extend irr::core::string<char>
{
public:
	static irr::core::string<char>* Factory(const char* const c){return new irr::core::string<char>(c);}
}
%extend irr::core::string<wchar_t>
{
public:
	static irr::core::string<wchar_t>* Factory(const wchar_t* const c){return new irr::core::string<wchar_t>(c);}
}

%nodefault;

namespace irr
{
namespace core
{

class string<char>
{
public:
//	string<char>();
//	string(const stringc& other);
//	explicit string(const double number);
//	explicit string(int number);
//	explicit string(unsigned int number);
//	string(const char* const c, u32 length);
//	string(const char* const c);
	~string();
	stringc& operator=(const stringc& other);
	stringc& operator=(const char* const c);
	stringc operator+(const stringc& other) const;
	stringc operator+(const char* const c) const;
	char& operator [](const u32 index);
	const char& operator [](const u32 index) const;
	bool operator ==(const char* const str) const;
	bool operator ==(const stringc& other) const;
	bool operator <(const stringc& other) const;
	bool operator !=(const char* const str) const;
	bool operator !=(const stringc& other) const;
	u32 size() const;
	const char* c_str() const;
	void make_lower();
	void make_upper();
	bool equals_ignore_case(const stringc& other) const;
	bool lower_ignore_case(const stringc& other) const;
	bool equalsn(const stringc& other, u32 n) const;
	bool equalsn(const char* const str, u32 n) const;
	void append(char character);
	void append(const char* const other);
	void append(const stringc& other);
	void append(const stringc& other, u32 length);
	void reserve(u32 count);
	s32 findFirst(char c) const;
	s32 findFirstChar(const char* const c, u32 count) const;
	s32 findFirstCharNotInList(const char* const c, u32 count) const;
	s32 findLastCharNotInList(const char* const c, u32 count) const;
	s32 findNext(char c, u32 startPos) const;
	s32 findLast(char c, s32 start = -1) const;
	s32 findLastChar(const char* const c, u32 count) const;
	s32 find(const char* const str) const;
	stringc subString(u32 begin, s32 length) const;
	stringc& operator += (char c);
	stringc& operator += (const char* const c);
	stringc& operator += (const stringc& other);
	stringc& operator += (const int i);
	stringc& operator += (const unsigned int i);
	stringc& operator += (const long i);
	stringc& operator += (const unsigned long& i);
	stringc& operator += (const double i);

	stringc& operator += (const float i);
	void replace(char toReplace, char replaceWith);
	stringc& trim(const stringc & whitespace = " \t\n\r");
	void erase(u32 index);

};


class irr::core::string<wchar_t>
{
public:
//	string();
//	string(const stringw& other);
//	explicit string(const double number);
//	explicit string(int number);
//	explicit string(unsigned int number);
//	string(const wchar_t* const c, u32 length);
//	string(const wchar_t* const c);
	~string();
	stringw& operator=(const stringw& other);
	stringw& operator=(const wchar_t* const c);
	stringw operator+(const stringw& other) const;
	stringw operator+(const wchar_t* const c) const;
	wchar_t& operator [](const u32 index);
	const wchar_t& operator [](const u32 index) const;
	bool operator ==(const wchar_t* const str) const;
	bool operator ==(const stringw& other) const;
	bool operator <(const stringw& other) const;
	bool operator !=(const wchar_t* const str) const;
	bool operator !=(const stringw& other) const;
	u32 size() const;
	const wchar_t* c_str() const;
	void make_lower();
	void make_upper();
	bool equals_ignore_case(const stringw& other) const;
	bool lower_ignore_case(const stringw& other) const;
	bool equalsn(const stringw& other, u32 n) const;
	bool equalsn(const wchar_t* const str, u32 n) const;
	void append(wchar_t character);
	void append(const wchar_t* const other);
	void append(const stringw& other);
	void append(const stringw& other, u32 length);
	void reserve(u32 count);
	s32 findFirst(wchar_t c) const;
	s32 findFirstChar(const wchar_t* const c, u32 count) const;
	s32 findFirstCharNotInList(const wchar_t* const c, u32 count) const;
	s32 findLastCharNotInList(const wchar_t* const c, u32 count) const;
	s32 findNext(wchar_t c, u32 startPos) const;
	s32 findLast(wchar_t c, s32 start = -1) const;
	s32 findLastChar(const wchar_t* const c, u32 count) const;
	s32 find(const wchar_t* const str) const;
	stringw subString(u32 begin, s32 length) const;
	stringw& operator += (wchar_t c);
	stringw& operator += (const wchar_t* const c);
	stringw& operator += (const stringw& other);
	stringw& operator += (const int i);
	stringw& operator += (const unsigned int i);
	stringw& operator += (const long i);
	stringw& operator += (const unsigned long& i);
	stringw& operator += (const double i);

	stringw& operator += (const float i);
	void replace(wchar_t toReplace, wchar_t replaceWith);
	stringw& trim(const stringw & whitespace = " \t\n\r");
	void erase(u32 index);

};


}
}