#pragma once

#include "vtvsub.h"
#include "..\munga\average.h"

//##########################################################################
//################    VTVControlsMapper::ModelResource    ##################
//##########################################################################

class VTVControlsMapper:
	public VTVSubsystem
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
	static Derivation *GetClassDerivations();
	static SharedData DefaultData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Messaging Support
//
public:
	enum {
		ConfigureControlsMessageID = VTVSubsystem::NextMessageID,
		ConfigureSideSlipMappablesMessageID,
		ChooseSideSlipMessageID,
		ConfigureLiftCutMappablesMessageID,
		ChooseLiftCutMessageID,
		ConfigureHornMappablesMessageID,
		ChooseHornMessageID,
		ActivateHornMessageID,
		ConfigurePTTMappablesMessageID,
		ChoosePTTMessageID,
		ActivatePTTMessageID,
		ToggleReticleMessageID,
		NextMessageID
	};

	void
		ConfigureControlsMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ConfigureSideSlipMappablesMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ChooseSideSlipMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ConfigureLiftCutMappablesMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ChooseLiftCutMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ConfigureHornMappablesMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ChooseHornMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ActivateHornMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ConfigurePTTMappablesMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ChoosePTTMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ActivatePTTMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);
	void
		ToggleReticleMessageHandler(
			ReceiverDataMessageOf<ControlsButton> *message
		);

private:
	static const HandlerEntry MessageHandlerEntries[];

protected:
	//static MessageHandlerSet MessageHandlers;
	static MessageHandlerSet& GetMessageHandlers();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
	enum {
		StickPositionAttributeID = VTVSubsystem::NextAttributeID,
		ThrottlePositionAttributeID,
		PedalsPositionAttributeID,
		ReverseThrustAttributeID,
		LiftCutAttributeID,
		SideSlipAttributeID,
		PowerDemandAttributeID,
		AngularVelocityDemandAttributeID,
		BrakeLightsAttributeID,
		LookLeftAttributeID,
		LookRightAttributeID,
		LookBehindAttributeID,
		LookUpAttributeID,
		ControlModeAttributeID,
		HornBlastAttributeID,
		MustMatchAttributeID,
		ReverseThrustEngagedAttributeID, // ECH 8/3/95 - HACK - deal with thrust
		LiftCutEngagedAttributeID,
		PTTStatusAttributeID,
		NextAttributeID
	};

private:
	static const IndexEntry AttributePointers[];

protected:
	//static AttributeIndexSet	AttributeIndex
	static AttributeIndexSet& GetAttributeIndex();

//
// public attribute declarations go here
//
public:
	ControlsJoystick	stickPosition;
	Scalar				throttlePosition;
	Scalar				pedalsPosition;
	ControlsButton
		reverseThrust,
		liftCut,
		sideSlip,
		rollLeft,
		rollRight,
		pitchUp,
		pitchDown;
	Vector3D
		powerDemand,
		angularVelocityDemand;

	int brakeLights;
	ControlsButton
		lookLeft,
		lookRight,
		lookBehind,
		lookUp,
		hornBlast,
		pttStatus;

	// ECH 8/3/95 - HACK - deal with thrust
	AverageOf<Scalar>
		averageOfForwardThrustDemand;
	Scalar
		forwardThrustDemand;
	Logical
		reverseThrustEngaged;

	Logical
		liftCutEngaged;

	enum {
		BasicMode = 0,
		StandardMode,
		VeteranMode,
		MasterMode
	}
		controlMode;

	unsigned int
		mustMatch,
		mayMatch;

protected:
	ControlsButton
		previousPTTStatus;		// used to detect change in PTT status

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
public:
	enum {
		ConfigurationState = VTVSubsystem::StateCount,
		StateCount
	};

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

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

	void
		InterpretControls(Scalar time_slice);
	void
		SetConfigurationState(Logical enter_config);

	virtual void
		CreateTemporaryEventMappings(
			Receiver *receiver,
			Receiver::MessageID config_message_id
		),
		RemoveTemporaryEventMappings(),
		AddOrErase(
			unsigned int button_ID,
			Receiver *target,
			Receiver::MessageID message_ID
		),
		AddOrErase(
			unsigned int button_ID,
			ControlsButton *destination
		);

	virtual void
		NotifyOfControlModeChange(int new_mode);

	virtual void
		NotifyOfConfigurationModeChange(Logical new_state);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	VTVControlsMapper(
		VTV *owner,
		int subsystem_ID,
		SubsystemResource *subsystem_resource,
		SharedData &shared_data
	);
	~VTVControlsMapper();

	Logical
		TestInstance() const;
};
