// Author : Chris Tolley
// Date   : 7/28/2004
// Bug.h contains the class declaration for a bug derived from Object to use
// in the Survival game

#if !defined(AFX_BUG_H__ECBA93B3_EE02_4D62_A2E7_D427ADDC98A6__INCLUDED_)
#define AFX_BUG_H__ECBA93B3_EE02_4D62_A2E7_D427ADDC98A6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>
using std::string;

#include "Gene.h"
#include "ms3d.h"
#include "Object.h"
#include "SmartPointer.h"

// Forward class declarations
class quadTreeTerrain;
class QuadTree;
class SurvivalEngine;

// Some consts to help us out
// Duh......
const double		 PI				    = 3.141592;
// The length of the patrol path.
const int			 PATROL_PATH_LENGTH = 20;
// The radius of the bug
const float			 BUG_RADIUS         = 1;
// The basic unit of movement for the bug
const float			 MOVEMENT_UNIT	    = -200;
// A basic unit of time for a bug
const float			 TIME_UNIT		    = 100;
// The basic unit of rotation
const float			 ROTATION_UNIT	    = 90;
// The radius of site for the bugs
const float			 SITE_RADIUS	  = 20;
// The lifetime of the bug
const unsigned short BUG_LIFETIME     = 120;
// The distance of a range attack
const float			 ATTACK_RANGE	  = 10;
// The amount of energy a bug can recover per second
const int			 ENERGY_UNIT	  = 8;
// The maxium amount of energy a bug can posses
const int			 ENERGY_MAX		  = 255;
// The amount of time it takes for a bug to reproduce
const float			 GESTATION_TIME	  = 10;
// The energy cost of reproducing
const unsigned char  GESTATION_COST	  = 128;
// The time it takes to become fertile again
//const float			 FERTILITY_RATE	  = 30;
// The maxinium amount of food and water a bug can have
const unsigned char	 MAX_RESOURCE	  = 255;
// The maximum age of a particle from a bug
const float			 MAX_PART_AGE	  = 1;
// The amount of damage an attack does
const unsigned char  ATTACK_DAMAGE	  = 20;
// The amount of life that is added to a bug when it kills another bug
const float			 KILL_REWARD	  = 10;


// Some structs to help us out
// This struct holds this unit's threshold values
struct ThresholdValues
{
	unsigned char Reproduce_;
	unsigned char Eat_;
	unsigned char Drink_;
	unsigned char Rest_;
	unsigned char Fight_;
};// End struct ThresholdValues


// Holds this units patrol path
struct PatrolPath
{
	// The actual path data
	unsigned char Path_[ PATROL_PATH_LENGTH ];
};// End struct PatrolPath


// An enum to keep track of which state this unit is in
enum BugState
{
	// The unit is resting
	RESTING,
	// The unit is eating
	EATING,
	// The unit is drinking
	DRINKING,
	// The unit is fighting
	FIGHTING,
	// The unit is patroling
	PATROLING,
	// The unit is reproducing
	REPRODUCING
};// End enum BugState


class Bug : public Object  
{
public:
	// Constructor.  x and z are the current position of this unit
	Bug( float x, float z, const char* ms3dFile, string species );

	// Bug Constructor to use when a bug is giving birth
	Bug( const Bug& rhs );

	// Another Bug constructor
	Bug( string species, Gene& genotype, const char* ms3dFile, 
		 float x, float z );

	// A bug constructor for the bug cam to use
	Bug( string species, Gene& genotype, matrix& local, unsigned int list );

	// Destructor
	virtual ~Bug();

	// Updates the object.  Must be implemented at a derived level
	void Update( float elapsedSec );

	// Renders the object to the screen. Must be implemented at a derived level
	void Render();

	// Returns true if this Object is inside the sphere
	bool InSphere( float x, float z, float radius );

	// Overloaded from object. Returns true if it is time to remove this object
	bool TimeToDie();

	// Does damage to this bug
	void DoDamage( const unsigned char damage );

	// Returns a value indicating the type of object this object is
	inline string GetType() { return "bug"; };

	// Returns the type of species this bug is
	inline string GetSpecies() { return m_sSpecies; };

	// Sets the species of this bug
	inline void SetSpecies( string species ) { m_sSpecies = species; };

	// Checks to see if we need to change states and to what state
	void CheckState();

	// Adjusts the energy, hunger, and thirst of the bug
	void AdjustStats();

	// Causes this bug to move towarded m_spTarget
	bool MoveTowardTarget( float elapsedSec );

	// Initializes the display list
	static void InitializeList( SurvivalEngine* engine,
					quadTreeTerrain* terrain, QuadTree* tree );

	// Returns the hunger level of this bug
	inline unsigned char GetHunger() const { return m_ucHunger; };

	// Returns the thirst level of this bug
	inline unsigned char GetThirst() const { return m_ucThirst; };

	// Returns the energy level of this bug
	inline unsigned char GetEnergy() const { return m_ucEnergy; };

	// Sets the bugs energy
	inline void SetEnergy( unsigned char energy ) { m_ucEnergy = energy; };

	// Returns the fertility value of this bug
	inline float GetFertility() const { return m_fFertility; };

	// Sets the fertility of this bug
	inline void SetFertility( float f ) { m_fFertility = f; };

	// Returns the age of this bug
	inline float GetAge() const { return m_fAge; };

	// Updates the age of this bug
	inline void UpdateAge( float elapsedSec ) { m_fAge += elapsedSec; };

	// Sets the target of this bug
	inline void SetTarget( SmartPointer& target )
	{ m_spTarget = target; };

	// Returns the target of this bug
	inline SmartPointer GetTarget() const { return m_spTarget; };

	// Sets the bugs state
	inline void SetState( BugState state ) { m_bsState = state; };

	// Returns this bugs state
	inline BugState GetState() const { return m_bsState; };

	// Returns the display list for this bug
	inline unsigned int GetListId() const { return m_uiList; };
private:
	// The quad tree that all units are stored on
	static QuadTree* m_qtTree;

	// The terrain that this unit is on
	static quadTreeTerrain* m_qtTerrain;

	// The engine that bugs are updated and renedered by
	static SurvivalEngine* m_pEngine;

	// The type of species this bug is
	string m_sSpecies;

	// The display list to draw this bug
	unsigned int m_uiList;

	// This units Threshold values
	ThresholdValues m_tvThresholds;

	// This unit's patrol path
	PatrolPath m_ppPath;

	// The genotype of this Bug
	Gene m_gGenotype;

	// The percentage that this unit is through it's current state frame
	float m_fPercent;

	// The current state of this bug
	BugState m_bsState;

	// The hunger level of this bug
	unsigned char m_ucHunger;

	// The thirst level of this bug
	unsigned char m_ucThirst;

	// The energy level of this bug
	unsigned char m_ucEnergy;

	// The age of this bug
	float m_fAge;

	// Keeps this bug from having a child for a certain amount of time
	float m_fFertility;

	// This bug's current position on it's patrol path
	unsigned char m_ucPatrolPathPos;

	// The target for the current state.  Not all states us Target
	SmartPointer m_spTarget;
};

#endif // !defined(AFX_BUG_H__ECBA93B3_EE02_4D62_A2E7_D427ADDC98A6__INCLUDED_)
