#ifndef MAP_VIEWER_APP_H
#define MAP_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 "./softProj/Render/RadarMapGameInterface.h"


#include <map>
using namespace std;

using namespace ANALYTICAL_GEOMETRY;
using namespace GEOMETRY;

/// Graphic navigation map viewer.
/**
* Encapsulate space map modes RadarMapGame and SpaceMapGame 
* into one common interface and managed both map modes
*/
class MapViewerApp: public AbstractAPP
{
	friend class ClientSynchronizer; /**< Client synchronizer can synchronize data recieved from server with data in this  class */
	

private:
	int windowRes[2]; /**< sizeX and sizeY in pixels of the graphic widget where we are connected with */
	bool newClick;	
	bool initialized;	/**< Flag if post constructor was called. Warning: Postconstructor is called automatic from OpenGL widget as soon as OpenGL will be initialized. */
	bool useMicroMap; /**< Flag of actual map mode : Micro or Macro mode? */
	unsigned long activeShipId; /**< Id of active ship, 0 if no ship is selected. */
	Keyboard keyboard;	/**< Keyboard state of our application*/
	Mouse mouse;		/**< Mouse state our application*/
	OpenGlSharedData &sharedData;	/**< Reference to data shared with other applications */
	

	RadarMapGame *starMap; /**< Contains Macro mode data */
	SpaceMapGame *spaceMap;	/**< Contains Micro mode data */

	SoftProjRender *render;	/**< Render class for OpenGL render */
	AnimationManager *animationManager; /**< Contains animation used in this application */
	
	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:

	GalaxyPart *getGalaxyPart(void); /**< Returns galaxy data, for reading only! */

	bool isInitialized(void); /**< Returns value of initialized flag */
	bool isMicroMapMode( void); /**< Returns value of useMicroMap flag */
	void setMicroMapMode( bool useMicroMap); /**< Sets value of useMicroMap flag */

	void removeRadarObjectsOlderThan( double simulationDtTime,  bool removeShips, bool removeStars  );	/**< Remove old Radar object data from its database. */
	void removeSpaceMapObjectsOlderThan( double simulationDtTime,  bool removeShips, bool removePlanets  ); /**< Remove old Space map object data from its database. */


	void centerCameraToShip( unsigned long shipId ); /**< Centers camera to selected ship */ 
	void setActiveShipId( unsigned long shipId ); /**< Sets active (selected) ship which is already used by the user. */ 
	void sendRadarWave( void );	/**< Emits radar wave. Radar wave is graphic effect. */ 
	void activateWarpEffect( const Point_3<double> &microPos, const Point_3<double> &macroPos  ); /**< Set warp effect on given position */

	void signalizeShip( unsigned long shipId  ); /**< SIgnalize position of active ship. */
	
	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 ); /**< Simulates galaxy - moves ships, planets and other object in galaxy */
	
	virtual void run(void); /**< Render new frame, is called automatic from GLwidget, but can be called also explicitly if required */


	/**< Sets callbacks for Space map and Radar map, these callbacks are called when selected ship change its destination position */
	void setOnShipNewDestinationPosCallbackFce(  void (*callbackFceMacro)( Point_3<double> ), void (*callbackFceMicro)( Point_3<double> ) );

	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 */

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



#endif