/*
/ HEIGHTMAP.H
/ ***********
/ Contains the array of values that make up a
/ heightmap that will be used by terrain. Computes
/ the heights from a heightmap file or generates
/ them randomly.
/
/ Will Beddow 2010 - http://343gs.com/brainstem
/
/ This software is currently under development
/ and is subject to change and improvement. Some
/ aspects of the system are incomplete and/or 
/ unstable due to ongoing implementation.
/
*/

#ifndef __HEIGHTMAP_H__
#define __HEIGHTMAP_H__

#include "Compile.h"
#include "Types.h"

#include "BstmDevice.h"

namespace Brainstem
{

	class Heightmap
	{
	public:
		Heightmap(Dimension2<int> size, float maxHeight);
		~Heightmap(void);

		void Release();

		void operator *= (const Heightmap &rhs);

		void CreateRandomHeightMap( int seed, float noiseSize, float persistence, int octaves);
		void GenerateHeightMapTexture(LPDIRECT3DDEVICE9 device, LPDIRECT3DTEXTURE9 *texture); 

		void LoadFromFile(LPDIRECT3DDEVICE9 device, const char* filename);
	
		void Raise(RECT r, float f);
		void Raise(Vector2<int> pt, int radius, float f);
		void Cap(float capHeight);	
		void Smooth();

		float *GetHeightTable() { return Map; }
		float GetMinHeight() { return MinFinalHeight; }
		float GetMaxHeight() { return MaxFinalHeight; }
		Dimension2<int> GetSize() { return Size; }
		const char* GetName() { return "Heightmap"; }

		float GetHeightAt(int x, int y)			
		{ 
			bool outOfBounds = false;
			int index = x + y * Size.Width;

			if (x > Size.Width)
				outOfBounds = true;
			else if (x < 0)
				outOfBounds = true;

			if (y > Size.Height)
				outOfBounds = true;
			else if (y < 0)
				outOfBounds = true;

			if (index < 0)
				outOfBounds = true;

			if (outOfBounds)
				return 0.0f;

			return Map[index]; 

		}
		void ModifyHeightAt( int x, int y, float f ) { Map[ x + y * Size.Width ] += f; }
		void SetHeightAt( int x, int y, float f ) { Map[ x + y * Size.Width ] = f; }
		bool Within(Vector2<int> p);

	private:	
		Dimension2<int> Size;	
		float MaxHeight;	
		float MinFinalHeight;
		float MaxFinalHeight;
		float* Map;
	};
}

#endif