/*

  Hovertank's ROAM implementation:
  This code is taken and modified from the SimpleROAM implementation.

  The original copyright and info is included:

		//
		// ROAM Simplistic Implementation
		// All code copyright Bryan Turner (Jan, 2000)
		//                    brturn@bellsouth.net
		//
		// Based on the Tread Marks engine by Longbow Digital Arts
		//                               (www.LongbowDigitalArts.com)
		// Much help and hints provided by Seumas McNally, LDA.
		//

*/

#pragma once


#include <glh_array.h>
using namespace glh;

//#include "global.h"
#include "roam_Patch.h"

// ---------------------------------------------------------------------
#define MAX_MAP_SIZE (2048)
#define PATCH_SIZE (128)


#define MAX_PATCHES_PER_SIDE (MAX_MAP_SIZE/PATCH_SIZE)

// ---------------------------------------------------------------------
// Scale of the terrain ie: 1 unit of the height map == how many world units (meters)?
// 1.0f == 1 meter resolution
// 0.5f == 1/2 meter resolution
// 0.25f == 1/4 meter resolution
// etc..
#define MULT_SCALE (0.5f)

// How many TriTreeNodes should be allocated?
#define POOL_SIZE (25000)


#define SQR(x) ((x) * (x))
#define MAX(a,b) ((a < b) ? (b) : (a))
#define DEG2RAD(a) (((a) * M_PI) / 180.0f)
//#define M_PI (3.14159265358979323846f)


#define DRAW_USE_LIGHTING  3
#define DRAW_USE_TEXTURE   2
#define DRAW_USE_FILL_ONLY 1
#define DRAW_USE_WIREFRAME 0

// External variables and functions:
extern GLuint gTextureID;
extern int gDrawMode;

//extern GLfloat gViewPosition[];
//extern GLfloat gCameraRotation[];
extern GLfloat gClipAngle;

//extern void calcNormal(float v[3][3], float out[3]);
extern void calcNormal(vec3f v[3], vec3f& out);
extern void ReduceToUnit(vec3f& v);
extern void SetDrawModeContext();



//
// Landscape Class
// Holds all the information to render an entire landscape.
//
class Landscape
{
protected:
	gs_image_type* m_HeightMap;										// HeightMap of the Landscape
	glh::array2<glh::vec3f>* m_NormalMap;

	Patch m_Patches[MAX_PATCHES_PER_SIDE][MAX_PATCHES_PER_SIDE];	// Array of patches

	static int	m_NextTriNode;										// Index to next free TriTreeNode
	static TriTreeNode m_TriPool[POOL_SIZE];						// Pool of TriTree nodes for splitting

	static int GetNextTriNode() { return m_NextTriNode; }
	static void SetNextTriNode( int nNextNode ) { m_NextTriNode = nNextNode; }

	int nPatchesWidth;
	int nPatchesHeight;

public:
	static TriTreeNode *AllocateTri();

	float xyscale, zscale;

	void Init(gs_image_type* hMap, glh::array2<glh::vec3f>* nMap);
	void Reset();
	void Tessellate();
	void Render();
};
