#include "..\inc\mydirect3d.h"
#include "myImage.h"
#include "myModel.h"
#include "myCamera.h"

myDirect3D* myDirect3D::m_singleton = NULL;

myDirect3D* myDirect3D::getD3D()
{
	if(m_singleton == NULL)
		m_singleton = new myDirect3D();
	return m_singleton;
}

LPDIRECT3DDEVICE9 myDirect3D::getDevice()
{
	return getD3D()->m_d3dDevice;
}

LPD3DXSPRITE myDirect3D::getSprite()
{
	return getD3D()->m_sprite;
}

myDirect3D::~myDirect3D(void)
{
	clean();
	m_singleton = NULL;
}

bool myDirect3D::init(HWND hwnd)
{
	m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if(m_d3d == NULL) return false;

	D3DPRESENT_PARAMETERS pp;
	ZeroMemory(&pp,sizeof(pp));
	pp.Windowed = TRUE;
	pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	pp.BackBufferFormat = D3DFMT_UNKNOWN;
	pp.BackBufferCount = 1;
	pp.hDeviceWindow = hwnd;

	pp.AutoDepthStencilFormat = D3DFMT_D16;
	pp.EnableAutoDepthStencil = TRUE;

	HRESULT hr;
	hr = m_d3d->CreateDevice(
		D3DADAPTER_DEFAULT,
		D3DDEVTYPE_HAL,
		hwnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&pp,
		&m_d3dDevice);
	if(FAILED(hr)) return false;

	hr = D3DXCreateSprite(m_d3dDevice,&m_sprite);
	if(FAILED(hr)) return false;

	m_camera = new myCamera();
	if(!m_camera->init()) return false;

	m_images = new myImageList();
	m_images->clear();

	m_models = new myModelList();
	m_models->clear();

	return true;
}

void myDirect3D::render()
{
	if(m_d3dDevice == NULL) return;
	m_d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0x00000000,1.0f,0);

	m_camera->useCamera();

	myDirect3D::getDevice()->BeginScene();

		myModelList::iterator m;
		for(m=m_models->begin();m!=m_models->end();m++)
			(*m)->draw();

	    myDirect3D::getSprite()->Begin(D3DXSPRITE_ALPHABLEND);

			myImageList::iterator i;
			for(i=m_images->begin();i!=m_images->end();i++)
				(*i)->draw();

		myDirect3D::getSprite()->End();
	myDirect3D::getDevice()->EndScene();

	m_d3dDevice->Present(NULL,NULL,NULL,NULL);
}

void myDirect3D::clean()
{
	if(m_camera != NULL)
	{
		delete m_camera;
		m_camera = NULL;
	}
	if(m_models != NULL)
	{
		delete m_models;
		m_models = NULL;
	}
	if(m_images != NULL)
	{
		delete m_images;
		m_images = NULL;
	}
	if(m_d3dDevice != NULL)
	{
		m_d3dDevice->Release();
		m_d3dDevice = NULL;
	}
	if(m_d3d != NULL)
	{
		m_d3d->Release();
		m_d3d = NULL;
	}	
}

void myDirect3D::setCurrentCamera(myCamera* camera)
{
	m_camera = camera;
}

myCamera* myDirect3D::getCurrentCamera()
{
	return m_camera;
}

void myDirect3D::registerImage(myImage* newImage)
{
	m_images->push_back(newImage);
}

void myDirect3D::unregisterImage(myImage* oldImage)
{
	m_images->remove(oldImage);
}

void myDirect3D::registerModel(myModel* newModel)
{
	m_models->push_back(newModel);
}

void myDirect3D::unregisterModel(myModel* oldModel)
{
	m_models->remove(oldModel);
}
void myDirect3D::rotateCameraXZ(void* data)
{
	m_camera->rotateCameraXZ(data);
}
void myDirect3D::tiltCameraY(void* data)
{
	m_camera->rotateCameraY(data);
}
myDirect3D::myDirect3D(void)
{
	m_d3d = NULL;
	m_d3dDevice = NULL;
	m_camera = NULL;
	m_images = NULL;
	m_models = NULL;
}