#ifndef TESTDATAGENERATOR_H
#define TESTDATAGENERATOR_H

#include <QObject>

class RepFpgaProgramData;

class TestDataGenerator: public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString name READ name)

public:
    explicit TestDataGenerator(QObject* parent=0);
    virtual ~TestDataGenerator();


    virtual void initialize();

    virtual unsigned int formatMarker() const;

    virtual void reinit();

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual unsigned int generateNextBatchExt(void* header, void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual bool completed() const;

    virtual int batchCounter() const;

    virtual bool stop();

    QString name() const;

protected:
    int batch_counter;
    QString m_name;
};


class DbsTestDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(QString fileName READ fileName WRITE setFileName)

public:
    explicit DbsTestDataGenerator(QObject* parent=0);
    ~DbsTestDataGenerator();

    virtual void initialize() override;

    virtual unsigned int formatMarker() const override;

    virtual void reinit() override;

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg) override;

    virtual bool completed() const override;

    QString fileName() const;
    void setFileName(const QString&);

private:
    class Implementation;
    Implementation& p_;
};


class SarTestDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(QString fileName READ fileName WRITE setFileName)
    Q_PROPERTY(int numberOfBatches READ numberOfBatches)

public:
    SarTestDataGenerator(QObject* parent=0);
    ~SarTestDataGenerator();

    virtual void initialize();

    virtual unsigned int formatMarker() const override;

    virtual void reinit();

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual bool completed() const;

    int numberOfBatches() const;

    QString fileName() const;
    void setFileName(const QString&);

private:
    class Implementation;
    Implementation& p_;
};

class FakeRbmTestDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(QString imgFileName READ imgFileName WRITE setImgFileName)
    Q_PROPERTY(Pattern pattern READ pattern WRITE setPattern)

public:
    enum Pattern { vect, img, pat1, pat2, pat3 };
    Q_ENUM(Pattern)

    FakeRbmTestDataGenerator(DbsTestDataGenerator* dbg, QObject* parent=0);
    ~FakeRbmTestDataGenerator();

    virtual void initialize();

    virtual void reinit();

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual bool completed() const;

    int numberOfBatches() const;

    virtual unsigned int formatMarker() const override;

    QString imgFileName() const;
    void setImgFileName(const QString&);

    Pattern pattern() const;
    void setPattern(Pattern);

private:
    class Implementation;
    Implementation& p_;
};

class TgtTestDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(Pattern pattern READ pattern WRITE setPattern)

public:
    enum Pattern { img, pat1, pat2, pat3 };
    Q_ENUM(Pattern)

    TgtTestDataGenerator(QObject* parent=0);
    ~TgtTestDataGenerator();

    virtual void initialize();

    virtual void reinit();

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual bool completed() const;

    int numberOfBatches() const;


    Pattern pattern() const;
    void setPattern(Pattern);

private:
    class Implementation;
    Implementation& p_;
};

class AdTestDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(float cwFrequency READ cwFrequency WRITE setCwFrequency)
    Q_PROPERTY(float noiseFrequency READ noiseFrequency WRITE setNoiseFrequency)
    Q_PROPERTY(float noiseLevel READ noiseLevel WRITE setNoiseLevel)
    Q_PROPERTY(float cwJitter READ cwJitter WRITE setCwJitter)
    Q_PROPERTY(float phaseJitter READ phaseJitter WRITE setPhaseJitter)
    Q_PROPERTY(float spuriousFrequency READ spuriousFrequency WRITE setSpuriousFrequency)

public:
    AdTestDataGenerator(QObject* parent=0);
    ~AdTestDataGenerator();

    unsigned int formatMarker() const override;

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg);

    virtual bool completed() const;

    int numberOfBatches() const;

    float noiseFrequency() const;
    void setNoiseFrequency(float);
    float noiseLevel() const;
    void setNoiseLevel(float);


    float phaseJitter() const;
    void setPhaseJitter(float);

    float cwFrequency() const;
    void setCwFrequency(float);

    float cwJitter() const;
    void setCwJitter(float);

    float spuriousFrequency() const;
    void setSpuriousFrequency(float);

private:
    class Implementation;
    Implementation& p_;
};

class PlaybackDataGenerator: public TestDataGenerator
{
    Q_OBJECT

    Q_PROPERTY(QString fileName READ fileName WRITE setFileName)
    Q_PROPERTY(int ch READ ch WRITE setCh)

public:
    explicit PlaybackDataGenerator(QObject* parent=0);
    ~PlaybackDataGenerator();

    virtual void initialize() override;

    virtual unsigned int formatMarker() const override;

    virtual void reinit() override;

    virtual unsigned int generateNextBatchExt(void* header, void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg) override;

    virtual unsigned int generateNextBatch(void* data, unsigned int max_data_size, const RepFpgaProgramData* cfg) override;

    virtual bool completed() const override;

    QString fileName() const;
    void setFileName(const QString&);

    int ch() const;
    void setCh(int n);

private:
    class Implementation;
    Implementation& p_;
};

#endif // TESTDATAGENERATOR_H
