#ifndef MODEL_VIEWER_APP_H
#define MODEL_VIEWER_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;



/// 3D graphic model viewer.
/**
*	Model Viewer application alow render
*	3d models. It is mainly based on ItemViewer 
*	class but provide easier interface and managed
*	some other important issues
*/
class ModelViewerApp: public AbstractAPP
{
private:
	OpenGlSharedData &sharedData; /**< Reference to data shared with other applications */

	ItemViewer *itemViewer;	/**< Item viewer is used to view 3d object */
	SoftProjRender *render; /**< Render class for OpenGL render */

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

	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;

	void moveLights( float dt);	/**< Moves point lights around the 3d model */

	static const string LIGHT_0; /**< Name of 1st point light in the scene */
	static const string LIGHT_1; /**< Name of 2nd point light in the scene */

	void initItemViewer(void);		/**< Alocates itemViewer resources */
	void destroyItemViewer(void);	/**<Dealocates itemViewer resources */
	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 setModel( const string &modelName );		/**< Set model name to view. Note: Model with given name must be stored in model database */
	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 ) */
	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 */

	bool isInitialized(void); 	/**< Returns value of member atribut #initialized. */

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





#endif