#ifndef SWISSSPADSTREAM_H
#define SWISSSPADSTREAM_H

#include <string>
#include "fx3stream.h"
#include "fx3utils.h"

#include <iostream>
using namespace std;

class SwissSPADStream : public FX3Stream {
public:
    static const unsigned HIGH_REG;

    static const unsigned CLOCK_ADR;
    static const unsigned GETCLKSTATUS_CMD;
    static const unsigned GETCLKFREQ_CMD;
    static const unsigned SWITCHCLK_REG;
    static const unsigned PROGCLK_REG;
    static const unsigned SHIFTCLK_REG;

    static const unsigned SHUTTER_ADR;
    static const unsigned SHUTTER_FLAGS_REG;
    static const unsigned SHUTTER_HOLDOFF_REG;

    static const unsigned MAIN_ADR;
    static const unsigned DUMP_CMD;
    static const unsigned MEMCLR_CMD;
    static const unsigned CAPSTART_CMD;
    static const unsigned ROWLIMITS_REG;
    static const unsigned DEFAULT_DELAY;
    static const unsigned READOUT_PARAM_REG;
    static const unsigned MAXCOUNT_REG;
    static const unsigned IMAGE_LENGTH_REG;
    static const unsigned FLAGS_REG;
    static const unsigned FRAME_DELAY_REG;
    static const unsigned INTER_FRAME_DELAY_REG;
    static const unsigned IMAGE_COUNT_REG;
    static const unsigned DESCRAMBLER_REG;

    SwissSPADStream();
    
    void descramblerOn();
    void descramblerOff();
    void readMem( unsigned bitwidth = 8 );
    void clrMem();
    void setRowLimits( unsigned min=0, unsigned max=127 );
    void setMemIncDelay( unsigned delay = DEFAULT_DELAY );
    void setBitWidth( unsigned bitwidth = 8 );
    void setMaxCount( unsigned count );
    void incMem( unsigned count );
    void startCap();
    void incRows( unsigned count, unsigned low, unsigned high );
    void updateTiming( unsigned config );
    uint32_t getSystemID( bool quiet = true );
    unsigned int getStatus( bool quiet = true );
    uint32_t incShift( unsigned amount, bool quiet = true );
    uint32_t decShift( unsigned amount, bool quiet = true );
    void setMultiFrameMode( bool flag = false );
    void setSoftRate( bool flag = false );
    void setResetBeforeFrame( bool flag = false );
    void setShiftMode( bool flag = false );
    void shutterIdleState( unsigned state );
    void setContShutter( bool flag = false );
    void setClassicShutter( bool flag = false );
    void setShutterHoldoff( unsigned value );
    void setFrameDelay( unsigned value );
    void setInterFrameDelay( unsigned value );
    void setImageCount( unsigned value );
    void setImageLength( unsigned value );
    void setShift( unsigned value );
    void set_classic_shutter( unsigned length, unsigned repetitions,
        unsigned spadoff_on_value, unsigned spadoff_off_value,
        unsigned recharge_on_value, unsigned recharge_off_value,
        unsigned gate_on_value, unsigned gate_off_value );
    void set_laser_shutter( unsigned length, unsigned repetitions,
        unsigned long long spadoff, unsigned long long recharge, unsigned long long gate );
    int syncLaserClock( bool sync );
};

#endif // SWISSSPADSTREAM_H

