#include "EDE_GridSceneNode.h"
#include <stdio.h>


/*  
    ##############################
	# Setting Up the Cell Struct #
	##############################
*/

EDE_GridSceneNode::Cell::Cell()
{
	this->topLeft = vector3df(); 
	this->topRight = vector3df(); 
	this->bottomLeft = vector3df();
	this->bottomRight = vector3df();
	this->id = 0;
	this->visible = false;
}

EDE_GridSceneNode::Cell::Cell(vector3df topLeft, vector3df topRight, vector3df bottomLeft, vector3df bottomRight, int id, bool visible)
{
	this->id = id;
	this->visible = visible;

	this->bottomLeft = bottomLeft;
	this->bottomRight = bottomRight;
	this->topLeft = topLeft;
	this->topRight = topRight;
	this->center = (bottomLeft + bottomRight + topLeft + topRight) / 4;

	meshBuffer = NULL;
	meshBuffer = new CDynamicMeshBuffer(EVT_STANDARD, EIT_16BIT);
	setDefaultMaterial();
}

EDE_GridSceneNode::Cell::~Cell()
{

}

void EDE_GridSceneNode::Cell::setDefaultMaterial()
{
	if (!meshBuffer)
		return;
	
	meshBuffer->getMaterial().Wireframe = false;
	meshBuffer->getMaterial().Lighting = false;
	meshBuffer->getMaterial().Thickness = 1;
	meshBuffer->getMaterial().FogEnable = false;
	meshBuffer->getMaterial().ZWriteEnable = true;
	meshBuffer->getMaterial().ZBuffer = true;
	meshBuffer->getMaterial().BackfaceCulling = true;
	meshBuffer->getMaterial().AntiAliasing = false;
}

void EDE_GridSceneNode::Cell::RenderCell(IVideoDriver* driver, SColor color = SColor(255, 255, 255, 255))
{
	if (!visible)
		return;

	
	driver->setMaterial(meshBuffer->getMaterial());
	driver->setTransform(ETS_WORLD, matrix4());
	// Draw the Box
	driver->draw3DLine(topLeft, topRight, color); // TopLeft -> TopRight
	driver->draw3DLine(bottomLeft, bottomRight, color); // BottomLeft -> BottomRight
	driver->draw3DLine(topLeft, bottomLeft, color); // TopLeft -> BottomLeft
	driver->draw3DLine(topRight, bottomRight, color); // TopRight -> BottomRight
	
}

/*  
	##############################
	# Setting Up the Grid Class  #
	##############################
*/
EDE_GridSceneNode::EDE_GridSceneNode(ISceneNode* parent, ISceneManager* smgr, s32 id)
	: scene::ISceneNode(parent, smgr, id)
{
	gridCells = NULL;
}

void EDE_GridSceneNode::init( int width, int height, vector3df gridPos, float cellSize)
{
	this->width = width;
	this->height = height;
	this->gridPos = gridPos;
	this->cellSize = cellSize;

	// Setting Up my 2D Grid Array
	gridCells = new Cell*[width];
	for (int i = 0; i < width; i++)
		gridCells[i] = new Cell[height];
}

void EDE_GridSceneNode::createGridFlat(float cellSize)
{
	for (int z = 0; z < height; z++)
	{
		for (int x = 0; x < width; x++)
		{
			vector3df v1 = vector3df((gridPos.X * (x+1)) + (x*cellSize), gridPos.Y, (gridPos.Z * (z+1)) + (z*cellSize));
			vector3df v2 = vector3df((gridPos.X * (x+1)) + (x*cellSize) + cellSize, gridPos.Y, (gridPos.Z * (z+1)) + (z*cellSize));
			vector3df v3 = vector3df((gridPos.X * (x+1)) + (x*cellSize), gridPos.Y, (gridPos.Z * (z+1)) + (z*cellSize) + cellSize);
			vector3df v4 = vector3df((gridPos.X * (x+1)) + (x*cellSize) + cellSize, gridPos.Y, (gridPos.Z * (z+1)) + (z*cellSize) + cellSize);
			
			gridCells[x][z] = Cell(v1, v2, v3, v4, z + x, true);
			 
		}
	}
}

void EDE_GridSceneNode::createGridOnTerrain(ISceneNode* terrainSceneNode, float cellSize)
{

}

void EDE_GridSceneNode::renderGrid(IVideoDriver* driver, SColor color)
{
	for (int z = 0; z < height; z++)
	{
		for (int x = 0; x < width; x++)
		{
			gridCells[x][z].RenderCell(driver, color);
		}
	}
}
