#include "TerrainBlockData.h"

using namespace core;

const video::S3DVertex* TerrainBlockData::vertices() const { return &m_vertices[0]; }
const u16* TerrainBlockData::indices() const { return &m_indices[0]; }
const core::aabbox3d<f32>& TerrainBlockData::boundingBox() const { return m_box; }
video::SMaterial& TerrainBlockData::material() { return m_material; }

TerrainBlockData::TerrainBlockData(video::ITexture* pTexture)
{
	m_material.Wireframe = false;
	m_material.Lighting = false;
	m_material.setTexture(0, pTexture);
	m_material.setFlag(video::EMF_ANISOTROPIC_FILTER, true);

	//
	//
	// The cube will be centered in the Center of the bottom
	// rectangle. Where the "C" is in the following ascii cube
	//
	//
	//			4-----------5
	//		   /|          /|
	//		  / |         / |
	//		 /  |        /  |  "Y"
	//		7-----------6   |
	//		|   |       |   |
	//		|   0-------|---1
	//		|  /        |  /
	//		| /     C   | /   "Z"
	//		|/          |/
	//		3-----------2
	//
	//           "X"
	//
	//  ========================
	// ===== ASCII ART FTW! =====
	//  ========================
	//
	// Numbers represent the vertices of the cube.
	//
	// Also, the coordinate system used for this model space is:
	//
	//
	//          Y
	//			|
	//			|
	//			0------X
	//		   /
	//        /
	//       Z
	//

	//Geometry
	const float xHalf = 1.f / 2;
	const float zHalf = 1.f / 2;
	const float y = 1.f;

	//Vertex positions
	const vector3df positions[] = {
		//Lower
		vector3df(-xHalf, 0, -zHalf),	//0
		vector3df(xHalf, 0, -zHalf),	//1
		vector3df(xHalf, 0, zHalf),		//2
		vector3df(-xHalf, 0, zHalf),	//3
		//Upper
		vector3df(-xHalf, y, -zHalf),	//4
		vector3df(xHalf, y, -zHalf),	//5
		vector3df(xHalf, y, zHalf),		//6
		vector3df(-xHalf, y, zHalf),	//7
	};

	//Add faces
	unsigned int vertexIndex = 0;
	unsigned int indexIndex = 0;
	addFace(vertexIndex, indexIndex, positions, vector3df(0,0,1), 7, 6, 2, 3);
	addFace(vertexIndex, indexIndex, positions, vector3df(1,0,0), 6, 5, 1, 2);
	addFace(vertexIndex, indexIndex, positions, vector3df(0,0,-1), 5, 4, 0, 1);
	addFace(vertexIndex, indexIndex, positions, vector3df(-1,0,0), 4, 7, 3, 0);
	addFace(vertexIndex, indexIndex, positions, vector3df(0,1,0), 7, 4, 5, 6);	//upper face
	addFace(vertexIndex, indexIndex, positions, vector3df(0,-1,0), 0, 3, 2, 1);	//lower face

	//Initialize bounding box
	m_box.reset(m_vertices[0].Pos);
	for (s32 i=1; i<VERTEX_COUNT; ++i) {
		m_box.addInternalPoint(m_vertices[i].Pos);
	}
}


TerrainBlockData::~TerrainBlockData()
{
}

void TerrainBlockData::addFace(unsigned& vertexIndex, unsigned& indexIndex, 
	const vector3df* positions, const core::vector3df& normal,
	unsigned v1, unsigned v2, unsigned v3, unsigned v4)
{
	video::SColor vertexColor(255,255,255,255);

	//Indices
	m_indices[indexIndex++] = vertexIndex+1;	//Triangle 1
	m_indices[indexIndex++] = vertexIndex;
	m_indices[indexIndex++] = vertexIndex+2;

	m_indices[indexIndex++] = vertexIndex+2;	//Triangle 2
	m_indices[indexIndex++] = vertexIndex;
	m_indices[indexIndex++] = vertexIndex+3;

	//Vertices
	m_vertices[vertexIndex++] = video::S3DVertex(
		positions[v1].X, positions[v1].Y, positions[v1].Z,
		normal.X, normal.Y, normal.Z,
		vertexColor,0,0);
	m_vertices[vertexIndex++] = video::S3DVertex(
		positions[v2].X, positions[v2].Y, positions[v2].Z,
		normal.X, normal.Y, normal.Z,
		vertexColor,1,0);
	m_vertices[vertexIndex++] = video::S3DVertex(
		positions[v3].X, positions[v3].Y, positions[v3].Z,
		normal.X, normal.Y, normal.Z,
		vertexColor,1,1);
	m_vertices[vertexIndex++] = video::S3DVertex(
		positions[v4].X, positions[v4].Y, positions[v4].Z,
		normal.X, normal.Y, normal.Z,
		vertexColor,0,1);
}
