//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: terrain.h
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Represents a 3D terrain.       
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __terrainH__
#define __terrainH__

#include "d3dUtility.h"
#include "material.h"
#include "shape.h"
#include <string>
#include <vector>

#include <kLibrary\Factory\factory.h>

namespace CBK
{
	class TerrainParam
	{
	public:
		IDirect3DDevice9* device;
		int numVertsPerRow;
		int numVertsPerCol;
		int cellSpacing;
		float heightScale;

		inline TerrainParam(IDirect3DDevice9* device = 0, const int numVertsPerRow = 64, const int numVertsPerCol = 64, const int cellSpacing = 10, const float heightScale = 0.5f)
		{
			this->device = device;
			this->numVertsPerRow = numVertsPerRow;
			this->numVertsPerCol = numVertsPerCol;
			this->cellSpacing = cellSpacing;
			this->heightScale = heightScale;
		}
	};

	class Terrain : public Mesh//, public kLibrary::factory::Item<const TerrainParam>
	{
	public:
		Terrain(IDirect3DDevice9* device, const std::string& heightmapFileName, const int numVertsPerRow, const int numVertsPerCol, const int cellSpacing, const float heightScale);
		Terrain(const std::string& fileName, const TerrainParam& params);

		~Terrain();

		int  getHeightmapEntry(const int row, const int col) const;
		void setHeightmapEntry(const int row, const int col, const int value);

		float getHeight(const float x, const float z) const;

		bool loadTexture(const std::string& fileName);
		bool genTexture(void);
		virtual void draw(const DWORD& subset = 0);

		virtual Mesh& reset(void);

	private:
		IDirect3DTexture9*      _tex;
		IDirect3DVertexBuffer9* _vb;
		IDirect3DIndexBuffer9*  _ib;

		int _numVertsPerRow;
		int _numVertsPerCol;
		int _cellSpacing;

		int _numCellsPerRow;
		int _numCellsPerCol;
		int _width;
		int _depth;
		int _numVertices;
		int _numTriangles;

		float _heightScale;

		std::vector<int> _heightmap;

		// helper methods
		virtual kLibrary::factory::Item<const MeshParam&>& load(const std::string& name, const MeshParam& param);
		void init(IDirect3DDevice9* device, const std::string& heightmapFileName, const int numVertsPerRow, const int numVertsPerCol, const int cellSpacing, const float heightScale);
		bool  readRawFile(const std::string& fileName);
		bool  computeVertices();
		bool  computeIndices();
	};
}

#endif // __terrainH__
