#pragma once

#include "..\munga\gaugrend.h"
#include "..\munga\gauge.h"
#include "l4wrhous.h"
#include "l4vb16.h"

extern char
	*nameCopy(const char *old_name);
//
//--------------------------------------------------------------------------
// NumericDisplay
//
// - displays a formatted numeric value.
// allowed formats are:
//    unsignedFormat    which displays an unsigned value of (N) digits
//    signedFormat      which displays + or - and (N-1) digits
//    timeFormat        which pairs of digits seperated by colons: HH:MM:SS
// ...where N = number_of_chars (below).
//--------------------------------------------------------------------------
//
class NumericDisplay SIGNATURED
{
public:
	enum NumericFormat
	{
		unsignedFormat,
		signedFormat,
		signedBlankedZerosFormat,
		absoluteFormat,
		timeFormat
	};

	NumericDisplay(
		L4Warehouse *warehouse,
		int x_position, int y_position,
		const char *font_name,		//BitMap *font_bitmap,
		int number_of_digits,
		NumericFormat requested_format,
		int background_color, int foreground_color
	);

	~NumericDisplay();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

	void
		ForceUpdate();

	void
		SetColors(
			int bg_color,
			int fg_color
		);
	void
		Draw(
			GraphicsView *graphics_view,
			Scalar current_value
		);
	void
		Erase(
			GraphicsView *graphics_view
		);
	enum
	{
		maxDigits = 16
	};

	enum
	{
		blankedDigit = 127,
		plusDigit=10,
		minusDigit,
		decimalDigit,
		colonDigit,
		totalDigitsPerFont
	};
protected:

L4Warehouse
	*warehouse;
char
	*digitMapName;
int
	digitWidth,
	digitHeight,
	numberOfDigits,
	backgroundColor,
	foregroundColor,
	offsetX,
	offsetY;
NumericFormat
	format;
Scalar
	largestValue,
	previousValue;
Logical
	erased;
char
	previousDigit[maxDigits];
};

//
//--------------------------------------------------------------------------
// NumericDisplayScalar
//
// - displays a formatted numeric value as a gauge.
//--------------------------------------------------------------------------
//
class NumericDisplayScalar :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

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

	NumericDisplayScalar(
		GaugeRate new_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,		//BitMap *font_bitmap,
		int number_of_chars,
		NumericDisplay::NumericFormat requested_format,
		int background_color, int foreground_color,
		Scalar *value_pointer,
		const char *identification_string = "NumericDisplayScalar"
	);

	~NumericDisplayScalar();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();
	void
		SetColors(
			int bg_color,
			int fg_color
		);
	void
		Execute();

protected:
	NumericDisplay
		*numericDisplay;
	Scalar
		currentValue;
};

//
//--------------------------------------------------------------------------
// NumericDisplaySpeed
//
// - converts Scalar input(MPS) to be displayed as KPH
//--------------------------------------------------------------------------
//
class NumericDisplaySpeed :
	public NumericDisplayScalar
{
public:
	static MethodDescription
		methodDescription;

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

	NumericDisplaySpeed(
		GaugeRate new_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,		//BitMap *font_bitmap,
		int number_of_chars,
		NumericDisplay::NumericFormat requested_format,
		int background_color, int foreground_color,
		Scalar *value_pointer
	);

	void
		Execute();
};

//
//--------------------------------------------------------------------------
// NumericDisplayInteger
//
// - displays a formatted numeric value as a gauge.
//--------------------------------------------------------------------------
//
class NumericDisplayInteger :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

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

	NumericDisplayInteger(
		GaugeRate new_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,		//BitMap *font_bitmap,
		int number_of_chars,
		NumericDisplay::NumericFormat requested_format,
		int background_color, int foreground_color,
		int *value_pointer,
		const char *identification_string = "NumericDisplayInteger"
	);

	~NumericDisplayInteger();

	Logical
		TestInstance() const;
	void
		ShowInstance(char *indent);
	void
		BecameActive();
	void
		SetColors(
			int bg_color,
			int fg_color
		);
	void
		Execute();

protected:
	NumericDisplay
		*numericDisplay;
	int
		currentValue;
};

//
//--------------------------------------------------------------------------
// DigitalClock
//
//--------------------------------------------------------------------------
//
class DigitalClock :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

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

	DigitalClock(
		GaugeRate new_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,		//BitMap *font_bitmap,
		int number_of_chars,
		NumericDisplay::NumericFormat requested_format,
		int background_color, int foreground_color,
		const char *identification_string = "DigitalClock"
	);

	~DigitalClock();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

	void
		BecameActive();

	void
		Execute();

protected:
	NumericDisplay
		*numericDisplay;
};

class RankAndScore :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

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

	RankAndScore(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom,
		const char *font_name,
		int background_color, int foreground_color,
		const char *identification_string = "RankAndScore"
	);

	~RankAndScore();

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

protected:
	NumericDisplay
		*numericDisplayRank,
		*numericDisplayScore;
	Entity
		*linkedEntity;
	Logical
		previousState;
	int
		foregroundColor,
		backgroundColor;
};

//##########################################################################
// MakeConfig
//##########################################################################
extern MethodDescription
	MakeConfigMethodDescription;

//##########################################################################
// MakeExternConfig
//##########################################################################
extern MethodDescription
	MakeExternConfigMethodDescription;

//##########################################################################
// BackgroundReconfig
//##########################################################################
class BackgroundReconfig :
	public GaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundReconfig(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		int port_number,
		int palette_ID,
		int enable_ID,
		const char *palette_name,
		const char *identification_string = "BackgroundReconfig" 
	);

	~BackgroundReconfig();

	void
		BecameActive();
protected:

	Logical
		ignorePaletteFlag;
	int
		portNumber,
		paletteID,
		enableID;
	char
		*paletteName;
};

//--------------------------------------------------------------------------
// BackgroundLine
//--------------------------------------------------------------------------
class BackgroundLine :
	public GraphicGaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundLine(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int thick,
		int left, int bottom, int right, int top,
		int color,
		const char *identification_string = "BackgroundLine"
	);

	void
		BecameActive();
protected:
	int
		thickFlag;
	Rectangle2D
		endpoints;
};

//--------------------------------------------------------------------------
// BackgroundRect
//--------------------------------------------------------------------------
class BackgroundRect :
	public GraphicGaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundRect(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		int color,
		const char *identification_string = "BackgroundRect"
	);

	void
		BecameActive();
protected:
	Rectangle2D
		endpoints;
};

//--------------------------------------------------------------------------
// BackgroundFilledRect
//--------------------------------------------------------------------------
class BackgroundFilledRect :
	public GraphicGaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundFilledRect(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		int color,
		const char *identification_string = "BackgroundFilledRect"
	);

	void
		BecameActive();
protected:
	Rectangle2D
		endpoints;
};

//--------------------------------------------------------------------------
// BackgroundPixelmap
//--------------------------------------------------------------------------
class BackgroundPixelmap :
	public GraphicGaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundPixelmap(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom,
		const char *pixelmap_name,
		int opaque_flag,
		const char *identification_string = "BackgroundPixelmap"
	);

	~BackgroundPixelmap();

	Logical
		TestInstance() const;

	void
		BecameActive();
protected:
	char
		*pixelMapName;
	int
		opaqueFlag;
};

//--------------------------------------------------------------------------
// BackgroundBitmap
//--------------------------------------------------------------------------
class BackgroundBitmap :
	public GraphicGaugeBackground
{
public:
	static MethodDescription
		methodDescription;

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

	BackgroundBitmap(
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom,
		const char *bitmap_name,
		int opaque_flag,
		int foreground_color,
		int background_color = 0,
		const char *identification_string = "BackgroundBitmap"
	);

	~BackgroundBitmap();

	Logical
		TestInstance() const;
	void
		BecameActive();

protected:
	char
		*bitMapName;
	int
		foregroundColor,
		backgroundColor,
		opaqueFlag;
};

//
//--------------------------------------------------------------------------
// WipeGaugeScalar
//
// - Base class for "wipe"-style instruments, where a parameter causes
// a rectangular area to change size.
//--------------------------------------------------------------------------
//
class WipeGaugeScalar :
	public GraphicGauge
{
public:
	enum Direction {
		wipeLeft,
		wipeDown,
		wipeRight,
		wipeUp
	};

	void
		BecameActive();

protected:
	WipeGaugeScalar(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		Direction direction,
		Scalar min,
		Scalar max,
		const char *identification_string = "WipeGaugeScalar"
	);

	virtual ~WipeGaugeScalar();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

	void
		Execute();

protected:
	virtual void
		DrawActive(
			Rectangle2D *rectangle
		);

	virtual void
		DrawInactive(
			Rectangle2D *rectangle
		);

	Direction
		wipeDirection;
	int
		width,
		height,
		previousValue;
	Rectangle2D
		previousSize;
	Scalar
		minimumValue,
		currentValue,
		maximumValue;
	Logical
		forceUpdateFlag;
};

//
//--------------------------------------------------------------------------
// 
//--------------------------------------------------------------------------
//
class BarGraphSolidScalar :
	public WipeGaugeScalar
{
public:
	static MethodDescription
		methodDescription;

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

	BarGraphSolidScalar(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		int foreground_color, int background_color,
		WipeGaugeScalar::Direction direction,
		Scalar min,
		Scalar max,
		Scalar *value_pointer,
		const char *identification_string = "BarGraphSolidScalar"
	);

	~BarGraphSolidScalar();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

protected:
	void
		DrawActive(
			Rectangle2D *rectangle
		);

	void
		DrawInactive(
			Rectangle2D *rectangle
		);

	int
		backgroundColor,
		foregroundColor;
};

//
//--------------------------------------------------------------------------
// 
//--------------------------------------------------------------------------
//
class BarGraphBitMapScalar :
	public WipeGaugeScalar
{
public:
	static MethodDescription
		methodDescription;

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

	BarGraphBitMapScalar(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		const char *bitmap_name,
		int foreground_color,
		int background_color,
		WipeGaugeScalar::Direction direction,
		Scalar min,
		Scalar max,
		Scalar *value_pointer,
		const char *identification_string = "BarGraphBitMapScalar"
	);

	~BarGraphBitMapScalar();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

protected:
	void
		DrawActive(
			Rectangle2D *rectangle
		);

	void
		DrawInactive(
			Rectangle2D *rectangle
		);

	char
		*bitMapName;
	int
		foregroundColor,
		backgroundColor;
};

//
//--------------------------------------------------------------------------
// 
//--------------------------------------------------------------------------
//
class BarGraphPixelMapScalar :
	public WipeGaugeScalar
{
public:
	static MethodDescription
		methodDescription;

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

	BarGraphPixelMapScalar(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom, int right, int top,
		const char *pixelmap_name,
		int background_color,
		WipeGaugeScalar::Direction direction,
		Scalar min,
		Scalar max,
		Scalar *value_pointer,
		const char *identification_string = "BarGraphPixelMapScalar"
	);

	~BarGraphPixelMapScalar();

	Logical
		TestInstance() const;

	void
		ShowInstance(char *indent);

protected:
	void
		DrawActive(
			Rectangle2D *rectangle
		);

	void
		DrawInactive(
			Rectangle2D *rectangle
		);

	char
		*pixelMapName;
	int
		backgroundColor;
};

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

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

	ColorState(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom,
		const char *bitmap_name,
		int first_color,
		Scalar first_bin,
		int second_color,
		Scalar second_bin,
		int third_color,
		Scalar third_bin,
		int fourth_color,
		Scalar fourth_bin,
		int fifth_color,
		int damage_zone,
		DamageZone ***value_pointer,
		const char *identification_string = "ColorState"
	);

	~ColorState();

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

protected:
	int
		previousState,
		color[5];
	char
		*bitMapName;
	DamageZone
		*damagePointer;
	Scalar
		bin[4];
};

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

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

	TwoState(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int left, int bottom,
		const char *bitmap_name,
		int first_color,
		int second_color,
		int *value_pointer,
		const char *identification_string = "TwoState"
	);

	~TwoState();

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

protected:
	int
		previousState,
		color[2];
	int
		currentValue;
	char
		*bitMapName;
};


//
//--------------------------------------------------------------------------
// NumericDisplayScalarTwoState
//
// - displays a formatted numeric value as a gauge.
// - can be turned on or off
//--------------------------------------------------------------------------
//
class NumericDisplayScalarTwoState :
	public GraphicGauge
{
public:
	static MethodDescription
		methodDescription;

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

	NumericDisplayScalarTwoState(
		GaugeRate new_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,		//BitMap *font_bitmap,
		int number_of_chars,
		NumericDisplay::NumericFormat requested_format,
		int background_color, int foreground_color,
		Scalar *value_pointer,
		int *logical_pointer,
		const char *identification_string = "NumericDisplayScalarTwoState"
	);

	~NumericDisplayScalarTwoState();

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

	#if 0
	void
		SetColors(
			int bg_color,
			int fg_color
		);
	#endif
	void
		Execute();

protected:
	NumericDisplay
		*numericDisplay;
	int
		previousState, previousValue,
		color[2];
	Scalar
		currentValue;
	int
		currentLogical;

};


//#######################################################################
// SegmentArc
//#######################################################################
class SegmentArc :
	public GraphicGauge
{
public:
	SegmentArc(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int center_x, int center_y,
		Scalar inner0, Scalar outer0,
		Scalar inner1, Scalar outer1,
		Scalar deg0, Scalar deg1,
		int number_of_segs_and_direction,
		int background_color,
		int foreground_color,
		Logical use_thick_lines = True,
		const char *identification_string = "SegmentArc"
	);

	~SegmentArc();

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

protected:
	int
		backgroundColor,
		foregroundColor,
		numberOfSegments,
		previousSegment;
	Logical
		useThickLines;
	Scalar
		currentValue,
		startAngle,
		deltaAngle,
		innerRadius,
		outerRadius,
		deltaInnerRadius,
		deltaOuterRadius;
};

//#######################################################################
// SegmentArcNormalized
//#######################################################################
class SegmentArcNormalized :
	public SegmentArc
{
public:
	static MethodDescription
		methodDescription;

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

	SegmentArcNormalized(
		GaugeRate new_rate,
		ModeMask mode_mask,
		L4GaugeRenderer *renderer,
		unsigned int owner_ID,
		int graphics_port_number,
		int center_x, int center_y,
		Scalar inner0, Scalar outer0,
		Scalar inner1, Scalar outer1,
		Scalar deg0, Scalar deg1,
		int number_of_segs_and_direction,
		int background_color,
		int foreground_color,
		Scalar *value_pointer,
		Logical use_thick_lines = True,
		const char *identification_string = "SegmentArcNormalized"
	);
};
