#include "AdcBlockReceivePlugin.h"
#include "AdcBlockReceiver.h"

#include "LQMeasStudio.h"
#include "DataBlockProcessPlugin.h"
#include "ChannelSignalParamPanel.h"

namespace LQMeasStudio {
    AdcBlockReceivePlugin::AdcBlockReceivePlugin(QObject *parent) :
        ProcessPlugin(typePluginName(), false, parent), m_receiver(new AdcBlockReceiver()), m_procThread(new QThread()) {

        qRegisterMetaType<QList<QSharedPointer<DataBlock> > >("QList<QSharedPointer<DataBlock> >");
    }

    AdcBlockReceivePlugin::~AdcBlockReceivePlugin() {
        delete m_receiver;
        delete m_procThread;
    }

    double AdcBlockReceivePlugin::blockTime() const {
        return m_receiver->blockTime();
    }

    double AdcBlockReceivePlugin::blockInterval() const {
        return m_receiver->blockInterval();
    }

    QSharedPointer<DataBlock> AdcBlockReceivePlugin::lastDataBlock(ChannelInfo *ch) const {
        return (ch->num() < m_lastAdcData.size()) ? m_lastAdcData[ch->num()] : QSharedPointer<DataBlock>();
    }

    void AdcBlockReceivePlugin::procStartPrepare() {

        foreach (QSharedPointer<ChannelInfo> ch, LQMeasStudioEnv->channelsConfig()->channels()) {
            m_lastAdcData.append(QSharedPointer<DataBlock>() );
        }
        m_procThread->start();

        AdcBlockReceiver *prevReceiver = m_receiver;

        m_receiver = new AdcBlockReceiver();
        m_receiver->moveToThread(m_procThread);
        if (prevReceiver) {
            m_receiver->setBlockTime(prevReceiver->blockTime(), prevReceiver->blockInterval());
            delete prevReceiver;
        }
        connect(m_receiver, SIGNAL(receiveBlock(QList<QSharedPointer<DataBlock> >)),
                SLOT(processBlock(QList<QSharedPointer<DataBlock> >)));
        m_receiver->start();
    }

    void AdcBlockReceivePlugin::procStopRequest() {

    }

    void AdcBlockReceivePlugin::procStop() {
        m_receiver->stop();
        m_procThread->quit();
        m_procThread->wait();
        disconnect(m_receiver, SIGNAL(receiveBlock(QList<QSharedPointer<DataBlock> >)),
                   this, SLOT(processBlock(QList<QSharedPointer<DataBlock> >)));
    }

    void AdcBlockReceivePlugin::procClear() {        
        m_receiver->clear();
        m_lastAdcData.clear();
    }

    void AdcBlockReceivePlugin::setBlockTime(double blockTime, double intervalTime) {
        m_receiver->setBlockTime(blockTime, intervalTime);
    }

    void AdcBlockReceivePlugin::procProtLoadSettings(QSettings &set) {
        double dval;
        bool ok;
        double blockTime = m_receiver->blockTime();
        double blockInterval = m_receiver->blockInterval();

        dval = set.value("blockTime", blockTime).toDouble(&ok);
        if (ok && (dval > 0))
            blockTime = dval;

        dval = set.value("intervalTime", blockInterval).toDouble(&ok);
        if (ok && (dval > 0))
            blockInterval = dval;
        if (blockInterval < blockTime)
            blockInterval = blockTime;
        m_receiver->setBlockTime(blockTime, blockInterval);
    }

    void AdcBlockReceivePlugin::procProtSaveSettings(QSettings &set) {
        set.setValue("blockTime", m_receiver->blockTime());
        set.setValue("intervalTime", m_receiver->blockInterval());
    }

    void AdcBlockReceivePlugin::processBlock(QList<QSharedPointer<DataBlock> > blockList) {
        emit receiveBlock(blockList);


        foreach (QSharedPointer<DataBlock>  block, blockList) {
            if (block->channel()->num() < m_lastAdcData.size())
                m_lastAdcData[block->channel()->num()] = block;

            foreach (ProcessPlugin *plugin, LQMeasStudioEnv->processPlugings()) {
                DataBlockProcessPlugin *blockPlugin = dynamic_cast<DataBlockProcessPlugin *>(plugin);
                if (blockPlugin && blockPlugin->procEnabled()) {
                    blockPlugin->blockShowResult(block);
                }
            }
        }
    }
}
