#include <Ogre.h>
#include <OIS/OIS.h>
#include <OgreConfigFile.h>
#include <OgreException.h>
#include "SceneObject.h"

using namespace Ogre;

class Navicella : public SceneObject {
	
	public:
		Navicella( String p_name, SceneManager * p_sceneMgr, Overlay * p_Overlay, bool p_MissionObjects[] );
		~Navicella();

		bool update( Real elapsedTime, OIS::Keyboard * p_keyboard, OIS::Mouse * p_mouse );


		void	increaseVel();
		void	decreaseVel();

		void	increaseRetroVel();
		void	decreaseRetroVel();

		double  Approssimate( double d );

		void	Raddrizza(Real r);

		void	setNavigationValues();
		
		void	setPrecisionValues();

		void	SwitchStatus();

		void	SetBonusTurbo();

		void	SetInvertedMalus();

		void	SetPigMalus();

		void	SetSlowMotion();

		void	SetInvisibleMode();
		
		void	AzzeraBonusMalus();

		void	ResetStates();

		void	DecreaseToggles(Real e);

		void	AttachParticle( SceneNode * n, ParticleSystem * p);
		void	DetachParticle( SceneNode * n, ParticleSystem * p);

		void	SetOverlay( String s, Real r );

		void	checkVictory();


		// definizione metodi get&set delle variabili della classe
		
		bool getAccellerating();
		void setAccellerating( bool a );

		int getVel();
		void setVel( int v );

		int getIncrVel();
		void setIncrVel( int i );

		int getMaxVel();
		void setMaxVel( int i );

		
		bool getBreaking();
		void setBreaking( bool b );

		int getDeriva();
		void setDeriva( int d );

		int getBreakStrenght();
		void setBreakStrenght( int b );

		
		int getPitchStrenght();
		void setPitchStrenght( int p );

		int getRollStrenght();
		void setRollStrenght( int r );
			
		int getYawStrenght();
		void setYawStrenght( int y );

		int getVerticalVel();
		void setVerticalVel( int v );


		bool getRetro();
		void setRetro( bool r );

		int getRetroVel();
		void setRetroVel( int r );

		int getIncrRetroVel();
		void setIncrRetroVel( int i );

		int getMaxRetroVel();
		void setMaxRetroVel( int m );

	private:
		
		String m_Name;
		OIS::MouseState ms;

		// definizione delle variabili inerenti al movimento
		bool		m_Accellerating; // per sapere se sto accellerando
		int			m_Vel; // velocità di spostamento
		int			m_IncrVel; // fattore di accellerazione
		int			m_MaxVel; // velocita massima
		
		bool		m_Breaking; // per sapere se sto decellerando
		int			m_Deriva; // fattore di decellerazione della deriva
		int			m_Frenata; // fattore di decellerazione della frenata

		int			m_PitchStrenght; // fattore di variazione della picchiata ( pitch )
		int			m_RollStrenght; // fattore di rotazione ( roll )
		int			m_YawStrenght; // fattore di rotazione ( yaw )

		int			m_VerticalVel; // velocità del movimento verticale
		
		// Solo per la retromarcia in modalità precisione
		bool		m_Retromarcia; // per sapere se sto andando di retromarcia
		int			m_RetroVel; // velocità di spostamento in retromarcia
		int			m_IncrRetroVel; // fattore di accellerazione in retromarcia
		int			m_MaxRetroVel; // velocita massima in retromarcia

		// definizione delle variabili inerenti al riposizionamento
		Real		m_StatusToggle; // tempo mancante al prossimo toggle
		double		m_ActualPitch; // variabile che mantiene il pitch attuale della navicella
		double		m_ActualRoll; // variabile che mantiene il roll attuale della navicella
		double		m_ActualPitchInt; // valore di m_ActualPitch approssimato
		double		m_ActualRollInt; // valore di m_ActualRoll approssimato
		bool		m_toRoll;
		bool		m_toPitch;
		

		// definizione variabili di navigazione
		static const int Navigator = 0; // valore attribuito allo stato di navigazione
		static const int Precision = 1; // valore attribuito allo stato di movimento preciso

		// definizione variabili per la gestione dei bonus/malus
		bool			 m_BonusMalus;
		Real			 m_BonusMalusToggle;

		int				 m_Status; // stato del sistema di input
		bool			 m_StatusChanged;
		bool			 m_NoControl;
		bool			 m_TurboEnabled;
		bool			 m_SlowMotionEnabled;
		bool			 m_PigEnabled;
		bool			 m_InvertedEnabled;
		bool			 m_InvisibleEnabled;
		 

		// definizione variabili gioco
		Real			m_LBToggle;
		bool			m_CassaPresa;
		bool			m_CassaPresaDaSparire;
		bool			m_CassaLasciataDaSparire;
		bool			m_CassaBonusDaSparire;
		SceneNode *		m_Cassa;
		SceneNode *		m_TempCassa;
		SceneNode *		m_TeleCassa;
		SceneNode *		m_GhostCassa;
		int				m_ScaleRate;
		bool			m_Victory;


		SceneNode *		m_Pig;
		Entity	  *		m_PigEntity;

	    SceneNode *		m_TurboSxNode;
		SceneNode *		m_TurboDxNode;

		bool *			m_MissionObjects;
		

		Entity *		EntSphere;

		// Particle System per gli effetti
			// per i motori principali
		ParticleSystem	*	m_motore_sx1;
		ParticleSystem	*	m_motore_sx2;
		ParticleSystem	*	m_motore_sx3;
		ParticleSystem	*	m_motore_sx4;

		ParticleSystem	*	m_motore_dx1;
		ParticleSystem	*	m_motore_dx2;
		ParticleSystem	*	m_motore_dx3;
		ParticleSystem	*	m_motore_dx4;

		SceneNode		*	m_Nodemotore_sx1;
		SceneNode		*	m_Nodemotore_sx2;
		SceneNode		*	m_Nodemotore_sx3;
		SceneNode		*	m_Nodemotore_sx4;

		SceneNode		*	m_Nodemotore_dx1;
		SceneNode		*	m_Nodemotore_dx2;
		SceneNode		*	m_Nodemotore_dx3;
		SceneNode		*	m_Nodemotore_dx4;
		
			// per il sistema di teleport
		ParticleSystem	*	m_TelePort2;
		ParticleSystem	*	m_TelePort1;

			// per il turbo
		ParticleSystem  *	m_TurboSx;
		ParticleSystem  *	m_TurboDx;
									
		// Variabili overlay
		Real				m_OverlayToggle;
		Overlay			*	m_Overlay;

		// Sphere Query
		SphereSceneQuery *			m_SphereSQ;
		static const unsigned int	MOVABLE_OBJECT	 = 0x00000001;
		static const unsigned int	MISSION_OBJECT	 = 0x00000002;

		static const unsigned int	TURBO_MALUS		 = 0x00000003;
		static const unsigned int	SLOWMOTION_MALUS = 0x00000004;
		static const unsigned int	PIG_MALUS		 = 0x00000005;
		static const unsigned int	INVERTED_MALUS	 = 0x00000006;
		static const unsigned int	INVISIBLE_MALUS	 = 0x00000007;

		int							m_SphereRange;

		// RayQuery
		RaySceneQuery *				m_RealeseCassaRQ;
		Ray							m_NavicellaRay;
		int							m_RayDistance;

};
