#ifndef __DataTable_h_
#define __DataTable_h_

#include <stdint.h>

#include <QHash>
#include <QLinkedList>
#include <QMap>
#include <QString>
#include <QVector>

#include "quantity.h"

class DataTable;

class DataRow {

    friend class DataTable;

    DataRow(DataTable *table, int64_t timestamp, int n);
    virtual ~DataRow();

    DataTable *table;
    int64_t timestamp;
    Quantity *quantities;
    int emptyCounter;
    int errorCounter;

    bool set(int col, const Quantity &qty);
    bool clear(int col);

  public:
    bool isEmpty(int col) const;
    bool isEmpty(const QString &id) const;

    bool isError(int col) const;
    bool isError(const QString &id) const;

    const Quantity &getQuantity(int col) const;
    const Quantity &getQuantity(const QString &id) const;

    int64_t getTimestamp() const;

    void print() const;
};

class DataTable {

    friend class DataRow;

    const int columnCount;

    QHash<QString, int> columnByID;
    QLinkedList<DataRow *> rows;
    QHash<int64_t, DataRow *> rowByTimestamp;
    DataRow *completeRow;

    QVector<int64_t> disconnectionTimestamps;
    int disconnectionCount;

    QVector<Quantity> latestQuantities;

    DataRow *addRow(int64_t timestamp);

  public:
    DataTable(const QVector<QString> &ids, bool connected = true);
    virtual ~DataTable();

    int getColumnCount() const;

    int getRowCount() const;

    int getDisconnectionCount() const;

    void insert(int64_t timestamp, int col, const Quantity &qty);

    void insert(int64_t timestamp, const QString &id, const Quantity &qty);

    void disconnect(int64_t timestamp, int col);

    void disconnect(int64_t timestamp, const QString &id);

    void connect(int64_t timestamp, int col);

    void connect(int64_t timestamp, const QString &id);

    bool hasCompleteRow();

    const DataRow *nextCompleteRow();

    void print();
};

#endif
