#include "renderer.h"
#include "map.h"
#include "quadtree.h"
#include "skybox.h"

extern rRenderer *g_Renderer;

struct rHMHeader
{
	int version;
	int sizeOfValue;
	int sideSize;

	float detailTextureScale;
	int hasNormals;
	char textureName[64];
	char detailTextureName[64];

	float fogColor[4];
	float fogDensity;
};

rMap::rMap()
{
	tree = 0;
	skyBox = 0;
}

rMap::~rMap()
{
	delete tree;
	delete skyBox;
	g_Renderer->DeleteTextures(1, &texture);
	g_Renderer->DeleteTextures(1, &detailTexture);
}

bool rMap::Load(char filename[])
{
	rHMHeader h;
	rSBHeader s;
	FILE *pFile = NULL;
	vector3		*normalArray = 0;
	float		*heightArray = 0;

	pFile = fopen(filename, "rb");

	if(!pFile)
	{
		g_Logger.Log("Map %s not found", filename);
		return 1;
	}

	g_Logger.Log("Loading %s", filename);

	fread(&h, sizeof(rHMHeader), 1, pFile);

	if(h.version != 1)
	{
		g_Logger.Log("Map file is version %d, not 1", h.version);
		return 1;
	}

	int size = h.sideSize * h.sideSize;

	heightArray = new float [size];

	//Load Skybox as well
	fread(&s, sizeof(rSBHeader), 1, pFile);

	fread(heightArray, sizeof(float), size, pFile);

	if(h.hasNormals)
	{
		normalArray = new vector3 [size];
		fread(normalArray, sizeof(vector3), size, pFile);
	}

	detailTextureScale = h.detailTextureScale;
	sizeOfValue = h.sizeOfValue;
	sideSize = h.sideSize;
	fogColor[0] = h.fogColor[0];
	fogColor[1] = h.fogColor[1];
	fogColor[2] = h.fogColor[2];
	fogColor[3] = h.fogColor[3];
	fogDensity = h.fogDensity;

	g_Renderer->CreateTexture(texture, h.textureName, 1);
	g_Renderer->CreateTexture(detailTexture, h.detailTextureName, 1);

	fclose(pFile);

	g_Logger.Log("Creating the quadtree");
	tree = new rQuadTree;
	tree->Create(this, sideSize, normalArray, heightArray);

	delete [] normalArray;
	delete [] heightArray;

	g_Logger.Log("Creating the skybox");
	skyBox = new rSkyBox;
	skyBox->Create(&s);

	g_Logger.Log("Map loaded");
	return 0;
}

void rMap::Draw()
{
	if(fogDensity > 0.0f)
	{
		glEnable (GL_FOG);
		glFogi (GL_FOG_MODE, GL_EXP2);

		glFogfv (GL_FOG_COLOR, fogColor);
		glFogf (GL_FOG_DENSITY, fogDensity);
	}
	tree->Draw();
	glDisable(GL_FOG);
	skyBox->Draw();
};