#pragma once

#include "..\munga\icom.h"
#include "l4ctrl.h"
#include "..\munga\time.h"

//##########################################################################
//############################    L4Icom    ################################
//##########################################################################
class L4Icom:
	public Icom
{
	friend class L4IcomManager;

public:
	L4Icom(HostID host_id, int channel_offset);
	~L4Icom();		// base destructor is virtual
	Logical
		TestInstance() const;

	//--------------------------------------------------
	// Channel offset accessor
	//--------------------------------------------------
	int
		GetChannelOffset()
			{
				Check(this);
				return channelOffset;
			}
	//--------------------------------------------------
	// public data
	//--------------------------------------------------
	ControlsButton
		pttButton;

	enum
	{
		numberOfChannels=7
	};

protected:
	//--------------------------------------------------
	// These methods are used to locally set the value
	// for the channel, PTT, and PA status.
	//
	// The difference between these methods and the
	// public methods defined in the base class is that
	// these methods are called by both the base class
	// public routines and the event receiver to actually
	// set the values involved.  Making them virtual
	// allows derived classes to be notified of changes
	// (but also requires that all derived classes
	// explicitly call the overridden methods!)
	//--------------------------------------------------
	void
		SetChannelValue(int new_channel);		// base method is virtual
	void
		SetPTTStatusValue(Logical new_ptt);		// base method is virtual
	void
		SetPACaptiveValue(Logical new_pa);		// base method is virtual
	//--------------------------------------------------
	// Recalibrate hardware
	//--------------------------------------------------
	void
		Recalibrate();
	//--------------------------------------------------
	// Hardware control method
	//--------------------------------------------------
	void
		Update(Scalar delta_t);

private:
	Logical
		WaitedLongEnough(Scalar how_long);
	void
		IncrementChannel();
	void
		DecrementChannel();
	void
		ChannelStatusUpdate();
	void
		ChannelSelectState(Logical state);
	//--------------------------------------------------
	// Protected data
	//--------------------------------------------------
protected:
	LBE4ControlsManager
		*controlsManager;

	ControlsButton
		homeSensor,
		channelButton;
	Scalar
		timeAccumulator;
	int
		hardwareChannel,
		previousChannel,
		channelOffset,
		seekCount;
	int
		previousPTTStatus;
	Logical
		channelSelectEnabled,
		seekRequired;
	enum
	{
		disabled = -2,
		failed = -1,
		seek40,
		offChannel,
		reachedChannel,
		onChannel,
	}
	state;
};

//##########################################################################
//########################    L4IcomManager    #############################
//##########################################################################
class L4IcomManager:
	public IcomManager
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared data Support
//
public:
	static Derivation *GetClassDerivations();
	static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	L4IcomManager(
		SharedData &shared_data=DefaultData
	);
	~L4IcomManager();		// base destructor is virtual

	Logical
		TestInstance() const;

	L4Icom *
		MakeIcom(HostID host_id, int unit_number=0);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LoadMission, Shutdown methods
// ...these are declared virtual in ICOM.HPP and must chain back to
// the previous methods.
//
public:
	void
		LoadMission(Mission *mission);
	void
		Shutdown();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Periodic update function
//
	void
		Execute();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// protected data
//
protected:
	Time
		previousUpdateTime;

	SlotOf<L4Icom*>
		localIcom;
};
