// Cuboid.cpp: implementation of the CCuboid class.
//
//////////////////////////////////////////////////////////////////////

#include "Cuboid.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCuboid::CCuboid(LPDIRECT3DDEVICE8 pD3DDevice)
{
	m_pD3DDevice = pD3DDevice;
	m_pVertexBuffer = NULL;

	//Set a default size and position
	m_rWidth = 10.0;
	m_rHeight = 10.0;
	m_rDepth = 10.0;
	m_rX = 0.0;
	m_rY = 0.0;
	m_rZ = 0.0;

	//Initialize Vertex Buffer
    if(SUCCEEDED(CreateVertexBuffer()))
	{
		UpdateVertices();
	}
}

CCuboid::~CCuboid()
{
	SafeRelease(m_pVertexBuffer);
}

bool CCuboid::Render()
{
	m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CUBIOD_CUSTOMVERTEX));
    m_pD3DDevice->SetVertexShader(CUBIOD_D3DFVF_CUSTOMVERTEX);
    m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);		//Top
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8);		//Sides
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2);	//Bottom

	return true;
}

HRESULT CCuboid::CreateVertexBuffer()
{
    //Create the vertex buffer from our device.
    if(FAILED(m_pD3DDevice->CreateVertexBuffer(18 * sizeof(CUBIOD_CUSTOMVERTEX),
                                               0, CUBIOD_D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT, &m_pVertexBuffer)))
    {
        return E_FAIL;
    }

    return S_OK;
}

bool CCuboid::UpdateVertices()
{
	VOID* pVertices;
    
    //Store each point of the cube together with it's colour
	//Make sure that the points of a polygon are specified in a clockwise direction,
	//this is because anti-clockwise faces will be culled
	//We will use a three triangle strips to render these polygons (Top, Sides, Bottom).
    CUBIOD_CUSTOMVERTEX cvVertices[] =
    {	
		//Top Face
		{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255),},		//Vertex 0 - Blue 
        {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 1 - Red 
        {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 2 - Red 
		{m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 3 - Green 

		//Face 1
		{m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 4 - Red 
        {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255),},		//Vertex 5 - Blue 
        {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 6 - Green 
		{m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 7 - Red 

		//Face 2
		{m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255),},		//Vertex 8 - Blue 
        {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 9 - Green
		
		//Face 3
        {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 10 - Green 
		{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 11 - Red 

		//Face 4
        {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 12 - Red 
        {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255),},		//Vertex 13 - Blue

		//Bottom Face
		{m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 14 - Green 
        {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255),},		//Vertex 15 - Blue 
        {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0),},		//Vertex 16 - Red 
		{m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0),},		//Vertex 17 - Green
    };

	//Get a pointer to the vertex buffer vertices and lock the vertex buffer
    if(FAILED(m_pVertexBuffer->Lock(0, sizeof(cvVertices), (BYTE**)&pVertices, 0)))
    {
        return false;
    }

    //Copy our stored vertices values into the vertex buffer
    memcpy(pVertices, cvVertices, sizeof(cvVertices));

    //Unlock the vertex buffer
    m_pVertexBuffer->Unlock();

	return true;
}

bool CCuboid::SetSize(float rWidth, float rHeight, float rDepth)
{
	m_rWidth = rWidth;
	m_rHeight = rHeight;
	m_rDepth = rDepth;

	UpdateVertices();

	return true;
}

bool CCuboid::SetPosition(float x, float y, float z)
{
	m_rX = x;
	m_rY = y;
	m_rZ = z;

	UpdateVertices();

	return true;
}