#ifndef GAMEHEROESOFCIS
#define GAMEHEROESOFCIS

/*
	The heroesproto.h file is the header file for the prototype of the HeroesOfCIS arcade game.
	This file is heavily based off the gamestub.h file that is distributed with the POP
	framework and includes a lot of code and comments from that file.

	In the code below, we put the word virtual in front of all the methods that we have
	inherited from the base classes and which we plan to overload.  (These methods were
	already declared as virtual in the base classes, so that our overloads can take effect.
	Declaring them virtual in this child class only means that they could be further overloaded 
	in the children of the child.)
*/

#include "game.h"
#include "critterarmed.h"
#include "critterwall.h"

//=== cGameHeroesOfCIS Critters ====================================

//--- menu items ---------------------------------------------------
class cCritterWrenchStatusIcon : public cCritter
{
DECLARE_SERIAL(cCritterWrenchStatusIcon);

private:
	/* Static Parameters */
	static Real WRENCH_STATUS_ICON_RADIUS;

	/* Other Parameters */
	int _displayedwrench;

public:
	/* Constructor */
	cCritterWrenchStatusIcon(cGame *pownergame = NULL);
	void initializeWrenchStatusIcon();

    /* Overloads */
	virtual void update(CPopView *pactiveview, Real dt);
};


class cCritterPrintQueueTray : public cCritter
{
DECLARE_SERIAL(cCritterPrintQueueTray);

private:
	/* Static Parameters */
	static Real PRINT_QUEUE_TRAY_RADIUS;
	static Real PRINT_QUEUE_TRAY_OFFSET;

public:
	/* Constructor */
	cCritterPrintQueueTray(cGame *pownergame = NULL);
	void initializePrintQueueTray(int traySpriteID, cVector queueposition);
};


class cCritterPrintQueue : public cCritter
{
DECLARE_SERIAL(cCritterPrintQueue);

private:
	/* Static Parameters */
	static Real PRINT_QUEUE_RADIUS;
	static int MAX_QUEUE;

	/* Other Parameters */
	cCritterPrintQueueTray* _pprintqueuetray; 
	int _queue;
	int _displayedqueue;

public:

	/* Constructor */
	cCritterPrintQueue(cGame *pownergame = NULL);
	void initializePrintQueue(int printerID);

	/* Accessors */
	void positionPrintQueue(int printerID);

	BOOL queueOverflow(){return (_queue > MAX_QUEUE) ? TRUE : FALSE;}
	int queue(){return _queue;}
	void setQueue(int value){_queue = value;}
	void incQueue(int value){_queue += value;}
	void decQueue(int value){_queue = max(0, _queue - value);}

    /* Overloads */
	virtual void update(CPopView *pactiveview, Real dt);
};


//--- environment ---------------------------------------------------

class cCritterHeroesWall : public cCritterWall
{
DECLARE_SERIAL(cCritterHeroesWall);
public:
	cCritterHeroesWall(cGame *pownergame = NULL):cCritterWall(pownergame){}
		//Don't actually use this one.
	cCritterHeroesWall(const cVector &enda, const cVector &endb, 
		Real thickness, UINT color, cGame *pownergame= NULL);
};


class cCritterDoor : public cCritter
{
DECLARE_SERIAL(cCritterDoor);

public:
	static Real DOOR_RADIUS;

	/* Constructor */
	cCritterDoor(cGame *pownergame = NULL);

	/* Overloads */
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};

class cCritterSupplyCabinet : public cCritter
{
DECLARE_SERIAL(cCritterSupplyCabinet);

public:
	static Real SUPPLY_CABINET_RADIUS;

	/* Constructor */
	cCritterSupplyCabinet(cGame *pownergame = NULL);

	/* Overloads */
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};


class cCritterPrinter : public cCritter
{
DECLARE_SERIAL(cCritterPrinter);

public:
    /* Constant Parameters */
	static const int PRINTER_UNNAMED = 0;
	static const int PRINTER_ODIE = 1;
	static const int PRINTER_CUJO = 2;
	static const int PRINTER_LASSIE = 3;
	static const int PRINTER_ASTRO = 4;
	static const int PRINTER_CLIFFORD = 5;
	static const int PRINTER_DINO = 6;

private:

	/* Other Parameters */
	int _printerID; // Printer ID for choosing graphics sprites, print queue location, etc.
	int	_brokenSpriteID;
	int _okSpriteID;

	cCritterPrintQueue* _pprintqueue; // Pointer to printer's print queue

	BOOL _broken;
	BOOL _exploded;

public:
	/* Static Parameters */
	static Real PRINTER_RADIUS;

	/* Constructor */
	cCritterPrinter(cGame *pownergame = NULL);

	int printerID(){return _printerID;}
	BOOL isBroken(){return _broken;}
	BOOL isExploded(){return _exploded;}

	void assignPrinterID(int printerID);

    /* Accessors */
	cCritterPrintQueue* pprintqueue(){return _pprintqueue;}

	/* Other functions */
	void breakMe();
	void fixMe();
	void explodeMe();

    /* Overloads */
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};


//--- enemies ---------------------------------------------------

class cCritterStudent : public cCritter
{
DECLARE_SERIAL(cCritterStudent);

private:

	/* Other Parameters */
	BOOL _breaker;
	cCritterPrinter* _target;

public:
	/* Static Parameters */
	static Real STUDENT_RADIUS;

	/* Constructor */
	cCritterStudent(cGame *pownergame = NULL);
	void initializeStudent(Real speed, cCritterPrinter* target, BOOL breaker = FALSE);

	/* Accessors */
	BOOL breaker(){return _breaker;}
	void setBreaker(BOOL breaker);

	/* Overloads */
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};


class cCritterBouncer : public cCritter
{
DECLARE_SERIAL(cCritterBouncer);

private:

public:
	/* Static Parameters */
	static Real BOUNCER_RADIUS;

	/* Constructor */
	cCritterBouncer(cGame *pownergame = NULL);
	void initializeBouncer(Real speed);

	/* Overloads */
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};


//--- player ---------------------------------------------------

class cCritterHeroesPlayer : public cCritterPlayer //Our player.
{
DECLARE_SERIAL(cCritterHeroesPlayer);

private:
	/* Static Parameters */
	static Real MAX_SPEED;
	static int SCORE_FIX_PRINTER;
	static int SCORE_STOP_BREAKER;

	/* Other Parameters */
	int _wrench;
	//enum Direction {UP, DOWN, LEFT, RIGHT} _direction;
	/* Direction was added as an optimization for the different 
	 * player-direction-dependent sprites.
	 */

	cCritterWrenchStatusIcon* _pwrenchicon;

public:
	static Real PLAYER_RADIUS;

	/* Constructor */
	cCritterHeroesPlayer(cGame *pownergame = NULL);

	/* Accessors */
	int wrench()const{return _wrench;}
	void setWrenchIcon(cCritterWrenchStatusIcon* pwrenchicon);

	/* Overloads */
	virtual void reset();
	virtual BOOL collide(cCritter *pcritter); 
	virtual void update(CPopView *pactiveview, Real dt);
};


//======================= cGameHeroesOfCIS ================


class cGameHeroesOfCIS : public cGame
{
DECLARE_SERIAL(cGameHeroesOfCIS);

private:
	/* Constant Paremeters */
	static const int MAX_PRINTERS = 6;
	static const int MAX_SUPPLYCABINETS = 4;

	/* Static Parameters */
	static Real BLANK_EDGE_WEIGHT; 
	static Real PLAYFIELD_WEIGHT;
	static Real PLAYFIELD_STATUSBOX_SPACER_WEIGHT; 
	static Real BOX_LINEWIDTH_WEIGHT; 
	static COLORREF PLAYFIELD_FILLCOLOR;
	static COLORREF PLAYFIELD_LINECOLOR;
	static COLORREF STATUSBOX_FILLCOLOR;
	static COLORREF STATUSBOX_LINECOLOR;

	/* Other Parameters */
	int _level;

	cRealBox _playfield;
	cRealBox _statusbox;

	int _supplycabinetcount;
	int _printercount;

	cCritterSupplyCabinet* _psupplycabinet[MAX_SUPPLYCABINETS];
	cCritterPrinter* _pprinter[MAX_PRINTERS];

	cCritter* _pdoor;

public:
	/* Constructor */
	cGameHeroesOfCIS();

	/* Accessors */
	cRealBox playfield(){return _playfield;}
	cRealBox statusbox(){return _statusbox;}
	cCritter* pdoor(){return _pdoor;}

	/* Player Stats */
	int wrench();

	/* Printer Stats */
	BOOL printerExploded();

	/* Other Functions */
	void addSupplyCabinet(cCritterSupplyCabinet* psupplycabinet);
	void addPrinter(cCritterPrinter* pprinter);
	void loadLevel(int level);

	/* Overloads */
	virtual void Serialize(CArchive& ar); //Overload for _rivalcount
	virtual void reset();
	virtual void adjustGameParameters();
	virtual CString statusMessage();
	virtual void initializeView(CPopView *pview);
	virtual void initializeViewpoint(cCritterViewer *pviewer); //To change the default view direction.
	virtual void drawBackground(cGraphics *pgraphics, int drawflags);
	virtual void drawForeground(cGraphics *pgraphics, int drawflags);
	virtual void seedCritters();
};

#endif //GAMEHEROESOFCIS
