#ifndef RADAR_MAP_GAME_INTERFACE_H
#define RADAR_MAP_GAME_INTERFACE_H

#include "./renderer/softProjRender.h"
#include "softProj\Render\GameFunctionalityInterface.h"
#include "./camera/Camera.h"
#include "math\Mathematics.h"
#include "./texture/TextureManager.h"
#include "softProj/Render/SpaceStructures.h"
#include <vector>
#include <map>
#include <cassert>

using namespace std;

using namespace ANALYTICAL_GEOMETRY;

enum RadarObjectType
{
	Star,
	Ship
};

///Basic class for all object that can be used with RadarMapGame class.
/**
*  Basic class for all object that can be used with RadarMapGame class.
*/
class RadarObject
{
private:
	RadarObjectType objectType;

protected:
	virtual void internalSimulate( double dt ) { };	/**< internal simulate method, this method is called by RadarObject::simulate().  Implement this method in our inherited classes  if some simulation action is required. */
	Point_3<double> position;	/**< Object position */

public:

	double lastSynchronizationTime; ///total (summed) dt since last synchronization
	

	void setPosition( const Point_3<double>& pos ); /**< Sets object position */
	Point_3<double> getPosition(void) const; /**< Returns object position */

	RadarObjectType getObjectType( void ) const;	/**< Returns type of the object */
	RadarObject( RadarObjectType objectType, const Point_3<double> &position );

	void simulate( double dt );	/**< Simulates object. It also calls #RadarObject::internalSimulate() which should be used to implement specific simulation action in ihherited classes. */
	virtual void render( SoftProjRender &renderer , const Billboard &srcBillboard  ) = 0; /**< Render given billboard on #position. */
};

///Inherited RadarObject class used for Ship objects.
/**
*	Inherited RadarObject class used for Ship objects.
*/
class ShipRadarObject : public RadarObject
{
private:
	virtual void internalSimulate( double dt ); /**< Simulates ship object - move ship in the move direction according to the #speed and #acceleration and change ship #alpha according to the #alphaOffsetDt */
	Point_3<double> dstPosition; /**< Destination point where the ship is moving on. */
	double speed;	/**< Speed of the ship. */
	double acceleration;	/**< Acceleration of the ship. */
	float alpha;	/**< Alpha of the ship - the ship is rendered as billboard with #alpha transparency */
	float alphaOffsetDt; /**< Alpha offset - the #alpha value is changed according this atribute */

public:
	bool inWarp;										/**< Is ship in Warp flag */ 
	bool inBase;										/**< Is ship in Base flag */ 

	ShipRadarObject( void );

	Point_3<double> getDstPosition(void) const;	/**< Retuns ship destination position. */
	void setDstPosition( const Point_3<double>& dstPos );	/**< Sets ship destination position. */

	void setSpeed( double speed );	/**< Sets ship speed. */
	void setAcceleration( double acceleration );	/**< Sets ship acceleration. */
	void setAlpha( float alpha );	/**< Sets ship alpha transparency value. */
	void setAlphaOffset( float alphaOffsetDt );	/**< Sets ship alpha transparency offset value. */

	bool isVisible( void ) const;	/**< Returns true if #alpha transparency is greater then zero, false otherwise. */
	virtual void render( SoftProjRender &renderer, const Billboard &srcBillboard  ); /**< Render given billboard on ship #ShipRadarObject::position with #ShipRadarObject::alpha transparency value. */
};

///Inherited RadarObject class used for Star objects.
/**
*	Inherited RadarObject class used for Star objects.
*/
class StarRadarObject : public RadarObject
{
private:

public:
	StarRadarObject( void );
	StarRadarObject( const Point_3<double> &position );
	virtual void render( SoftProjRender &renderer, const Billboard &srcBillboard  ); /**< Render given billboard on ship #StarRadarObject::position with #StarRadarObject::alpha transparency value. */
};

///Auxiliary structure to store RadarObject.
struct RadarData
{
	map< unsigned long, ShipRadarObject > ships;	/**< Stores ship id and ShipRadarObject data. */
	map< unsigned long, StarRadarObject > stars;	/**< Stores ship id and StarRadarObject data. */
};


///RadarMapGame application provides macro map mode and displays most important space objects.
/**
*	RadarMapGame application provides functions to work with inserted RadarObjects.
*	This application displays inserted RadarData. Selected ShipRadarObject can be navigated.
*	Camera position can be also moved over the map.
*/
class RadarMapGame : public GameFunctionalityInterface
{
private:
	const float NEAR_CAMERA_ZOOM;	/**<Maximal camera zoom*/
	const float FAR_CAMERA_ZOOM;	/**<Minimal camera zoom*/
	const int MAP_BOUNDARY;	/**<Maximal camera axisX and axisZ offset.*/

	unsigned int activeShipId; /**< Id of selected ship, 0 if no ship selected. */

	bool newDstPoint;	
	int dstPoint[2];

	SoftProjRender &renderer;
	
	unsigned int foregroundTex;	/**<foreground texture id*/
	unsigned int shipTex;	/**<Ships texture id*/
	unsigned int starTex;	/**<Stars texture id*/
	unsigned int backgroundTex;	/**<bacground texture id*/

	Camera<double> camera;	/**<Camera settings*/
	Point_3<double> cameraPivot; /**<Camera pivot position - Camera points on this point*/

	void zoomCamera( float zoom );	/**<zooms camera*/
	void renderInvisiblePickPlane( SoftProjRender &render,  const Point_3<float> &center );
	void refreshCamera(void); /**<recalculates camera*/

	Signalizer signalizer;	/**<signalize location of important events*/


	ShipRadarObject *getActiveShipPtr(void);
	ShipRadarObject *getShipPtr( unsigned long shipId);
public:
	RadarMapGame( SoftProjRender &renderer );

	RadarData RadarData;	/**<Stores objects to work with*/
	void setActiveShipId( unsigned long shipId );	/**<Select active ship*/
	void centerCameraToShip( unsigned long shipId ); /**< Center camera to the given ship. */
	void activateRadar( unsigned long shipId  );	/**<Activates #radar */
	void signalizeShip( unsigned long shipId ); /**<Signalize location of active ship. */

	void (*onShipNewDestinationPos)( Point_3<double> ); /**<Callback function which is called when new destination position for active ship is selected*/

	//---------------GAME INTERFACE-------------------
	virtual void simulate( float dt );
	virtual void render( void );
	virtual void handleKeyboard( Keyboard &keyboard );
	virtual void handleMouse( Mouse &mouse );
	//------------------------------------------------
};


#endif