/*********************************************************************
*	Game Environment
*	HEADER FILE
*	Autor:	Michal Jirouš
*	Datum: 16.9.2008
*	Soubor: game_environment.h
*	Popis: Trida vytvari okolni prostredi, coz je Sky box a Highmap, 
*			ktera generuje relief krajiny podle alfa slozky obrazku.
*			Textura obrazku je pak na tento povrch mapovana bud 1:1 nebo
*			je opakovana.
**********************************************************************/

#ifndef __GAME_ENVIRONMENT_H__
#define __GAME_ENVIRONMENT_H__

#include <string>
#include "algebraic.h"
#include "textureslib.h"

const float ENVIRONMENT_DEFAULT_GROUND = 0.0f;
const float ENVIRONMENT_DEFAULT_ELEM_SIZE = 512.0f;
const float ENVIRONMENT_MIN_ELEM_SIZE = 32.0f;
const float ENVIRONMENT_MAX_ELEM_SIZE = 1024.0f;

const float ENVIRONMENT_MIN_SKY_DIST = 512.0f;
const float ENVIRONMENT_MAX_SKY_DIST =20*1024.0f;
const float ENVIRONMENT_DEFAUL_SKY_DIST = 4096.0f;
static const char* ENVIRONMENT_DEFAULT_SKY = "alien1";

const float ENVIRONMENT_MIN_ALPHA_UNIT = 1.0f;
const float ENVIRONMENT_MAX_ALPHA_UNIT = 256.0f;
const float ENVIRONMENT_SIZE_PER_PIXEL_MIN = 1.0f;
const float ENVIRONMENT_SIZE_PER_PIXEL_MAX = 1024.0f;
const float ENVIRONMENT_SIZE_PER_PIXEL_DEFAULT = 128.0f;

const bool ENVIRONMENT_DEFAULT_TEXTURE_REPEAT = false;

//Zakladni graficka jednotka
struct EnvElem
{
	alg::BoundingBox m_Bounds;
	GLuint m_uiDListIndex;
	GLuint m_uiTextureIndex;
	EnvElem() : m_uiDListIndex(0) {}
	EnvElem(const EnvElem &e )
	{
		m_Bounds = e.m_Bounds;
		m_uiDListIndex = e.m_uiDListIndex;
		m_uiTextureIndex = e.m_uiTextureIndex;
	}
};

class CEnvironment
{
	float m_X, m_Y, m_W, m_H;	//celkove rozmery high mapy

	

	//High map items
	unsigned char* pCurrentPicture;	//ukazatel na data obrazku

	int m_iTextureRepeat;
	float m_fSizePerPixel;
	float m_fHeightPerAlphaUnit;
	float m_fGroundHeight;
	float m_fElemSize;
	ImageInfo m_HighMapImage;	//informace o obrazku
	GLuint m_iTextureID;
	std::list<EnvElem> m_ElementsList;

	float m_fSkyDistance;
	std::string m_sSkyName;
	
	//vypocita index v obrazku dle souradnic x a y a vraci ukazatel na cilovy pixel RGBA
	unsigned char *getPictureValues( int x_index, int y_index );	
	void makeElements( float x, float y, float w, float h );
	float makeVertex( float x, float y );
	void createHighMap();

	
	//Sky box items
	void createSkyBox();
	void createSkyBoxWall( alg::Point &A, alg::Point &B, alg::Point &C, alg::Point &D, std::string filename );
	std::list<EnvElem> m_SkyBoxWalls;
public:
	CEnvironment();
	~CEnvironment();

	//Highmap parameters
	void setHighMapPicture( std::string filename ) { m_HighMapImage.setFilename( filename ); }
	void setHighMapParms( float fGroundHeight ) { m_fGroundHeight = fGroundHeight; }
	void setElemSize( float size ) { m_fElemSize = getFromRange( size, ENVIRONMENT_MIN_ELEM_SIZE, ENVIRONMENT_MAX_ELEM_SIZE ); }
	void setAlphaUnit( float unit )	{ m_fHeightPerAlphaUnit = getFromRange( unit, ENVIRONMENT_MIN_ALPHA_UNIT, ENVIRONMENT_MAX_ALPHA_UNIT); }
	void setSizePerPixel( float size )	{ m_fSizePerPixel = getFromRange( size, ENVIRONMENT_SIZE_PER_PIXEL_MIN, ENVIRONMENT_SIZE_PER_PIXEL_MAX ); }
	void setTextureRepeat( int r )	{ m_iTextureRepeat = r; }

	void setSkyName(  std::string sName )	{ m_sSkyName = sName; }
	void setSkyDistance( float distance )	{ m_fSkyDistance = getFromRange(distance, ENVIRONMENT_MIN_SKY_DIST, ENVIRONMENT_MAX_SKY_DIST); }
	void compile();
	void decompile();
	void run() {}
	void drawHighmap();
	void drawSkyBox();

	std::list<EnvElem> * getHighMapElemList()	{ return &m_ElementsList; }
	std::list<EnvElem> * getSkyBoxElemList()		{ return &m_SkyBoxWalls; }
};

extern CEnvironment environment;

#endif
