//
// NavEngines.h
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifndef NAVENGINESH
#define NAVENGINESH

#include "HeightField.h"
#include "Engine.h"

///////////////////////////////////////////////////

class vtFlyer : public vtLastMouse
{
public:
	vtFlyer(float fSpeed = 1.0f, bool bPreventRoll = false);

	void SetSpeed(float fSpeed);
	float GetSpeed();

	void Eval();

protected:
	float	m_fSpeed;	// max units per frame of movement
	bool	m_bPreventRoll;
};

class vtTerrainFlyer : public vtFlyer
{
public:
	vtTerrainFlyer(float fSpeed, float fHeightAboveTerrain, bool bMin);

	void SetHeightField(vtHeightField *pGrid) { m_pHeightField = pGrid; }
	void FollowTerrain(bool bFollow);
	void Eval();
	void KeepAboveGround();
	void SetHeight(float fHeightAboveTerrain) { m_fHeightAboveTerrain = fHeightAboveTerrain; }
	float GetHeight() { return m_fHeightAboveTerrain; }
	void MaintainHeight(bool bMaintain) { m_bMaintain = bMaintain; }
	void SetMaintainHeight(float fheight) { m_fMaintainHeight = fheight; }

protected:
	vtHeightField *m_pHeightField;
	float	 m_fHeightAboveTerrain;
	bool	 m_bMin;
	bool	 m_bFollow;
	float	 m_fMaintainHeight;
	bool	 m_bMaintain;
};


//
// Similar to vtTerrainFlyer.  left mouse click affects a flying velocity.
// Viewpoint moves even after mouse button is released.
//
class VFlyer : public vtTerrainFlyer
{
public:
	VFlyer(float scale, float fHeightAboveTerrain, bool bMin);

	void SetGravity(bool bGrav) { m_bGravity = bGrav; }
	void AdjustUpwardVelocity(float velocity);

	// overrides
	void Eval();

protected:
	float	m_fTime;

	bool	m_bGravity;
	float	m_fVelocity;	// up-down
	float	m_fFlyVelocity;	// forward-backward
};


//
// Implemetation of a Quake-like engine
//
class QuakeFlyer : public vtTerrainFlyer
{
public:
	QuakeFlyer(float scale, float fHeightAboveTerrain, bool bMin);
	void Eval();
//	bool OnKey(int key, int flags, int repeat, float speed);

protected:

	float	m_fTime;

	bool	m_bGravity;
	float	m_fVelocity;
	float	m_fFlyVelocity;

	FPoint2 m_LastMousePt;
	float	m_flastmovex, m_flastmovey;
	short	m_sWrap;
	bool	m_bNavEnable;

};


//////////////////////////////////////////////////

class Trackball2 : public vtEngine
{
public:
	Trackball2(float fRadius) {
		m_Pos.Set(0.0f, 0.0f, fRadius);
		m_bDrag = false;
	}
	void OnMouse(vtMouseEvent &event);
	void Eval();

protected:
	FPoint3	m_Pos, m_Start;
	bool	m_bDrag;
	IPoint2	m_MouseStart;
};

#endif

