#ifndef PLANET_MODE_APP_H
#define PLANET_MODE_APP_H

#include "./../../../lib/glee/glee.h"
#include <iostream>

#include <qmutex.h>
#include "./cgSupport/CgShaderManager.h"
#include "./configurator/CALreader.h"
#include "./renderer/Render2D.h"
#include "./apps/AbstractAPP.h"
#include "./console/Environment.h"
#include "./exception/Exception.h"
#include "./renderer/softProjRender.h"
#include "./geometry/OBJsupport.h"
#include "./geometry/OBJmodel.h"
#include "./exception/Exception.h"
#include "./console/StrException.h"
#include "./math/Matrix.h"
#include "./math/SupportFunctions.h"
#include "./illumination/LightPrinter.h"
#include <cassert>
#include "./softProj/Render/SpaceStructures.h"

#include "./softProj/Render/SpaceMap.h"
#include "./softProj/Render/SpaceSky.h"

#include "./ModelViewer/ModelViewer.h"
#include "./heightMap/heightMap.h"
#include "./softProj/Render/SpaceMapGameInterface.h"
#include "./softProj/Render/SpacePlanetGameInterface.h"
#include "./softProj/Render/ItemViewer.h"
#include "./softProj/clientServer/sharedStructures.h"
#include "./effects/animationEffect.h"
#include "./softProj/selectionWidget/selectionWidget.h"
#include "./softProj/selectionWidget/otherviewWidget.h"
#include "./softProj/Render/oglSharedData.h"

#include <map>
using namespace std;

using namespace ANALYTICAL_GEOMETRY;
using namespace GEOMETRY;


/// Space planet graphic viewer.
/**
*	Planet Viewer application alow render
*	3d terrains. It is mainly based on SpacePlanetGame 
*	class but provide easier interface and managed
*	some other important issues
**/
class PlanetViewerApp: public AbstractAPP
{
public:
	OpenGlSharedData &sharedData; /**< Reference to data shared with other applications */

	int windowRes[2]; /**< sizeX and sizeY in pixels of the graphic widget where we are connected with */
	bool initialized;	/**< Flag if post constructor was called. Warning: Postconstructor is called automatic from OpenGL widget as soon as OpenGL will be initialized. */
	bool newClick;


	Keyboard keyboard; /**< Keyboard state of our application*/
	Mouse mouse;	   /**< Mouse state our application*/

	SpacePlanetGame *spacePlanet; /**< SpacePlanet viewer allow view space planet */
	LightManager lights;		/**< Manages ligts in scene */
	SoftProjRender *render;  /**< Render class for OpenGL render */
	
	static const string LIGHT; /**< Name of light in the scene */
	static const string HEIGHT_MAP_POSTFIX; /**< String prefix for all heightmap strings. This prefix is connected to heightmap string when loading height map textures */

	void moveLights( float dt ); /**< Moves point lights in the scene */

	void loadModelFromHeightMap( const string &path, unsigned int surfaceTexture, const string &modelName ); /**< Loads texture height map and create terrain model from it */
	void createModelFromHeightMap( const Texture<unsigned char> &heightTex, unsigned int surfaceTexture, const string &modelName ); /**< Creates terrain model from given data. */

	virtual void onOpenGLInit(void); /**< Postconstructor, is called automatic from OpenGL widget as soon as possible, all OpenGL issues cannot be done before this method is called!!! */

public:
	void setResolution( unsigned int sizeX, unsigned int sizeY ); /**< Store resolution in pixels of graphic widget we are connected with. This resolution must be the same as the graphic widget resolution! */
	void simulate( float dt );	/**< Simulate scene ( ie moves lights and other non static issues ) */
	virtual void run(void); /**< Render new frame, is called automatic from GLwidget, but can be called also explicitly if required */

	virtual void keyPressEvent( unsigned int key );	/**< Is called when key is pushed down */
	virtual void keyReleaseEvent( unsigned int key );	/**< Is called when key is released */

	virtual void mouseReleaseEvent( unsigned int mouseButton ); /**< Is called on mouse button release event */
	virtual void mousePressEvent( unsigned int mouseButton );	/**< Is called on mouse button press event */
	virtual void mouseMoveEvent( unsigned int posX, unsigned int posY );	/**< Is called on mouse move event */
	virtual void mouseWheelEvent( int delta );	/**< Is called on mouse wheel event */

	PlanetViewerApp( const string appName, Context &context, OpenGlSharedData &sharedData );
	~PlanetViewerApp(void);
};



#endif