//===========================================================================//
// File:	btl4mppr.hpp                                                        //
// Project: BattleTech           Brick: BattleTech LBE Application            //
// Contents: The L4-application-side Mech controls mappers -- the platform     //
//           (cockpit-hardware) layer that wires physical Thrustmaster / RIO   //
//           panel inputs onto the in-Mech MechControlsMapper demands, the     //
//           target-range zoom, control/display modes and the pilot hotbox.    //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
//                                                                           //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
//
// RECONSTRUCTED -- no header survived for this TU.  BTL4.MAK lists btl4mppr.obj
// and the class names are recovered from the .rdata string pool
// ("L4MechControlsMapper" @0051e1eb, "MechThrustmasterMapper" @0051e2b3,
// "MechRIOMapper" @0051e2e3).  The shape mirrors the surviving Red Planet
// analog RP_L4\RPL4MPPR.h (L4VTVControlsMapper / VTVThrustmasterMapper /
// VTVRIOMapper) -- the only substitution is Mech for VTV and the in-Mech base
// MechControlsMapper (mechmppr.cpp) for VTVControlsMapper.
//
// Hierarchy (parallels RP exactly):
//   Subsystem -> MechControlsMapper [mechmppr.cpp, already recovered]
//             -> L4MechControlsMapper [this TU]   ctor @004d17ac vtable @0051e440
//                ├─ MechThrustmasterMapper        ctor @004d21d0 vtable @0051e3f0
//                └─ MechRIOMapper                 ctor @004d266c vtable @0051e3a0
//

#if !defined(BTL4MPPR_HPP)
#	define BTL4MPPR_HPP

#	if !defined(MECHMPPR_HPP)
#		include <mechmppr.hpp>
#	endif

	class Mech;
	class L4Lamp;

	//
	// ClassID stamped onto the in-Mech controls-mapper subsystem (the
	// class_ID passed to the L4MechControlsMapper ctor).  Recovered as 0x7dc
	// (@004d21d0 / @004d266c call sites in btl4app.cpp).
	//
	enum { MechControlsMapperClassID = 0x7dc };

	//##########################################################################
	//####################    L4MechControlsMapper    ##########################
	//##########################################################################
	//
	// The platform-independent L4 layer.  Adds the target-range "zoom"
	// (exponential, driven from the panel), the mission-review mode watcher,
	// and the configuration-time temporary event mappings.  Pure-platform
	// behaviour (which physical buttons do what) is supplied by the two
	// derived mappers below.
	//
	class L4MechControlsMapper:
		public MechControlsMapper
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Shared Data Support
	//
	public:
		// WinTesla refactored the static derivation/handler objects behind
		// Get* accessors (avoids static-init ordering bugs).
		static Derivation	*GetClassDerivations();
		static SharedData	DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Messaging Support
	//
	public:
		enum {
			KeypressMessageID = MechControlsMapper::NextMessageID,
			StringMatchMessageID,
			NextMessageID
		};

		void
			KeypressMessageHandler(				// @004d1bf0
				ReceiverDataMessageOf<ControlsKey> *message
			);

	protected:
		static const HandlerEntry MessageHandlerEntries[];
		static MessageHandlerSet& GetMessageHandlers();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Model Support
	//
	public:
		void
			InterpretControls(Scalar time_slice);		// @004d196c

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Target-range "zoom"
	//
	public:
		void
			ZoomTargetRangeIn(),				// @004d1b64
			ZoomTargetRangeOut();				// @004d1b9c

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Control / display modes
	//
	public:
		void
			SetControlMode(int new_mode);		// @004d1ae4 (mode-mask switch)
		void
			SetPresetMode(int group, int item);	// @004d1b24 (preset mode-mask)

		void
			NotifyOfControlModeChange(int new_mode),		// @004d195c (no-op)
			NotifyOfConfigurationModeChange(Logical new_state);	// @004d1964 (no-op)

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Configuration support (overrides MechControlsMapper traps)
	//
	public:
		void
			CreateTemporaryEventMappings(		// @004d1840
				Receiver *receiver,
				Receiver::MessageID config_message_id
			),
			RemoveTemporaryEventMappings();		// @004d18dc

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction and Destruction Support
	//
	public:
		L4MechControlsMapper(					// @004d17ac
			Mech *owner,
			int subsystem_ID,
			SubsystemResource *subsystem_resource,
			ClassID class_ID,
			SharedData &shared_data = DefaultData
		);
		~L4MechControlsMapper();				// @004d1814

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Protected data  (object grows to >= 0x1bc)
	//
	protected:
		Scalar
			targetRangeExponentDemand,	// @0x1a0  panel "zoom" demand (init 2.0, range 0..5)
			targetRangeExponent;		// @0x1a4  smoothed value -> mech target range (2^x)
		int
			previousMissionReviewMode;	// @0x1a8  last-seen mech mission-review flag

		//
		// Per-platform input staging slots (filled by the derived ctor's
		// controls-group .Add()s; the two platforms use them differently --
		// Thrustmaster routes throttle scalars here, the RIO routes panel
		// buttons here).  Cleared to 0 by both derived ctors.
		//
		ControlsScalar
			throttleForward;			// @0x1ac
		// NOTE (engine drift): the recovered code staged the reverse throttle in
		// a ControlsScalar mapped to a "ScalarThrottleReverse" group that does
		// NOT exist in the WinTesla LBE4ControlsManager.  Reverse is a button in
		// this engine generation, so this slot is a ControlsButton mapped to
		// LBE4ControlsManager::ButtonThrottle1 (mirrors the era's L4MPPR.CPP).
		ControlsButton
			throttleReverse;			// @0x1b0
		ControlsScalar
			leftPedal,					// @0x1b4
			rightPedal;					// @0x1b8
	};

	//##########################################################################
	//####################    MechThrustmasterMapper    ########################
	//##########################################################################
	//
	// Joystick + throttle + pedals "Thrustmaster" cockpit.  Maps the analog
	// throttle / pedal axes and the PC keyboard onto the Mech demands.
	//
	class MechThrustmasterMapper:
		public L4MechControlsMapper
	{
	public:
		static Derivation *GetClassDerivations();	// @0051dc78
		static SharedData DefaultData;			// @0051dcxx

		typedef void
			(MechThrustmasterMapper::*Performance)(Scalar time_slice);

		void
			InterpretControls(Scalar time_slice);	// @004d2150

		void
			SetPerformance(Performance performance)
				{
					Check(this);
					activePerformance = (Simulation::Performance)performance;
				}

	protected:
		static const HandlerEntry MessageHandlerEntries[];	// {Keypress, 0x17}
		static MessageHandlerSet MessageHandlers;

	public:
		MechThrustmasterMapper(					// @004d21d0
			Mech *owner,
			int subsystem_ID,
			SubsystemResource *subsystem_resource,
			ClassID class_ID,
			SharedData &shared_data = DefaultData
		);
		~MechThrustmasterMapper();				// @004d22b4

		Logical
			TestInstance() const;				// @004d22e0
	};

	//##########################################################################
	//###########################    MechRIOMapper    ##########################
	//##########################################################################
	//
	// The full "RIO" / Cockpit panel: aux-equipment quadrant buttons, target
	// hotbox, target-range zoom, control-mode and preset selection.
	//
	class MechRIOMapper:
		public L4MechControlsMapper
	{
	public:
		static Derivation *GetClassDerivations();	// @0051dd00
		static SharedData DefaultData;			// @0051dcxx

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Messaging Support
	//
	public:
		enum {
			Aux1QuadMessageID = L4MechControlsMapper::NextMessageID,	// 3
			Aux1Eng1MessageID, Aux1Eng2MessageID, Aux1Eng3MessageID, Aux1Eng4MessageID,
			Aux2QuadMessageID, Aux2Eng1MessageID, Aux2Eng2MessageID, Aux2Eng3MessageID, Aux2Eng4MessageID,
			Aux3QuadMessageID, Aux3Eng1MessageID, Aux3Eng2MessageID, Aux3Eng3MessageID, Aux3Eng4MessageID,
			ZoomInMessageID,				// 0x12
			ZoomOutMessageID,				// 0x13
			HotboxMessageID,				// pilot-target select
			NextMessageID
		};

		void
			Aux1QuadMessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d22fc
			Aux1Eng1MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d231c
			Aux1Eng2MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d233c
			Aux1Eng3MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d235c
			Aux1Eng4MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d237c
			Aux2QuadMessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d239c
			Aux2Eng1MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d23bc
			Aux2Eng2MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d23dc
			Aux2Eng3MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d23fc
			Aux2Eng4MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d241c
			Aux3QuadMessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d243c
			Aux3Eng1MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d245c
			Aux3Eng2MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d247c
			Aux3Eng3MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d249c
			Aux3Eng4MessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d24bc
			ZoomInMessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d24dc
			ZoomOutMessageHandler(ReceiverDataMessageOf<ControlsButton> *message),	// @004d24f8
			HotboxMessageHandler(ReceiverDataMessageOf<ControlsButton> *message);	// @004d2574

	protected:
		static const HandlerEntry MessageHandlerEntries[];	// @0051dd30
		static MessageHandlerSet MessageHandlers;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Model Support
	//
	public:
		typedef void
			(MechRIOMapper::*Performance)(Scalar time_slice);

		void
			InterpretControls(Scalar time_slice);	// @004d25c0

		void
			SetPerformance(Performance performance)
				{
					Check(this);
					activePerformance = (Simulation::Performance)performance;
				}

		void
			AddOrErase(								// @004d25e8
				unsigned int button_ID,
				Receiver *target,
				Receiver::MessageID message_ID
			);
		void
			AddOrErase(								// @004d262c
				unsigned int button_ID,
				ControlsButton *destination
			);

	public:
		MechRIOMapper(							// @004d266c
			Mech *owner,
			int subsystem_ID,
			SubsystemResource *subsystem_resource,
			ClassID class_ID,
			SharedData &shared_data = DefaultData
		);
		~MechRIOMapper();						// @004d27cc

		Logical
			TestInstance() const;				// @004d27f8
	};

#endif
