#pragma once

#include "..\munga_l4\l4grend.h"
#include "..\munga_l4\l4gauge.h"
#include "..\munga\rotation.h"
#include "..\munga\random.h"
#include "..\munga\point3d.h"

//#########################################################################
//####################### Various gauge utilities #########################
//#########################################################################
extern int
	determineEntityColor(Entity *entity, Entity *local_entity=NULL);

//#########################################################################
class Compass :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;
	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer *gauge_renderer
		);

	Compass(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,

		int center_x, int center_y,
		int radius,
		int background_color,
		const char *north_map_name,
		const char *west_map_name,
		const char *south_map_name,
		const char *east_map_name,
		const char *bug_map_name,
		const char *identification_string = "Compass"
	);

	~Compass();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();
	void
		Execute();
protected:
	enum
	{
		northIndex = 0,
     eastIndex,
     southIndex,
     westIndex,
		bugIndex,
		numberOfItems
	};

	char
		*imageName[numberOfItems];

	Vector2DOf<int>
		offset[numberOfItems],
		previousPosition;

	int
		radius,
		backgroundColor;
	L4GaugeRenderer
		*renderer;
	GraphicsViewRecord
  	previousDrawing;
};

class ThreatIndicator :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;
	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer *gauge_renderer
		);

	ThreatIndicator(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,

		int center_x, int center_y,
		int inner_radius,
		int outer_radius,
		int bg_color,
		int team_color,
		int other_color,
		Scalar sensing_radius,
		const char *identification_string = "ThreatIndicator"
	);

	~ThreatIndicator();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();		// virtual function in 'GaugeBase'
	void
		Execute();
protected:
	void
		Select();
	void
		Draw();

	Scalar
		viewRadius,
		topClosingVelocity;

	int
		innerRadius,
		outerRadius,
		backgroundColor,
		teamColor,
		otherColor,
		operatingPhase;

	GaugeEntityList
		movingEntityList;

	GraphicsViewRecord
  	previousDrawing;
};

class NavDisplay;

class NavName SIGNATURED		// Used exclusively by NavDisplay
{
	friend class NavDisplay;

	NavName()
		{}
	~NavName()
		{}

	Logical
		TestInstance() const
			{
				return True;
			}

protected:
	void
		ExtractFromEntity(Entity *entity, AffineMatrix &worldToView);
	static void
		CalculatePositions(NavName *array, int count);
	void
		Draw(GraphicsView *graphics_view, Scalar radius_multiplier);

	Point3D
		center;
	Vector3D
		direction;
	BitMap
		*nameBitmap;
	int
		color;
};

class NavDisplay :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;
	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer *gauge_renderer
		);

	NavDisplay(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,

		int left, int bottom,
		int right, int top,
		int bg_color,
		int static_color,
		Scalar *scale_value_pointer,
		Point3D **position_pointer,
		Quaternion **angle_pointer,
		Logical allow_rock_and_roll=False,
		const char *identification_string = "NavDisplay"
	);

	~NavDisplay();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();
	void
		Execute();

protected:
	void
		CalculateBounds();
	void
		SelectStatic();
	void
		SelectMoving();
	void
		DrawStatic(AffineMatrix &worldToView);
	void
		DrawMoving(AffineMatrix &worldToView);
	void
		DrawNames(AffineMatrix &worldToView);

	enum
	{
		maximumNames = 16
	};

	NavName
		nameArray[maximumNames];

	Scalar
		currentScale;
	Point3D *
		currentPositionPointer;
	Quaternion *
		currentAngularPointer;

	Scalar
  	LODIndex,
		pixelsPerMeter,
		metersPerPixel,
		xMin,
		yMin,
		zMin,
		xMax,
		yMax,
		zMax;

	AffineMatrix
		worldToView;

	int
		operatingPhase,
		backgroundColor,
		staticColor,
		halfWidth,
		halfHeight;

	Logical
		rockAndRoll;

	GaugeEntityList
		staticEntityList,
		movingEntityList;

	GraphicsViewRecord
		previousDrawing;
};

class GPS :
	public GraphicGauge
{
	struct GPSRecord
	{
		int x, y, color;
		Logical me;
	};

public:
	static MethodDescription
		methodDescription;
	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer *gauge_renderer
		);

	GPS(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,

		int left, int bottom,
		int right, int top,
		Scalar LOD_index,
		const char *identification_string = "GPS"
	);

	~GPS();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();		// virtual function in 'GaugeBase'
	void
		NotifyOfNewInterestingEntity(Entity *entity);
	void
		Execute();

protected:
	void
		UpdateStaticEntities();

	enum
	{
		max_moving_entities=32
	};

	Logical
		needsStaticUpdate,
		needsScreenUpdate;
	Scalar
  	LODIndex,
		metersPerPixel,
		pixelsPerMeter;
	Point3D
  	centeringOffset;
	int
		width,
     height,
		numberOfMovingEntities;
	GPSRecord
		previousGPSRecord[max_moving_entities];
	Video8BitBuffered
		*background;
};

//#######################################################################
// Ranking
//#######################################################################
class Ranking :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer * gauge_renderer
		);

	Ranking(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int top, int left,
		const char *font_name,
		int spacing,
		int numeric_color,
		int new_options,
		const char *identification_string = "Ranking"
	);

	~Ranking();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		LinkToEntity(Entity *entity);
	void
		BecameActive();
	void
		Execute();

	enum
	{
		useTeamColorOption=0x0001,
		showAllScoresOption=0x0002,
		showIcomOption=0x0004
	};

protected:
	char
		*messageName;

	enum
	{
		maximumDisplayedPlayers=8
	};

	Entity
		*linkedEntity;
	int
		previousRanking;
	int
		x,
		y,
		options,
		spacing,
		width;

	Player
		*previousArray[maximumDisplayedPlayers];
	Scalar
		previousScore[maximumDisplayedPlayers];
	NumericDisplay
		*numericDisplay[maximumDisplayedPlayers];
	Logical
		previousIntercomEnabled;
	int
		previousChannel[maximumDisplayedPlayers];
	NumericDisplay
		*channelDisplay[maximumDisplayedPlayers];
};

//#######################################################################
// ConfigMap
//#######################################################################
class ConfigMap :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer * gauge_renderer
		);

	ConfigMap(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int top, int bottom,
		const char *unmapped_icon,
		const char *other_icon,
		const char *my_icon,
		const char *both_icon,
		const char *identification_string = "ConfigMap"
	);

	~ConfigMap();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		LinkToEntity(Entity *entity);
	void
		BecameActive();
	void
		Execute();

protected:
	Entity
		*linkedEntity;
	char
		*iconName[4];
	int
		previousState[4];
};

//#######################################################################
// MessageBoard
//#######################################################################
class MessageBoard :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

	static Logical
		Make(
			int display_port_index,
			Vector2DOf<int> position,
			Entity *entity,
			GaugeRenderer * gauge_renderer
		);

	MessageBoard(
		GaugeRate rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,

		int left, int bottom,
		int right, int top,
		const char *font_name,
		const char *message_name,
		int bg_color,
		int numeric_color,
		const char *identification_string = "MessageBoard"
	);

	~MessageBoard();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		LinkToEntity(Entity *entity);
	void
		BecameActive();
	void
		Execute();

protected:
	NumericDisplay
		*numericDisplay;
	Entity
		*linkedEntity;
	char
		*messageName;
	int
		backgroundColor,
		fontHeight;
	enum
	{
  	deliberatelyBogusPointerValue = -1
	};
	Player
		*previousPlayerPointer;
	int
		previousMessageType;
	Scalar
		previousValue;
};
