#ifndef _TDevice_h__
#define _TDevice_h__

#include <stdint.h>

#include <QMetaType>
#include <QString>
#include <QVector>

class TProvider;
class TChannel;
class TDevice;

#include "TChannel.h"
#include "TProvider.h"
#include "source.h"

class TDevice {

  public:
    enum Event { NONE, ADD, REMOVE, CONNECT, DISCONNECT, UPDATE };

    static const QString TICKER_SERIAL_NUMBER;
    static const QString TICKER_CHANNEL_ID;

    TDevice(TProvider *provider, const QString &serialNumber, const QString &productName, const Version &version);
    TDevice(TProvider *provider, Source *source);
    TDevice(const TDevice &device);
    virtual ~TDevice();

    TDevice &operator=(const TDevice &device) = delete;

    void update(const TDevice *device);
    void update(Source *source);

    bool isAlive() const;
    bool isLocal() const;
    bool isLocalTenkinet() const { return _isLocalTenkinet; };
    bool isTenkinet() const;
    bool isMath() const;
    bool isTicker() const;
    bool isSpecial() const;

    bool isUserCalibrationSupported(int index) const;
    bool isUserCalibrationEnabled(int index) const;

    void setAlive(bool alive);

    void setLocalTenkinet() { _isLocalTenkinet = true; }

    void convertUnits();
    void invalidate();

    TProvider *provider;

    const QString serialNumber;
    const QString productName;
    const Version version;

    uint8_t event;
    uint8_t port;
    uint32_t flags;
    int64_t timestamp;

    QVector<TChannel *> channels;

  private:
    bool _isLocalTenkinet{false};

    // 1 bit per channel, indicating whether user calibration is enabled
    uint32_t user_calibration_enabled[((DEVICE_MAX_CHANNELS - 1) / 32) + 1];
};

#endif
