#ifndef __CASSINI_H__
#define __CASSINI_H__

/**
	Class Driver:  Main Application Driver for the game
	This class provides all the necessary functions and data
	to run the game
**/

// let the compiler know these structs exist without 
// having to include all the headers
struct iEngine;
struct iLoader;
struct iGraphics3D;
struct iKeyboardDriver;
struct iVirtualClock;
struct iObjectRegistry;
struct iEvent;
struct iSector;
struct iView;
struct iDynamics;
struct UserInputFilter;
struct World;

//enum listing the various states the game could be in
typedef enum {GAME_INVALID, 
			  GAME_MENU, 
			  GAME_LOBBY, 
			  GAME_SERVER, 
			  GAME_CLIENT, 
			  GAME_MULTI,
			  GAME_CUST,
			  GAME_PLAY}; state;

class Driver {
private:

	//crap that crystalspace needs
	iObjectRegistry* object_reg;

	//graphics engine
	csRef<iEngine> engine;

	//loads files
	csRef<iLoader> loader;

	//3d graphics driver
	csRef<iGraphics3D> g3d;

	//keyboard driver .. used for asynchronous input handling
	csRef<iKeyboardDriver> kbd;

	//clock, duh
	csRef<iVirtualClock> vc;

	//camera stuff, probably should kill
	csRef<iView> view;

	//physics controller
	csRef<iDynamics> dynamics;

	//the world, probably should be moved to the "world" class
	// this defines the "place" where all the polygons will reside
	iSector* room;

	//event handling function that is registered with crystalspace
	static bool CassiniEventHandler (iEvent& ev);

	//actual event handler look in this function for
	//the means by which CrystalSpace handles events
	bool HandleEvent (iEvent& ev);

	//called by crystalspace every frame
	void SetupFrame ();

	//called by crystalspace after SetupFrame
	void FinishFrame ();

public:

	/** Constructor
	  *	object_reg, a variable that crystalspace needs
	  * check crystalspace documentation for further details
	  */
	Driver(iObjectRegistry *object_reg);

	/**
	  * Destructor, currently does nothing
	  */
	~Driver();

	/** Initialize
	  * Initializes all the data necessary for the game
	  */
	bool Initialize();

	/** Start
	  * starts the crystalspace loop
	  */
	void Start();

	/** ShutDown();
	  * Shuts down the program
	  */
	void ShutDown();

	/** GetWorld
	  *	returns a pointer to the world
	  */
	World *GetWorld();
};

/**
	Class GameState: defines the various states the game can be in.
	An instance of this class will represent the the current state 
	of the game.
**/

class GameState{
private:
	//pointer to the main driver app
	Driver *driver;

	//pointer the user input filter
	UserInputFilter *filter;

	//flag indicating what state the game is in
	state currState;

public:

	/** Constructor
	  * d - pointer to the main driver object
	  */
	GameState(Driver *d);

	/** Destructor
	  */
	~GameState();

	/** Quit
	  * shutdown the application
	  */
	void Quit();

	/** DisplayDebugString
	  * call this function to display debug info
	  */
	void DisplayDebugString(char *string);
};

#endif
