#ifndef QGGRIFOBEAMUPTFTP_H
#define QGGRIFOBEAMUPTFTP_H

#include <QObject>

#include <QHostAddress>

class BupTFTPReceiver
{
public:
    BupTFTPReceiver(void* store, unsigned int size):
        buffer(reinterpret_cast<char*>(store)),
        max_size(size)
    {
    }

    virtual ~BupTFTPReceiver() {}

    virtual bool receiveBegin(unsigned int expected_size)
    {
        if (expected_size>max_size)
            return false;
        return true;
    }

    virtual bool receiveError(unsigned int /*error*/)
    {
        return true;
    }

    virtual bool receiveBlock(const void* data, unsigned int len, unsigned /*lock_num*/)
    {
        memcpy(&buffer[used_size], data, len);
        used_size+=len;
        return true;
    }

    virtual bool receiveTerminated()
    {
        return true;
    }

protected:
    char* buffer;
    unsigned int max_size;
    unsigned int used_size;
};

class BupTFTPID
{
public:
};

class BupTFTP : public QObject
{
    Q_OBJECT
public:
    explicit BupTFTP(QObject *parent = 0);
    virtual ~BupTFTP();

    void setId(int id);
    int sid() const;

    void bind(const QHostAddress&adr, unsigned int port=0);

    void bindRemote(const QHostAddress&adr, unsigned int dst_port=0);

    bool sendFile(const QString& localFileName, const QString& remoteFileName);
    bool sendMemory(BupTFTPID*, void* data, unsigned int size, const QString& remoteFileName, bool embedFirstBlock=false);

    bool sendMemory(BupTFTPID*,void* data, unsigned int size, const char* remoteFileName, bool embedFirstBlock=false);

    bool receive(BupTFTPID* rId, BupTFTPReceiver* theReceived, const QString& remoteFilename, bool embedFirstBlock=false);

    bool receiveMemory(BupTFTPID*,void* data, unsigned int max_size, const QString& remoteFileName, bool embedFirstBlock=false);
    bool receiveMemory(BupTFTPID*,void* data, unsigned int max_size, const char* remoteFileName, bool embedFirstBlock=false);

    //bool srioSend(unsigned int remote_address, unsigned int db, const void* data, unsigned int size);
    //bool srioReceive(unsigned int remote_address, unsigned int db, const void* data, unsigned int size);

    QString errorString();
    int errorCode();

    void setTargetNetIp(unsigned int ip);

    void fixServerBug(int n);

    QString remoteAddress() const;

    void setTimeous(int start_tm, int data_tm=-1, int last_tm=-1);

signals:
    void serverHello(unsigned intip, int port, const QString& msg);

    void transferError(BupTFTP*, BupTFTPID*, int code, const QString& msg);
    void progressInfo(int percentage, const QString& msg);

    void lastBlockSent();

    void sendBegin();
    void sendTerminated(BupTFTP*, BupTFTPID*);

    void sendStart();
    void sendError(BupTFTPID*);

    void sendProgress(int completition);

    void receiveTerminated(BupTFTP*, BupTFTPID*, int ok, QHostAddress remoteAddress);

    void queueChanged(int n);

    void unsollecitatedAck(BupTFTP*, QHostAddress remoteAddress, int code, const QString& msg);

public slots:
    void pingServer(int port);
    //void pingPartition(unsigned int address, int port);

private:
    class Implementation;
    Implementation& p_;
};

#endif // QGGRIFOBEAMUPTFTP_H
