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

#include "Cuboid.h"

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

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

	//Set a default size and position
	m_rWidth = 20.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_pTexture);
	SafeRelease(m_pVertexBuffer);
}

bool CCuboid::Render()
{
	m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CUBIOD_CUSTOMVERTEX));
    m_pD3DDevice->SetVertexShader(CUBIOD_D3DFVF_CUSTOMVERTEX);

	//Set how the texture should be rendered.
	if(m_pTexture != NULL)
	{
		//A texture has been set. We don't want to blend our texture with
		//the colours of our vertices, so use D3DTOP_SELECTARG1
        m_pD3DDevice->SetTexture(0, m_pTexture);
		m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    }
	else
	{
		//No texture has been set. So we will disable texture rendering.
		m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
	}

    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;
}

bool CCuboid::Render_2()
{
	m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CUBIOD_CUSTOMVERTEX));
    m_pD3DDevice->SetVertexShader(CUBIOD_D3DFVF_CUSTOMVERTEX);

	//Set how the texture should be rendered.
	if(m_pTexture != NULL)
	{
		//A texture has been set. We don't want to blend our texture with
		//the colours of our vertices, so use D3DTOP_SELECTARG1
        m_pD3DDevice->SetTexture(0, m_pTexture);
		m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    }
	else
	{
		//No texture has been set. So we will disable texture rendering.
		m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
	}

    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 and texture coordinates
	//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), 0.0f, 1.0f,},		//Vertex 0 - Blue 
			{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0), 0.0f, 0.0f,},		//Vertex 1 - Red 
			{m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0), 1.0f, 1.0f,},		//Vertex 2 - Red 
			{m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f,},		//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), 0.0f, 1.0f,},		//Vertex 4 - Red 
			{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255), 0.0f, 0.0f,},		//Vertex 5 - Blue 
			{m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0), 1.0f, 1.0f,},		//Vertex 6 - Green 
			{m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0), 1.0f, 0.0f,},		//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), 0.0f, 1.0f,},		//Vertex 8 - Blue 
		   {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0), 0.0f, 0.0f,},		//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), 1.0f, 1.0f,},		//Vertex 10 - Green 
			{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0), 1.0f, 0.0f,},		//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), 0.0f, 1.0f,},		//Vertex 12 - Red 
			{m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255), 0.0f, 0.0f,},		//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), 0.0f, 1.0f,},		//Vertex 14 - Green 
		  {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 0, 255), 0.0f, 0.0f,},		//Vertex 15 - Blue 
		 {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), D3DCOLOR_XRGB(255, 0, 0), 1.0f, 1.0f,},		//Vertex 16 - Red 
			{m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f,},		//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;
}

bool CCuboid::SetTexture(const char *szTextureFilePath)
{
	if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pTexture)))
	{
		return false;
	}

	return true;
}
