#include "Destiny3D.hpp"
#include "deBitmap.hpp"
#include "deAnimatedMesh.hpp"
#include "deSurface.hpp"
#include "deRenderStates.hpp"
#include "deScene.hpp"
#include "deResource.hpp"
#include "deRender.hpp"
#include "deWorld.hpp"
#include "de2D.hpp"
#include "deFont.hpp"
#include "deFile.hpp"
#include "deFileSystem.hpp"
#include "deDriver.hpp"
#include "dePlugins.hpp"
#include "deCamera.hpp"
#include "dePortal.hpp"
#include "deMesh.hpp"

class Destiny3DFactory : public IDestiny3DFactory
{
	friend IDestiny3DFactory* Destiny3D_GetFactory();
	static Destiny3DFactory* s_pFactory;
public:
	Destiny3DFactory() { s_pFactory = this; }
	~Destiny3DFactory() { s_pFactory = NULL; }
	void				ShutDown() { delete this; Destiny3D_ShutDown(); }
	
	// interface queries
	long				GetIdeBitmapRscInterfaceID() {return IdeBitmap_GetRscInterfaceID();}
	long				GetIdeBitmapProxyWOInterfaceID() {return IdeBitmapProxy_GetWOInterfaceID();}
	long				GetIdeAnimatedMeshRscInterfaceID() {return IdeAnimatedMesh_GetRscInterfaceID();}
	long				GetIdeSurfaceWOInterfaceID() {return IdeSurface_GetWOInterfaceID();}
	long				GetIdeRenderStateWOInterfaceID() {return IdeRenderState_GetWOInterfaceID();}
	long				GetIdeSceneRoomWOInterfaceID() {return IdeSceneRoom_GetWOInterfaceID();}
	long				GetIdeSceneObjectWOInterfaceID() {return IdeSceneObject_GetWOInterfaceID();}
	long				GetIdeMeshWOInterfaceID() {return IdeMesh_GetWOInterfaceID();}
	
	// singletons
	IdeResourceManager*	GetIdeResourceManager() {return IdeResourceManager_GetManager();}
	IdeRender*			GetIdeRender() {return IdeRender_GetPtr();}
	IdeSceneGraph*		GetIdeSceneGraph() {return IdeSceneGraph_GetSceneGraphPtr();}
	IdeWorldManager*	GetIdeWorldManager() {return IdeWorld_GetManager();}
	IdeThreadPool*		GetIdeThreadPool(u32 minThreadCount) {return IdeThreadPool_GetPtr(minThreadCount);}

	// creators
	Ide2DCollection*	CreateIde2DCollection() {return Ide2DObject_Create2DCollection();}
	IdeFont*			CreateIdeFont() {return IdeFont_CreateFont();}
	IdeBitmap*			CreateIdeBitmap() {return IdeBitmap_CreateBitmap();}
	IdeBitmap*			CreateIdeBitmapWithInfo(s32 Width, s32 Height, IdeDriver::BPP Format, deBoolean CubeMap)
							{return IdeBitmap_CreateBitmapWithInfo(Width, Height, Format, CubeMap);}
	IdeBitmapProxy*		CreateIdeBitmapProxy(IdeResourceBase* FromBitmap) {return IdeBitmap_CreateProxy(FromBitmap);}
	IdeMesh*			CreateIdeMesh() {return IdeMesh_CreateMesh();}
	IdeDriverLoad*		CreateIdeDriverLoad(char const * path) {return IdeDriverLoad_CreateDriverLoad(path);}
	IdeVertexBuffer*	CreateIdeVertexBuffer() {return IdeVertexBuffer_CreateVBuffer();}
	IdeSurface*			CreateIdeSurface() {return IdeSurface_CreateSurface();}
	IdeRenderTexture*	CreateIdeRenderTexture() {return IdeRenderState_CreateRenderTexture();}
	IdeRenderMaterial*	CreateIdeRenderMaterial() {return IdeRenderState_CreateRenderMaterial();}
	IdeRenderLight*		CreateIdeRenderLight() {return IdeRenderState_CreateRenderLight();}
	IdeFileMemory*		CreateIdeFileMemory() {return IdeFile_CreateFileMemory();}
	IdeFilePlugin*		CreateIdeFilePlugin() {return IdeFile_CreateFilePlugin();}
	IdeFSReal*			CreateIdeFSReal() {return IdeFileSystem_CreateFSReal();}
	IdeFSVirtual*		CreateIdeFSVirtual() {return IdeFileSystem_CreateFSVirtual();}
	IdePluginTwofish*	CreateIdePluginTwofish() {return IdePlugin_CreateTwofish();}
	IdePluginRijndael*	CreateIdePluginRijndael() {return IdePlugin_CreateRijndael();}
	IdePluginZLib*		CreateIdePluginZLib() {return IdePlugin_CreateZLib();}
	IdePluginSHA1*		CreateIdePluginSHA1() {return IdePlugin_CreateSHA1();}
	IdeCamera*			CreateIdeCamera() {return IdeCamera_CreateCamera();}
	IdePlaneFrustum*	CreateIdePlaneFrustum() {return IdeFrustum_CreatePlaneFrustum();}
	IdePortal*			CreateIdePortal() {return IdePortal_CreatePortal();}
	IdeCollision*		CreateIdeCollision() {return IdeCollision_CreateCollision();}
	IdeSceneRoom*		CreateIdeSceneRoom() {return IdeSceneRoom_CreateRoom();}
	IdeSceneABT *		CreateIdeSceneABT() {return IdeSceneObject_CreateSceneABT();}
	IdeSceneActor*		CreateIdeSceneActor() {return IdeSceneObject_CreateSceneActor();}
	IdeSceneSky *		CreateIdeSceneSky() {return IdeSceneObject_CreateSceneSky();}
	IdeSceneStaticMesh*	CreateIdeSceneStaticMesh() {return IdeSceneObject_CreateSceneStaticMesh();}
	IdeSceneTerrain*	CreateIdeSceneTerrain() {return IdeSceneObject_CreateSceneTerrain();}
	IdeSceneLight*		CreateIdeSceneLight() {return IdeSceneObject_CreateSceneLight();}
	IdeThread*			CreateIdeThread(IdeThread::ThreadProc threadProc) {return IdeThread_CreateThread(threadProc);}
	IdeThreadLock*		CreateIdeThreadLock(u32 spinCount) {return IdeThreadLock_CreateThreadLock(spinCount);}
};

Destiny3DFactory* Destiny3DFactory::s_pFactory = NULL;

IDestiny3DFactory* Destiny3D_GetFactory()
{
	if (NULL != Destiny3DFactory::s_pFactory)
		return Destiny3DFactory::s_pFactory;

	if (!Destiny3D_Init(NULL))
	{
		Destiny3D_ShutDown();
		DEBUGRETURN(NULL, "Destiny3D_GetFactory: Destiny3D_Init() failed");
	}

	Destiny3DFactory::s_pFactory = new Destiny3DFactory;
	if (NULL == Destiny3DFactory::s_pFactory)
	{
		Destiny3D_ShutDown();
		DEBUGRETURN(NULL, "Destiny3D_GetFactory: failed to create Destiny3DFactory");
	}
	
	return Destiny3DFactory::s_pFactory;
}
