// Author : Chris Tolley
// Date   : 7/21/2004
// SurvivalEngine.h contains the class declaration for the engine that will
// drive Survival

#if !defined(AFX_SURVIVALENGINE_H__886CF3F2_AFD5_4E1E_9B3D_9F251C444157__INCLUDED_)
#define AFX_SURVIVALENGINE_H__886CF3F2_AFD5_4E1E_9B3D_9F251C444157__INCLUDED_

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

#include <windows.h>

#include <vector>
#include <map>
using std::vector;
using std::map;

#include "SurvivalCamera.h"
#include "QuadTree.h"
#include "SmartPointer.h"
#include "ParticleSystem.h"
#include "BugCam.h"
#include "Menu.h"

// Forward class declarations
class quadTreeTerrain;
class HiResTimer;
class CInputSystem;
class Plant;
class WaterPool;
class Bug;

// An enum to set the state of the engine
enum EngineState
{
	// The player is controlling a bug
	PLAY,
	// The player is just watching things
	OBSERVE
};// End EngineState


// An enum to help keep track of who wins or looses
enum GameStatus
{
	// The game is still going
	GAME_ON,
	// The player has won
	PLAYER_WON,
	// The computer has won
	COMPUTER_WON
};// End GameStatus


class SurvivalEngine  
{
public:
	// Default Constructor
	SurvivalEngine();

	// Destructor
	virtual ~SurvivalEngine();

	// Initializes all the engine variables.  Returns true if successful
	bool Initialize( HWND hwnd, HINSTANCE hInstance, 
					 CInputSystem* input, HiResTimer* timer );

	// Prepares everything for a game
	void SetupGame( enum EngineState state );

	// Cleans up everything after a game
	void CleanUpGame();

	// Renders all the game objects to the screen
	void Render();

	// Renders the mini map to the top left of the screen
	void RenderMiniMap();

	// Updates all the game objects. Returns Menu if the game is over or if
	// the user wants to quit the game.  Returns game by default
	MenuChoice Update();

	// Adds a particle to the particle system
	inline void AddParticle( Particle& part ) 
	{ m_psPSystem.AddParticle( part ); };

	// Returns a player controlled bug for the player to take control of
	SmartPointer NewFocus();

	// Returns the current fertility rate
	inline int GetFertilityRate() const { return m_iFertilityRate; };

	// Creates a new plant from x,z and adds it to the map and the terrain
	void CreatePlant( float x, float z );

	// Creates a new bug from x,z and adds it to the map and terrain
	void CreateBug( const Bug* bug );

	// Removes a plant from the object map and from the update vector
	void RemovePlant( Plant* plant );

	// Removes the object obj from the vector of objects
	void RemoveObject( SmartPointer obj );

	// Calculates the current status of the game and returns it
	enum GameStatus IsGameOver();

	// Returns the current status of the game
	enum GameStatus GetStatus() const { return m_gsStatus; };

	// Adds a carcus to the vector of carcus's
	inline void AddCarcus( SmartPointer& car ) { m_vCarcus.push_back( car ); };
private:
	// The timer that runs this game
	HiResTimer* m_Timer;

	// The terrain that this game is played on
	quadTreeTerrain* m_qtTerrain;

	// The input system of this game
	CInputSystem* m_Input;

	// The cameras for this game
	SurvivalCamera m_scCamera;
	BugCam m_bcCamera;

	// a quad tree that helps keep track off all units on the map
	QuadTree m_qtObjectMap;

	// The current fertility rate
	int m_iFertilityRate;

	// The particle system for this game
	ParticleSystem m_psPSystem;

	// The place to store new object
	vector< SmartPointer > m_vecNewObjects;

	// The place to hold the WaterPools
	vector< SmartPointer > m_vecWaterPools;

	// The place to store the bug
	map< string, vector< SmartPointer > > m_mapBugs;

	// The place to store the plants
	vector< SmartPointer > m_vPlants;

	// The place to store the carcus's
	vector< SmartPointer > m_vCarcus;

	// True if the game is paused
	bool m_bPaused;
	// Keeps track of a single space bar press
	bool m_bSpaceDown;

	// The current state of the game
	EngineState m_esState;

	// The status of the current game
	GameStatus m_gsStatus;

	// The number of frames per second we are currently getting
	int m_iFPS;
};

#endif // !defined(AFX_SURVIVALENGINE_H__886CF3F2_AFD5_4E1E_9B3D_9F251C444157__INCLUDED_)
