#include "rawrectreader.h"
#include "bytereader.h"

#include <QFinalState>

NativeRawRectReader::NativeRawRectReader(QIODevice *device, QState *parent):
    QState(parent), m_device(device)
{
    QState *readRawRectLine = new QState(this);
    QState *readRawRectLineDone = new QState(this);
    QState *readMoreLines = new QState(this);
    m_byteReader = new ByteReader(device, readRawRectLine);
    QFinalState *readRawRectDone = new QFinalState(this);

    readRawRectLine->addTransition(this, SIGNAL(performRead()), m_byteReader );
    m_byteReader->addTransition(readRawRectLineDone);
    readRawRectLineDone->addTransition(this, SIGNAL(readMore()), readMoreLines );
    readRawRectLineDone->addTransition(this, SIGNAL(readDone()), readRawRectDone );
    readMoreLines->addTransition(device, SIGNAL(readyRead()), readRawRectLine );

    connect( readRawRectLine, SIGNAL(entered()), this, SLOT( readFramebufferLine() ) );
    connect( readRawRectLineDone, SIGNAL(entered()), this, SLOT(onReadFramebufferLineDone() ) );
    //connect( readMoreLines, SIGNAL(entered()), this, SLOT( onReadMoreLines() ) );
    //connect( readRawRectDone, SIGNAL(entered()), this, SLOT( onReadRawRectDone() ) );

    setInitialState( readRawRectLine );
    readRawRectLine->setInitialState( m_byteReader);
}

bool NativeRawRectReader::hasError() const
{
    return m_hasError;
}

void NativeRawRectReader::configure( const QRect &fbSize, int bpp, uchar *framebuffer, const QRect &rect )
{
    m_bpp = bpp;
    m_fbSize = fbSize;
    m_framebuffer = framebuffer;
    m_rect = rect;
    m_line = m_fbSize.width() * m_bpp;
    m_pixelDataLine = rect.width() * m_bpp;
    m_dst = &framebuffer[rect.y() * m_fbSize.width() * m_bpp + rect.x() * m_bpp];
}

void NativeRawRectReader::readFramebufferLine()
{
    m_byteReader->configure( (char*)m_dst, m_pixelDataLine );
    emit performRead();
}

void NativeRawRectReader::onReadFramebufferLineDone()
{
    m_dst += m_line;
    m_idx++;

    if( m_idx < m_rect.height() )
    {
        emit readMore();
    }
    else
    {
        emit readDone();
    }
}


