#ifndef SERVERFRAMEBUFFERUPDATEMESSAGE_H
#define SERVERFRAMEBUFFERUPDATEMESSAGE_H

#include "servermessagebase.h"
#include "clientglobals.h"
#include "pixelformat.h"

#include <QColor>
#include <QList>
#include <QRect>
#include <QFlags>
#include <zlib.h>

class QIODevice;
class CompressionContext;

class ServerFramebufferUpdateMessage : public ServerMessageBase
{
public:

    enum HextileEncoding { RAW_SUB_ENCODING = 1, BG_SUB_ENCODING = 2, FG_SUB_ENCODING = 4, AS_SUB_ENCODING = 8, SC_SUB_ENCODING = 16};
    Q_DECLARE_FLAGS(HextileEncodings, HextileEncoding);

    ServerFramebufferUpdateMessage();
    void setPixelFormat( const PixelFormat &props );
    void setCompressionContext( CompressionContext *ctx );
    void setFramebufferSize( const QSize &sz );
    void setFramebufferDepth( int depth );

    struct FrameBufferUpdates {
        ClientGlobals::RfbEncoding encoding;
        PixelFormat format;
        QRect rect;
    };

    bool hasData() const;
    QList<FrameBufferUpdates> readUpdate( QIODevice *device, uchar *framebuffer ) const;
    FrameBufferUpdates readNextRectUpdate( QIODevice *device ) const;


    virtual bool loadMessage( QIODevice *device );

    void readRawRect( QIODevice *device, uchar *framebuffer, const QRect &rect  ) const;
    void readRreRect( QIODevice *device, uchar *framebuffer, const QRect &rect  ) const;
    void readCoRreRect( QIODevice *device, uchar *framebuffer, const QRect &rect  ) const;
    void readCopyRect( QIODevice *device, uchar *framebuffer, const QRect &rect ) const;
    void readHextileRect( QIODevice *device, uchar *framebuffer, const QRect &rect ) const;
    void readZlibRect( QIODevice *device, uchar *framebuffer, const QRect &rect ) const;

private:

    QRgb readPixel( QIODevice *device ) const;
    void setFrameBufferPixel( uchar *framebuffer, const QRgb &pixel, int x, int y ) const;
    void fillRect( uchar *framebuffer, const QRgb &pixel, const QRect &rect ) const;

    int m_bpp;
    int m_bigEndian;
    int m_redShift;
    int m_redMax;
    int m_greenShift;
    int m_greenMax;
    int m_blueShift;
    int m_blueMax;
    int m_numberOfRects;
    mutable int m_currentRectIndex;
    CompressionContext *m_zip;
    QSize m_fbSize;
    int m_fbDepth;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(ServerFramebufferUpdateMessage::HextileEncodings)
#endif // SERVERFRAMEBUFFERUPDATEMESSAGE_H

