//===========================================================================//
// File:	btl4gau2.hpp                                                        //
// Project: BattleTech          Brick: Gauge Renderer Manager                 //
// Contents: Cockpit instrument library, part 2 -- the COMPOSITE "panel"      //
//           gauges that the BattleTech engineering / weapon-status HUD is     //
//           assembled from.  Where btl4gaug.cpp holds the primitive widgets   //
//           (bars, dials, lamps, colour-mappers), btl4gau2.cpp holds the      //
//           higher-level gauges that AGGREGATE those primitives into a single  //
//           subsystem read-out:                                               //
//             * SeekVoltageGraph   -- energy-weapon seek-voltage curve         //
//             * ConfigMapGauge     -- joystick / config-manager state lamp     //
//             * GeneratorCluster   -- generator voltage + coolant + leak panel //
//             * PrepEngrScreen     -- per-weapon engineering screen builder    //
//             * SubsystemCluster    +-> HeatSinkCluster                        //
//                                    +-> WeaponCluster +-> EnergyWeaponCluster //
//                                                       +-> BallisticWeaponClu.//
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 02/22/96  CPB  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc. All rights reserved //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//
//
// RECONSTRUCTED.  No BTL4GAU2.HPP survived; recovered from the shipped binary
// (BTL4OPT.EXE).  Ghidra pseudo-C is in recovered/all/part_014.c.
//
// Translation-unit extent (BTL4.MAK link order:
//   btl4mode -> btl4rdr -> btl4gaug -> btl4gau2 -> btl4gau3 -> btl4grnd -> ...):
//      first gau2 code  @004c6798   (SeekVoltageGraph::SeekVoltageGraph)
//      last  gau2 code  @004c9b50   (BallisticWeaponCluster helpers)
//      btl4gau3 begins  @004c9bd0   (PlayerStatusMappingGroup -- not this TU)
//
// Class names recovered from the CODE name-string pool around 0x519760
// (the gauge name list) and the per-instance identification strings:
//   "GeneratorCluster"  0x519a8c   "PrepEngr"   0x519a9d
//   "ConfigMap"         0x519a38   "CoolingLoop" 0x519a42  "PowerSource" 0x519a4e
//   "GeneratorVoltage(scalar)" 0x519a73   "GeneratorVoltage(slotOf)" 0x519a5a
//   "EngrGraph" 0x519a2e   "WeaponCluster ... " 0x519dcb
// Field offsets in comments are byte offsets (e.g. "@0x90" == this[0x24]).
//
// Bases (MUNGA L4 gauge primitives, shared with btl4gaug.cpp):
//   GraphicGauge   ctor FUN_00444818  dtor FUN_00444870  (GraphicsView @+0x48)
//   Gauge group    ctor FUN_004440d4  dtor FUN_00443f7c  (owns a ChainOf<Gauge*>
//                  at +0x24; used by PrepEngrScreen -- it draws into a port and
//                  hosts no GraphicsView of its own)
//   ArcGauge/BarGraph primitives  FUN_00472ef0 (bar), FUN_004c6244 (SegmentArc270,
//                  in btl4gaug), FUN_004739d8 (TwoState), FUN_00471d00
//                  (BackgroundBitmap), FUN_004700bc (NumericDisplay),
//                  FUN_00470888 (NumericDisplayScalar),
//                  FUN_00473c94 (NumericDisplayScalarTwoState).
//
// Names flagged "(best-effort)" exist in the binary but their identification
// string could not be tied to them unambiguously.
//

#if !defined(BTL4GAU2_HPP)
#	define BTL4GAU2_HPP

#	if !defined(SLOT_HPP)
#		include <slot.hpp>
#	endif
#	if !defined(L4GREND_HPP)
#		include <l4grend.hpp>
#	endif
#	if !defined(L4GAUGE_HPP)
#		include <l4gauge.hpp>
#	endif
#	if !defined(BTL4GAUG_HPP)
#		include <btl4gaug.hpp>
#	endif
#	if !defined(HEAT_HPP)
#		include <heat.hpp>
#	endif
	// (see btl4gaug.hpp -- <powersub.hpp> intentionally not pulled in; the
	//  composite gauges reference subsystems by pointer/attribute, not by type.)

	//
	// Reconstruction type: the original referenced an "AttributeAccessor" handle
	// (a small object that samples one named subsystem attribute).  Only its
	// address is used here (it is immediately reinterpreted as an Entity*), so an
	// opaque forward declaration is sufficient for this translation unit.
	//
	class AttributeAccessor;


	//#######################################################################
	// SeekVoltageGraph -- the energy-weapon "seek voltage" curve display.
	// @004c6798 ctor / @004c68ac dtor / @004c6920 BecameActive / @004c6934 Execute.
	// vtable PTR_FUN_0051a1fc.  Reads the four SeekVoltage attribute indices off
	// the weapon subsystem ("CurrentSeekVoltageIndex" / "Min" / "Max" /
	// "SeekVoltage") and plots a 0..230 x 0..187 curve, with min/max tick marks
	// and a live cursor at the current seek index.  When the subsystem is
	// destroyed (subsys+0x40==1) it shows a centred "destroyed" bitmap instead.
	//#######################################################################
	class SeekVoltageGraph :
		public GraphicGauge
	{
	public:
		SeekVoltageGraph(						// @004c6798
			GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer,
			int graphics_port_number, Entity *subsystem,
			AttributeAccessor *seek_voltage_pointer,
			const char *destroyed_image, Logical draw_cursor,
			const char *identification_string);
		~SeekVoltageGraph();					// @004c68ac
		Logical	TestInstance() const;
		void	BecameActive();					// @004c6920
		void	Execute();						// @004c6934
	protected:
		char	*destroyedImage;				// @0x90  this[0x24]
		int		currentSeekIndex;				// @0x94  this[0x25]  attr idx
		int		minSeekIndex;					// @0x98  this[0x26]  attr idx
		int		maxSeekIndex;					// @0x9C  this[0x27]  attr idx
		int		seekVoltageTable;				// @0xA0  this[0x28]  attr idx
		Entity	*voltageSubsystem;				// @0xA4  this[0x29]
		Subsystem *subsystem;					// @0xA8  this[0x2A]
		Scalar	previousVoltage;				// @0xAC  this[0x2B]  (9999 = redraw)
		Scalar	xScale;							// @0xB0  this[0x2C]  =230.0f
		Scalar	yScale;							// @0xB4  this[0x2D]  =187.0f
		int		destroyedShown;					// @0xB8  this[0x2E]
		Logical	drawCursor;						// @0xBC  this[0x2F]
		// helpers: SetupClip @004c6be4, DrawCursor @004c6c30, DrawTicks @004c6c6c
	};


	//#######################################################################
	// ConfigMapGauge -- the joystick / config-manager (control-mapper) state
	// lamp.  @004c6d80 ctor / @004c6e54 dtor / @004c6ee0 SetColor /
	// @004c6ef4 BecameActive / @004c6f1c Execute.  vtable PTR_FUN_0051a1b8.
	// Owns a base joystick bitmap ("btjoy.pcc") plus four config-state pixmaps
	// (cm_off/cm_other/cm_only/cm_both .pcc) selected from a 4-entry table
	// (DAT_00518eb8) driven by the control-mapper state.  Named "ConfigMap".
	//#######################################################################
	class ConfigMapGauge :
		public GraphicGauge
	{
	public:
		ConfigMapGauge(							// @004c6d80
			GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
			int x, int y, Entity *subsystem, const char *identification_string);
		~ConfigMapGauge();						// @004c6e54
		Logical	TestInstance() const;
		void	SetColor(int color);			// @004c6ee0  this[0x25]
		void	BecameActive();					// @004c6ef4
		void	Execute();						// @004c6f1c
	protected:
		Entity	*subsystem;						// @0x90  this[0x24]
		int		color;							// @0x94  this[0x25]
		char	*joystickImage;					// @0x98  this[0x26]  "btjoy.pcc"
		char	*stateImage[4];					// @0x9C  this[0x27..0x2A]
		int		previousState[4];				// @0xAC  this[0x2B..0x2E]
		Logical	dirty;							// @0xBC  this[0x2F]
	};


	//#######################################################################
	// Two small OneOfSeveral subclasses that drive the selected frame from a
	// subsystem value through a file-private GaugeConnection (the same
	// connection classes declared in btl4gaug.cpp).
	//   AnimatedSubsystemLamp  @004c70a4 (vtable 0051a174) -- connection @004c3134
	//   AnimatedSourceLamp     @004c7160 (vtable 0051a130) -- connection @004c31ec
	// Both chain OneOfSeveral::OneOfSeveral (@004c4d88, fromImageStrip=1) and
	// share dtor FUN_004c4e7c.  Used for the cooling-loop / power-source lamps.
	// (Class names best-effort; the gauge is generic and reused with the
	// instance strings "CoolingLoop" and "PowerSource".)
	//#######################################################################
	class AnimatedSubsystemLamp :				// (best-effort)
		public OneOfSeveral
	{
	public:
		AnimatedSubsystemLamp(					// @004c70a4
			GaugeRate, ModeMask, L4GaugeRenderer *, int,
			int x, int y, const char *image, int columns, int rows,
			Entity *subsystem, const char *identification_string);
		~AnimatedSubsystemLamp();				// @004c7134
	protected:
		int		selected;						// @0xAC  this[0x2B]  (connection dst)
	};

	class AnimatedSourceLamp :					// (best-effort)
		public OneOfSeveral
	{
	public:
		AnimatedSourceLamp(						// @004c7160
			GaugeRate, ModeMask, L4GaugeRenderer *, int,
			int x, int y, const char *image, int columns, int rows,
			Entity *source, const char *identification_string);
		~AnimatedSourceLamp();					// @004c71f0
	protected:
		int		selected;						// @0xAC  this[0x2B]
	};


	//#######################################################################
	// ScalarBarGauge -- a generator-voltage bar (derives from the MUNGA L4 bar
	// primitive @00472ef0).  Two ctors:
	//   @004c721c (vtable 0051a0e4) adds an "AltId" connection (@004c3288)
	//   @004c72ac (same vtable)     adds a plain GaugeConnectionDirectOf<Scalar>
	//                               (@00474855)
	// Both share dtor FUN_004c733c (chains the bar dtor @00472fb4).  Used with
	// the strings "GeneratorVoltage(slotOf)" / "GeneratorVoltage(scalar)".
	//#######################################################################
	class ScalarBarGauge :						// (best-effort)
		public GraphicGauge						// MUNGA L4 bar primitive (FUN_00472ef0); engine has no plain "BarGraph" class
	{
	public:
		ScalarBarGauge(/* ...bar geometry..., Scalar *value, id */);	// @004c721c / @004c72ac
		~ScalarBarGauge();						// @004c733c
	protected:
		Scalar	value;							// @0xB4  this[0x2D]  (connection dst)
	};


	//#######################################################################
	// GeneratorCluster -- the generator read-out panel.  @004c7368 Make /
	// @004c746c ctor / @004c7778 dtor.  vtable PTR_FUN_0051a0a0.  A GraphicGauge
	// that owns five child gauges, parented to its own graphics port:
	//      VertTwoPartBar         (temperature)    this[0x26]
	//      ScalarBarGauge         (voltage 0..12kV) this[0x27]
	//      BitMapInverseWipe/Leak (coolant leak)    this[0x28]
	//      TwoState x2            (status lamps)    this[0x29],this[0x2A]
	// Reads CurrentTemperature/DegradationTemperature/FailureTemperature/
	// CoolantMassLeakRate/OutputVoltage attribute indices off the subsystem.
	// Make resolves the named subsystem ("GeneratorCluster") via FindSubObject;
	// warns "Subsystem <name> not found".
	//#######################################################################
	class GeneratorCluster :
		public GraphicGauge
	{
	public:
		static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *);	// @004c7368
		GeneratorCluster(						// @004c746c
			GaugeRate, ModeMask, L4GaugeRenderer *, int,
			int x, int y, const char *background_image,
			int /*color*/, const char *temp_tile,
			Scalar *low, Scalar *high,
			const char *voltage_tile, Scalar *voltage_low,
			const char *leak_image, const char *lampA_image,
			const char *lampB_image, int onColor, int offColor,
			Subsystem *subsystem, const char *identification_string);
		~GeneratorCluster();					// @004c7778
	protected:
		char	*backgroundImage;				// @0x90  this[0x24]
		int		hostPortNumber;					// @0x94  this[0x25]
		GraphicGauge
				*temperatureBar,				// @0x98  this[0x26]  VertTwoPartBar
				*voltageBar,					// @0x9C  this[0x27]  ScalarBarGauge
				*leakGauge,						// @0xA0  this[0x28]  BitMapInverseWipe
				*lampA,							// @0xA4  this[0x29]  TwoState
				*lampB;							// @0xA8  this[0x2A]  TwoState
		Subsystem *subsystem;					// @0xAC  this[0x2B]
	};


	//#######################################################################
	// PrepEngrScreen -- builds the per-weapon "engineering" status screen.
	// @004c7b30 Make / @004c7bf0 ctor / @004c7d14 dtor.  vtable PTR_FUN_0051a06c.
	// Derives from the non-graphic Gauge group (FUN_004440d4) and interns seven
	// status pixmaps (this[0x1D..0x23]).  Make validates DAT_0051936c (engineer
	// screen number, must be 1..12; warns "PrepEngr: screen number out of range").
	// Execute @004c7e48 walks the mech's critical-subsystem roster (mech+0x124
	// count / mech+0x128 array) and, for each weapon on the selected screen,
	// renders its label & ammo via NumericDisplay, dispatching on subsystem
	// ClassID (0xBC3 Sensor, 0xBC6, 0xBC8/0xBD4 Emitter/PPC, 0xBCD/0xBD0
	// Projectile/Missile, 0xBCE GaussRifle -- "Gauss rifle not yet supported").
	//#######################################################################
	class PrepEngrScreen :
		public Gauge							// non-graphic Gauge group (FUN_004440d4)
	{
	public:
		static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *);	// @004c7b30
		PrepEngrScreen(							// @004c7bf0
			GaugeRate, ModeMask, L4GaugeRenderer *, int screen_number,
			Entity *mech, int graphics_port_number,
			const char *img0, const char *img1, const char *img2,
			const char *img3, const char *img4, const char *img5,
			const char *img6, const char *identification_string);
		~PrepEngrScreen();						// @004c7d14
		void	Execute();						// @004c7e48
	protected:
		Entity	*mech;							// @0x6C  this[0x1B]
		int		screenNumber;					// @0x70  this[0x1C]
		char	*statusImage[7];				// @0x74  this[0x1D..0x23]
		// child gauges chained in the base Gauge group at +0x24
	};


	//#######################################################################
	// SubsystemCluster family -- the big composite panels.  Each is a
	// GraphicGauge that builds a dozen child gauges into one cockpit instrument.
	//
	//   SubsystemCluster      @004c8140  (vtable 0051a020) -- base "engineering"
	//        panel: HorizTwoPartBar + cooling/power loops + generator voltage +
	//        OneOfSeveralInt + OneOfSeveralStates + 2x VertTwoPartBar + LeakGauge
	//        + BackgroundBitmap.  Uses the btXXloop / btXbus / evolt / btecmode /
	//        eleak palette files.  Reads InputVoltage/HeatSink/CurrentTemperature/
	//        DegradationTemperature/FailureTemperature attributes.
	//
	//   HeatSinkCluster       @004c8a6c  (vtable 00519fd4) : SubsystemCluster
	//        adds 4 failure-annunciator TwoStates (btehfail/btepfail/btesfail)
	//        and a NumericDisplayScalar.  Execute @004c8db0 scales this[0x35] by
	//        _DAT_004c8df0 into the numeric read-out.
	//
	//   WeaponCluster         @004c8fc4  (vtable 00519f38) : SubsystemCluster
	//        adds a SegmentArc270 (recharge dial, 0..360) + a ConfigMapGauge.
	//        Make-time warns "WeaponCluster missing <name>".  Reads "PercentDone".
	//        Execute @004c9290 toggles a warning lamp when this[0x36] > _DAT_004c92e0.
	//
	//        EnergyWeaponCluster   @004c93b0 (vtable 00519ee8) : WeaponCluster
	//            adds a SeekVoltageGraph ("EngrGraph", edestryd.pcc) and a
	//            seek-step OneOfSeveralInt (bteseek.pcc, subsys+0x3F0).
	//        BallisticWeaponCluster @004c9558 (vtable 00519e98) : WeaponCluster
	//            adds 2x NumericDisplayInteger (ammo), jam/fire TwoStates
	//            (btejam/btefire), NumericDisplayScalarTwoState, an eject
	//            BitMapInverseWipeScalar (bteejtm) reading subsys+0x3F8, plus a
	//            GraphicsViewRecord erase tracker (this[0x3F]).  Execute @004c9a38
	//            tracks weaponAlarm==5 (Jammed) and the ammo-bin link (+0x43C).
	//#######################################################################
	class SubsystemCluster :
		public GraphicGauge
	{
	public:
		SubsystemCluster(						// @004c8140
			GaugeRate, ModeMask, L4GaugeRenderer *, int,
			int x, int y, Subsystem *subsystem, GaugeRenderer *eng_renderer,
			const char *port_name, const char *tile_image,
			const char *background_image, int damage_zone_table,
			const char *identification_string);
		~SubsystemCluster();					// @004c87dc
		Logical	TestInstance() const;
		void	BecameActive();					// @004c88e4 (shared base Execute trampoline)
		void	Execute();						// @004c88e4
	protected:
		GraphicGauge
				*background,					// @0x90  this[0x24]  BackgroundBitmap
				*temperatureBar,				// @0x98  this[0x26]  HorizTwoPartBar
				*coolingLoopA,					// @0x9C  this[0x27]  AnimatedSubsystemLamp
				*coolingLoopB,					// @0xA0  this[0x28]
				*powerSourceA,					// @0xA4  this[0x29]
				*powerSourceB,					// @0xA8  this[0x2A]
				*vertBarA,						// @0xAC  this[0x2B]  VertTwoPartBar
				*vertBarB,						// @0xB0  this[0x2C]
				*modeLamp,						// @0xB4  this[0x2D]  OneOfSeveralInt
				*stateLamp,						// @0xB8  this[0x2E]  OneOfSeveralStates
				*leakGauge;						// @0xBC  this[0x2F]  LeakGauge
		Subsystem *subsystem;					// @0xC0  this[0x30]
		Logical	operating;						// @0xC4  this[0x31]
	};

	class HeatSinkCluster :						// @004c8a6c
		public SubsystemCluster
	{
	public:
		~HeatSinkCluster();						// @004c8d18
		void	Execute();						// @004c8db0
	protected:
		Subsystem *failSubsystem;				// @0xCC  this[0x33]
		Logical	failFlag;						// @0xD0  this[0x34]
		Scalar	heatLoad;						// @0xD4  this[0x35]
		Scalar	heatLoadScaled;					// @0xD8  this[0x36]
		GraphicGauge
				*heatFailLamp,					// @0xDC  this[0x37]  TwoState
				*hsFailLamp,					// @0xE0  this[0x38]  TwoState (btehfail)
				*powerFailLamp,					// @0xE4  this[0x39]  TwoState (btepfail)
				*structFailLamp,				// @0xE8  this[0x3A]  TwoState (btesfail)
				*heatNumeric;					// @0xEC  this[0x3B]  NumericDisplayScalar
	};

	class WeaponCluster :						// @004c8fc4
		public SubsystemCluster
	{
	public:
		~WeaponCluster();						// @004c91d4
		void	BecameActive();					// @004c9258
		void	Execute();						// @004c9290
		void	DrawWarningLamp(int color);		// @004c932c
	protected:
		char	*clusterImage;					// @0xCC  this[0x33]
		GraphicGauge *rechargeArc;				// @0xD0  this[0x34]  SegmentArc270
		ConfigMapGauge *configMap;				// @0xD4  this[0x35]
		Scalar	percentDone;					// @0xD8  this[0x36]  (connection dst)
		int		warningCenterX;					// @0xDC  this[0x37]
		int		warningCenterY;					// @0xE0  this[0x38]
		int		warningState;					// @0xE4  this[0x39]
	};

	class EnergyWeaponCluster :					// @004c93b0
		public WeaponCluster
	{
	public:
		~EnergyWeaponCluster();					// @004c94dc
	protected:
		SeekVoltageGraph *seekGraph;			// @0xE8  this[0x3A]
		GraphicGauge	 *seekStepLamp;			// @0xEC  this[0x3B]  OneOfSeveralInt
	};

	class BallisticWeaponCluster :				// @004c9558
		public WeaponCluster
	{
	public:
		~BallisticWeaponCluster();				// @004c9940
		void	BecameActive();					// @004c99cc
		void	Execute();						// @004c9a38
		Logical	TestInstance() const;			// @004c9adc
	protected:
		Logical	jammed;							// @0xE8  this[0x3A]
		Logical	firing;							// @0xEC  this[0x3B]
		Logical	reloading;						// @0xF0  this[0x3C]
		int		reloadStartTime;				// @0xF4  this[0x3D]
		Scalar	reloadSeconds;					// @0xF8  this[0x3E]
		GraphicsViewRecord
				*ammoErase;						// @0xFC  this[0x3F]
		GraphicGauge
				*ammoNumeric,					// @0x100 this[0x40]  NumericDisplayScalarTwoState
				*destroyedLamp,					// @0x104 this[0x41]  TwoState
				*jamLamp,						// @0x108 this[0x42]  TwoState (btejam)
				*fireLamp,						// @0x10C this[0x43]  TwoState (btefire)
				*ejectWipe,						// @0x110 this[0x44]  BitMapInverseWipeScalar
				*ammoCountA,					// @0x114 this[0x45]  NumericDisplayInteger
				*ammoCountB;					// @0x118 this[0x46]  NumericDisplayInteger
	};

#endif
