/*******************************************************************************
 *	Tests.h	Signal Generator classes
 *			T.Barnaby,	BEAM Ltd,	2006-09-12
 *******************************************************************************
 */

#ifndef Tests_h
#define Tests_h	1

#include <BError.h>
#include <BFile.h>
#include <SigGen.h>
#include <Da8150.h>

class TestParam {
public:
			TestParam(BString name = "", BString value = "");
	BString		name;
	BString		value;	
};

class TestParams : public BList<TestParam> {
public:
	BString		getValue(BString name);
	void		setValue(BString name, BString value);
};

class Test {
public:
				Test(BString name);
	virtual			~Test();
	
	virtual BString		name();
	virtual BString		info();
	virtual BError		init(TestParams& params);
	virtual void		close();
	virtual BError		run();

	virtual BError		output(BSignalList& sigs);

protected:
	BString			oname;
	BString			oinfo;
	TestParams		oparams;
	double			osampleRate;
	double			oamplitude;
	BString			ofileName;
	BString			ofileType;
	BSignalList		osigList;
	
	Da8150			owgen;
	BFile			ofile;
	uint64_t		ox;
};

class TestSine : public Test {
public:
			TestSine();
			~TestSine();

	BError		run();
	
protected:
	double		ofreq;
};

class TestSquare : public Test {
public:
			TestSquare();
			~TestSquare();

	BError		run();
	
protected:
	double		ofreq;
};

class TestBeam : public Test {
public:
			TestBeam(BString name = "");
			~TestBeam();

	BError		init(TestParams& params);
	BError		run();
	
protected:
	uint32_t	numLoops(double fref, int ms);
	int		addCycleNone(int numRepeat, int next);
	int		addCycleBlank(int numRepeat, int next);
	int		addCycleStart(int numRepeat, int next);
	int		addCycleStartMulti(int numRepeat, int next);
	int		addCyclePreInjection(int numRepeat, int next);
	int		addCycleInjection(int numRepeat, int next);
	int		addCycleBeam(int numRepeat, int next, int harmonic, int numBunches, int hchange, double reduce);
	int		addCycleStop(int numRepeat, int next);

protected:
	double		ofref;
	double		osysClock;
	uint32_t	onumSamples;
};

class TestBeam1 : public TestBeam {
public:
			TestBeam1();

	BError		run();
};

class TestBeam2 : public TestBeam {
public:
			TestBeam2();

	BError		run();
};

class TestBeam3 : public TestBeam {
public:
			TestBeam3();

	BError		run();
};

class TestBeam4 : public TestBeam {
public:
			TestBeam4();

	BError		run();
};

class TestMulti : public TestBeam {
public:
			TestMulti();

	BError		run();
};

BList<Test*>&	testsInit();

#endif
