#include "CRfePurExperimentalSettings.h"

#include <reader/QrfeRfePurReader>

#include <QrfeQwt>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_legend.h>
#include <qwt_scale_div.h>

#define MAX_X				251
#define MAX_Y				255

CRfePurExperimentalSettings::CRfePurExperimentalSettings(QTextEdit* infoEdit, QWidget* parent)
	: ReaderTabWidget(tr("Experimental"), parent)
    , m_reader(0)
{
	ui.setupUi(this);
	setInfoEdit(infoEdit);

	connect(ui.oadButton,					SIGNAL(clicked()),
			this, 							  SLOT(setOAD()));
	connect(ui.setTariButton,				SIGNAL(clicked()),
			this, 							  SLOT(setTariSettings()));
    connect(ui.setLinkFrequencyButton,		SIGNAL(clicked()),
            this, 							  SLOT(setLinkFrequency()));
    connect(ui.setLongPreambleButton,		SIGNAL(clicked()),
            this, 							  SLOT(setLongPreamble()));
    connect(ui.setModulatorSettingsButton,	SIGNAL(clicked()),
			this, 							  SLOT(setModulatorSettings()));
    connect(ui.setPredistortionDataButton,	SIGNAL(clicked()),
            this, 							  SLOT(setPredistortionData()));
    connect(ui.getPredistortionDataButton,	SIGNAL(clicked()),
            this, 							  SLOT(getPredistortionData()));
    connect(ui.setReadBlockSizeButton,		SIGNAL(clicked()),
            this, 							  SLOT(setReadParams()));

    m_predistDataPlot = new QwtPlot(this);
    ui.plot->addWidget(m_predistDataPlot);

    QPen pen;

    pen = QPen(QPen(Qt::blue));
    pen.setWidth(2);
    m_predistDataCurve = new QwtPlotCurve("Motor");
    m_predistDataCurve->attach(m_predistDataPlot);
    m_predistDataCurve->setPen(pen);

    m_predistDataPlot->setAxisScale(2, 	0, MAX_X);
    //m_predistDataPlot->enableAxis(2, false);
    m_predistDataPlot->setAxisScale(0, 	0, MAX_Y);
    //m_predistDataPlot->enableAxis(0, false);

    m_predistDataPlot->updateAxes();
    m_predistDataPlot->replot();

}

CRfePurExperimentalSettings::~CRfePurExperimentalSettings()
{

}

bool CRfePurExperimentalSettings::init(QrfeReaderInterface* reader)
{
	m_reader = qobject_cast<QrfeRfePurReader*>(reader);
	if( m_reader == 0 )
		return false;

	clearInfo();
    clearPlot();

	return true;
}

void CRfePurExperimentalSettings::deinit()
{
	m_reader = 0;
}

void CRfePurExperimentalSettings::activated()
{
    if(m_reader == 0)
        return;

	clearInfo();
	reloadSettings();
}

void CRfePurExperimentalSettings::reloadSettings()
{
	QrfeGlobal::Result res;
	QByteArray data = 0;

	res = m_reader->getParam(0xFF84, data);
	if(res != QrfeGlobal::RES_OK || data.size() != 1)
	{
		ui.oadGroupBox->setEnabled(false);
	}
	else
	{
		ui.oadGroupBox->setEnabled(true);

		ui.oadModeComboBox->setCurrentIndex(data.at(0));
	}


	res = m_reader->getParam(0xFF85, data);
	if(res != QrfeGlobal::RES_OK || data.size() != 4)
	{
		ui.tariGroupBox->setEnabled(false);
	}
	else
	{
		ui.tariGroupBox->setEnabled(true);

		ui.tariCustomCheckBox->setChecked(data.at(0) != 0);
		ui.tariComboBox->setCurrentIndex(data.at(1));
		ui.txPwLengthComboBox->setCurrentIndex(data.at(2));
		ui.tx1LengthComboBox->setCurrentIndex(data.at(3));
	}


	uchar lf;
	res = m_reader->linkFrequency(lf);
	if(res != QrfeGlobal::RES_OK)
	{
		ui.linkFreqGroupBox->setEnabled(false);
	}
	else
	{
		ui.linkFreqGroupBox->setEnabled(true);

		ui.linkFreqeuncyBox->setCurrentIndex(lf);
	}

    bool longPreamble;
    res = m_reader->longPreamble(longPreamble);
    if(res != QrfeGlobal::RES_OK)
    {
        ui.longPreambleGroupBox->setEnabled(false);
    }
    else
    {
        ui.longPreambleGroupBox->setEnabled(true);

        ui.longPrerambleBox->setChecked(longPreamble);
    }


	res = m_reader->getParam(0xFF86, data);
    if(res != QrfeGlobal::RES_OK || data.size() != 9)
	{
		ui.modControlGroupBox->setEnabled(false);
	}
	else
	{
		ui.modControlGroupBox->setEnabled(true);

        ui.modulatorCustomCheckBox->setChecked(data.at(0) != 0);
        ui.useCorrectionCheckBox->setChecked(data.at(1) != 0);
        ui.lowPassFilterCheckBox->setChecked(data.at(2) != 0);
        ui.askTransRateComboBox->setCurrentIndex(data.at(3));
        ui.linModeCheckBox->setChecked(data.at(4) != 0);
        ui.prAskCheckBox->setChecked(data.at(5) != 0);
        ui.modDepthSpinBox->setValue(data.at(6));
        ui.rfOnOffTransComboBox->setCurrentIndex(data.at(7));
        ui.ookAskCheckBox->setChecked(data.at(8) != 0);
	}

	res = m_reader->getParam(0x002C, data);
	if(res != QrfeGlobal::RES_OK || data.size() != 1)
	{
		ui.readGroupBox->setEnabled(false);
	}
	else
	{
		ui.readGroupBox->setEnabled(true);

		ui.readBlockSizeSpinBox->setValue(data.at(0));
	}




	infoAppend("-- Reload settings --");
	showOK();
}

void CRfePurExperimentalSettings::setOAD()
{
	if(m_reader == 0)
		return;

	uchar mode = ui.oadModeComboBox->currentIndex();
	QrfeGlobal::Result res = m_reader->setParam(0xFF84, QByteArray(1, mode) );
	if(res == QrfeGlobal::RES_OK)	{
		infoSetOK("-- Set OAD to " + QString::number(mode) + " --");
	}
	else {
		infoSetError("-- Could not set OAD --");
	}

	reloadSettings();
}

void CRfePurExperimentalSettings::setTariSettings()
{
	if(m_reader == 0)
		return;

	bool  customSetting = ui.tariCustomCheckBox->isChecked();
	uchar tari 			= ui.tariComboBox->currentIndex();
	uchar txPwLength 	= ui.txPwLengthComboBox->currentIndex();
	uchar tx1Length 	= ui.tx1LengthComboBox->currentIndex();
	QByteArray data;
	data.append(customSetting);
	data.append(tari);
	data.append(txPwLength);
	data.append(tx1Length);
	QrfeGlobal::Result res = m_reader->setParam(0xFF85, data );
	if(res == QrfeGlobal::RES_OK)	{
		infoSetOK("-- Set Tari to " + QString::number(customSetting) + ", "  + QString::number(tari) + ", " + QString::number(txPwLength) + ", " + QString::number(tx1Length) + " --");
	}
	else {
		infoSetError("-- Could not set Tari --");
	}

	reloadSettings();
}

void CRfePurExperimentalSettings::setLinkFrequency()
{
	if(m_reader == 0)
		return;

	uchar lf = ui.linkFreqeuncyBox->currentIndex();
	QrfeGlobal::Result res = m_reader->setLinkFrequency(lf);
	if(res == QrfeGlobal::RES_OK)	{
		infoSetOK("-- Set Link Frequency to " + QString::number(lf) + " --");
	}
	else {
		infoSetError("-- Could not set Link Frequency --");
	}

	reloadSettings();
}

void CRfePurExperimentalSettings::setLongPreamble()
{
    if(m_reader == 0)
        return;

    bool longPreamble = ui.longPrerambleBox->isChecked();
    QrfeGlobal::Result res = m_reader->setLongPreamble(longPreamble);
    if(res == QrfeGlobal::RES_OK)	{
        infoSetOK("-- Set Long Preamble to " + QString::number(longPreamble) + " --");
    }
    else {
        infoSetError("-- Could not set Long Preamble --");
    }

    reloadSettings();
}

void CRfePurExperimentalSettings::setModulatorSettings()
{
	if(m_reader == 0)
		return;

    bool  useCustomSett = ui.modulatorCustomCheckBox->isChecked();
    bool  useCorrection = ui.useCorrectionCheckBox->isChecked();
    bool  lowPass 		= ui.lowPassFilterCheckBox->isChecked();
	uchar askTransRate	= ui.askTransRateComboBox->currentIndex();
	bool  linMode 		= ui.linModeCheckBox->isChecked();
	bool  prAsk 		= ui.prAskCheckBox->isChecked();
	uchar modDepth		= ui.modDepthSpinBox->value();
	uchar rfTrans		= ui.rfOnOffTransComboBox->currentIndex();
	bool  ookAsk 		= ui.ookAskCheckBox->isChecked();

	QByteArray data;
    data.append(useCustomSett);
    data.append(useCorrection);
    data.append(lowPass);
	data.append(askTransRate);
	data.append(linMode);
	data.append(prAsk);
	data.append(modDepth);
	data.append(rfTrans);
	data.append(ookAsk);
	QrfeGlobal::Result res = m_reader->setParam(0xFF86, data );
	if(res == QrfeGlobal::RES_OK)	{
		infoSetOK("-- Set Modulator Settings to " +
                        QString::number(useCustomSett) + ", "  +
                        QString::number(useCorrection) + ", "  +
                        QString::number(lowPass) + ", "  +
                        QString::number(askTransRate) + ", " +
                        QString::number(linMode) + ", " +
                        QString::number(prAsk) + ", " +
                        QString::number(modDepth) + ", " +
                        QString::number(rfTrans) + ", " +
                        QString::number(ookAsk) + " --");
	}
	else {
		infoSetError("-- Could not set Modulator Settings  --");
	}

	reloadSettings();

}

void CRfePurExperimentalSettings::setPredistortionData()
{
    if(m_reader == 0)
        return;

    uchar   bitShiftValue = ui.predistortionBitShiftSpinBox->value();

    QByteArray data;
    data.append(bitShiftValue);

    QrfeGlobal::Result res = m_reader->setParam(0xFF87, data );
    if(res == QrfeGlobal::RES_OK)	{
        infoSetOK("-- Set Predistortion Bit Shift Value to " +
                        QString::number(bitShiftValue) + " --");
    }
    else {
        infoSetError("-- Could not set Predistortion Bit Shift Value  --");
    }

    reloadSettings();
}

void CRfePurExperimentalSettings::getPredistortionData()
{
    if(m_reader == 0)
        return;

    QByteArray data;

    QrfeGlobal::Result res = m_reader->getParam(0xFF87, data );

    if(res == QrfeGlobal::RES_OK && data.size() >= 251)
    {
        data = data.left(251);

        infoSetOK("-- Get Predistortion Data OK --");
        infoAppend(QrfeGlobal::bytesToString(data));

        clearPlot();

        for(int i = 0; i < data.size(); i++)
        {
            m_predistData.append((double)(uint)(uchar)data.at(i));
            m_predistIndex.append((double)i);
        }

        m_predistDataCurve->setSamples(m_predistIndex.toVector(), m_predistData.toVector());
        m_predistDataPlot->replot();
    }
    else {
        infoSetError("-- Could not get Predistortion Data Value  --");
        infoAppend(QString::number(res) + " - "+ QString::number(data.size()));
        infoAppend(QrfeGlobal::bytesToString(data));
    }
}

void CRfePurExperimentalSettings::setReadParams()
{
	if(m_reader == 0)
		return;

	uchar size = ui.readBlockSizeSpinBox->value();
	QrfeGlobal::Result res = m_reader->setParam(0x002C, QByteArray(1, size) );
	if(res == QrfeGlobal::RES_OK)	{
		infoSetOK("-- Set ReadBlockSize to " + QString::number(size) + " words --");
	}
	else {
		infoSetError("-- Could not set ReadBlockSize --");
	}

    reloadSettings();
}

void CRfePurExperimentalSettings::clearPlot()
{
    m_predistData.clear();
    m_predistIndex.clear();

    m_predistDataCurve->setSamples(0, 0, 0);
    m_predistDataCurve->show();
    m_predistDataPlot->replot();
}
