/*******************************************************************************
 *	PuServer.h	PuServer process
 *			T.Barnaby,	BEAM Ltd,	2007-02-15
 *******************************************************************************
 */
#ifndef PuServer_H
#define PuServer_H	1

#include <stdint.h>
#include <TmsD.h>
#include <TmsC.h>
#include <BError.h>
#include <BMutex.h>

class Control;

using namespace Tms;

class PuServerConnection {
public:
	BMutex			olock;
	PuControl		opuControl;
	PuProcess		opuProcess;
};

/// The main system PuServer class
class PuServer {
public:
			PuServer(Control& control, BUInt32 number, int physNumber);
			~PuServer();

	// Main functionality	
	BError		init();				///< Initialise the system
	BError		disconnect();			///< Disconnect
	BError		status();			///< Status of PuServer

	BUInt32		getNumber();			///< Gets the number of this module
	BError		initCmd();					///< Initialise command
	BError		configure(BUInt ring, ConfigInfo configInfo);		///< Configure the system for use. This includes mapping the individual physical PickUp channels to logical pickup channels.
	BError		test(BList<BError>& errors);			///< Performs a basic test of the system returning a list of errors. The call will return an error object indicating success or an error condition as appropriate.
	BError		getStatus(BList<NameValue>& statusList);	///< Returns the current status of the system. This information includes the number of Pick­Up\u2019s present and their individual status.
	BError		getStatistics(BList<NameValue>& statsList);	///< Returns a list of the statistic values as name/value pairs. The call will return an error object indicating success or an error condition as appropriate.
	BError		getMasterPuChannel(PuChannel& puChannel);
	
	// Test functions
	BError		setTestMode(PuChannel puChannel, BUInt32 testOutput, BUInt32 timingDisableMask);	///< The signal source for the digital test output connector. 0: None, 1: FrefDelayed, 2: PllFRef, 3: PllFRefHarm. The timingDisableMask bit mask defines which of the timing inputs should be disabled. If a timing input is disabled it can be still operated by software command.
	BError		setTimingSignals(PuChannel puChannel, BUInt32 timingSignals);			///< This function sets the given timing signals to the values as defined in the timingSignals bit array.
	BError		captureDiagnostics(PuChannel puChannel, TestCaptureInfo captureInfo, BArray<BUInt64>& data);	///< This function will capture test data
	BError		setTestData(PuChannel puChannel, BInt32 on, BArray<BUInt32> data);	///< This function will set a PU channel to sample data from memory rather than the ADC's
	BError		setPupeConfig(PuChannel puPhysChannel, PupeConfig pupeConfig);
	BError		getPupeConfig(PuChannel puPhysChannel, PupeConfig& pupeConfig);

	BError		setControlInfo(CycleParam params);			///< Sets the control information for the cycle number given and subsequent cycles. The parameters for the processing cycle are passed, this includes the Phase and State table information. The call will return an error object indicating success or an error
	BError		setNextCycle(BUInt32 cycleNumber, BString cycleType);			///< Sets the cycle number for the next processing cycle. The call will return an error object indicating success or an error condition as appropriate. This should be called at least 100ms before the next CYCLE_START event.
	BError		getStatus(PuChannel puChannel, PuStatus& puStatus);
	BError		getCycleInformation(BUInt32 cycleNumber, CycleInformation& cycleInformation);
	BError		getData(PuChannel puChannel, DataInfo dataInfo, Data& data, BUInt32& orbitNumber);	///< This function returns a set of data from the data present in the data cache or directly from the Pick-Up processing engines. The  DataInfo object describes the data required. The call will return the required data along with an error object indicating success or an error condition as appropriate. The call will block until data is ready.
	BError		requestData(PuChannel puChannel, DataInfo dataInfo);		///< This adds a request for some data. The DataInfo object defines the data required. This request can be made at any time. If the data is present in cache the data will be available immediately, if not the system will await the data from a subsequent processing cycle. When the data is available a "data" event will be sent to the client. Not that it is not necessary to use requestData. The client can call getData() directly although this call will block until the data is actually ready.


private:
	BError		handleError(BError err, int e);

	// PuServer data
	Control&			ocontrol;		///< The main Control class
	BUInt32				onumber;
	BString				ophysNumber;
	BList<PuServerConnection*>	oconns;
	PuControl			opuControl;
	PuProcess			opuProcess;
	PuControl			opuControl1;
	PuProcess			opuProcess1;
	BError				oerr;
};

#endif
