/*
 * CRfePurRfSettings.cpp
 *
 *  Created on: 12.12.2011
 *      Author: stefan.detter
 */

#include "CRfePurRfSettings.h"
#include <ui_CRfePurDialog.h>

#include <QInputDialog>
#include <QMessageBox>
#include <QtCore/qmath.h>

#include <reader/QrfeRfePurReader>
#include <QrfeProgressDialog>


#include "../../permission/Permissions.h"



CRfePurRfSettings::CRfePurRfSettings(Ui::CRfePurDialogClass* dialog, QWidget* parent)
	: QObject(parent)
	, QrfeTraceModule("CRfePurRfSettings")
	, m_ui(dialog)
	, m_parent(parent)
	, m_reader(0)
	, m_sensitivityOffset(0)
{
	setInfoEdit(m_ui->infoEdit);

//	connect(m_ui->setRfSettingsButton,		SIGNAL(clicked()), 			this, SLOT(writeSettings()));
//	connect(m_ui->reloadRfSettingsButton,	SIGNAL(clicked()), 			this, SLOT(reloadSettings()));

	connect(m_ui->attenuationSlider, 		SIGNAL(valueChanged(int)), 	this, SLOT(setAttenuationLabel(int)));
	connect(m_ui->sensitivitySlider, 		SIGNAL(valueChanged(int)), 	this, SLOT(setSensitivityLabel(int)));
	connect(m_ui->modulationDepthSlider,	SIGNAL(valueChanged(int)), 	this, SLOT(setModulationDepthLabel(int)));

	connect(m_ui->freqAddChannelButton,		SIGNAL(clicked()), 			this, SLOT(addFrequencyEntry()));
	connect(m_ui->freqProfileBox, 			SIGNAL(activated(int)), 	this, SLOT(loadFrequencyProfileTable()));

	connect(m_ui->lbtProfileBox, 			SIGNAL(activated(int)), 	this, SLOT(loadLbtProfileTable()));
	connect(m_ui->lbtRssiThresholdSlider,	SIGNAL(valueChanged(int)), 	this, SLOT(setRssiThresholdLabel(int)));

	connect(m_ui->epcSizeSlider,			SIGNAL(valueChanged(int)), 	this, SLOT(setEpcSizeLabel(int)));
	connect(m_ui->initialSlotsSlider,		SIGNAL(valueChanged(int)), 	this, SLOT(setInitialSlotsLabel(int)));
	connect(m_ui->minimalSlotsSlider,		SIGNAL(valueChanged(int)), 	this, SLOT(setMinimalSlotsLabel(int)));
	connect(m_ui->maximalSlotsSlider,		SIGNAL(valueChanged(int)), 	this, SLOT(setMaximalSlotsLabel(int)));

	connect(m_ui->selMask1_useGroupBox,		SIGNAL(toggled(bool)), 		this, SLOT(setSelectionMask1Editable(bool)));
	connect(m_ui->selMask1_countSpinBox,	SIGNAL(valueChanged(int)), 	this, SLOT(setSelectionMask1Mask(int)));
	connect(m_ui->selMask2_useGroupBox,		SIGNAL(toggled(bool)), 		this, SLOT(setSelectionMask2Editable(bool)));
	connect(m_ui->selMask2_countSpinBox,	SIGNAL(valueChanged(int)), 	this, SLOT(setSelectionMask2Mask(int)));

	m_ui->frequencyTableWidget->setColumnWidth(0, 22);
	m_ui->frequencyTableWidget->setColumnWidth(1, 180);


	m_etsiFrequencies.insert(865.7, true);
	m_etsiFrequencies.insert(866.3, true);
	m_etsiFrequencies.insert(866.9, true);
	m_etsiFrequencies.insert(867.5, true);

    m_etsiUpperFrequencies.insert(916.3, true);
    m_etsiUpperFrequencies.insert(917.5, true);
    m_etsiUpperFrequencies.insert(918.7, true);
    m_etsiUpperFrequencies.insert(919.9, true);

	for(int i = 0; i < 25; i++)
	{
		m_fcc25Frequencies.insert(903.0 + i, true);
	}

	for(int i = 0; i < 50; i++)
	{
		m_fcc50Frequencies.insert(902.75 + (i * 0.50), true);
	}

	m_japanFrequencies.insert(916.8, true);
	m_japanFrequencies.insert(918.0, true);
	m_japanFrequencies.insert(919.2, true);
	m_japanFrequencies.insert(920.4, true);

	m_lbt_ETSI.listenTime 		= 0;
	m_lbt_ETSI.idleTime 		= 0;
	m_lbt_ETSI.maxAllocTime 	= 1000;
	m_lbt_ETSI.rssiThreshold 	= -40;

	m_lbt_FCC.listenTime 		= 1;
	m_lbt_FCC.idleTime 			= 0;
	m_lbt_FCC.maxAllocTime 		= 400;
	m_lbt_FCC.rssiThreshold 	= -40;
}

CRfePurRfSettings::~CRfePurRfSettings()
{
}

bool CRfePurRfSettings::init ( QrfeRfePurReader* reader, QrfeProgressDialog* pb )
{
	m_reader = reader;

	///////////////////////////////////////////////////////////////
	// Check Software revision and activate components
	m_ui->linkFrequencyLabel->setEnabled(false);
	m_ui->linkFreqeuncyBox->setEnabled(false);

	m_ui->codingLabel->setEnabled(false);
	m_ui->codingBox->setEnabled(false);

	m_ui->sensitivityDescriptionLabel->setEnabled(false);
	m_ui->sensitivitySlider->setEnabled(false);
	m_ui->sensitivityLabel->setEnabled(false);

	m_ui->epcSizeLabel->setEnabled(false);
	m_ui->epcSizeSlider->setEnabled(false);
	m_ui->epcSizeValueLabel->setEnabled(false);

	m_ui->lbtTab->setEnabled(false);

	m_ui->sendHandleLabel->setEnabled(false);
	m_ui->sendHandleCheckBox->setEnabled(false);
	m_ui->sendPCLabel->setEnabled(false);
	m_ui->sendPCCheckBox->setEnabled(false);

	m_ui->gen2PopulationTab->setEnabled(false);
	m_ui->initialSlotsLabel->setEnabled(true);
	m_ui->initialSlotsSlider->setEnabled(false);
	m_ui->initialSlotsValueLabel->setEnabled(false);
	m_ui->minimalSlotsLabel->setEnabled(false);
	m_ui->minimalSlotsSlider->setEnabled(false);
	m_ui->minimalSlotsValueLabel->setEnabled(false);
	m_ui->maximalSlotsLabel->setEnabled(false);
	m_ui->maximalSlotsSlider->setEnabled(false);
	m_ui->maximalSlotsValueLabel->setEnabled(false);
	m_ui->slotsAdjustLabel->setEnabled(false);
	m_ui->slotsAdjustComboBox->setEnabled(false);
	m_ui->sessionLabel->setEnabled(false);
	m_ui->sessionComboBox->setEnabled(false);
	m_ui->inventoryRoundsLabel->setEnabled(false);
	m_ui->inventoryRoundsSpinBox->setEnabled(false);
	m_ui->selMask1_useGroupBox->setEnabled(false);
	m_ui->selMask2_useGroupBox->setEnabled(false);

    m_ui->sendRN16Label->setEnabled(false);
    m_ui->sendRN16CheckBox->setEnabled(false);
    m_ui->nxpBrandIdCheckBox->setEnabled(false);


	if( (m_reader->readerTypeExact()&0x000000FF) == 0x09 )
	{
		m_ui->gen2Tab->setEnabled(false);
	}

	ulong sw_rev = m_reader->softwareRevision();
	sw_rev &= 0x00007FFF;
	if(sw_rev >= 0x0020)
	{
		m_ui->linkFrequencyLabel->setEnabled(true);
		m_ui->linkFreqeuncyBox->setEnabled(true);

		m_ui->codingLabel->setEnabled(true);
		m_ui->codingBox->setEnabled(true);
	}
	if(sw_rev >= 0x0027)
	{
		m_ui->sensitivityDescriptionLabel->setEnabled(true);
		m_ui->sensitivitySlider->setEnabled(true);
		m_ui->sensitivityLabel->setEnabled(true);
	}
	if(sw_rev >= 0x0107)
	{
		m_ui->lbtTab->setEnabled(true);
		m_ui->epcSizeLabel->setEnabled(true);
		m_ui->epcSizeSlider->setEnabled(true);
		m_ui->epcSizeValueLabel->setEnabled(true);
	}
	if(sw_rev >= 0x0117)
	{
		m_ui->sendHandleLabel->setEnabled(true);
		m_ui->sendHandleCheckBox->setEnabled(true);
		m_ui->sendPCLabel->setEnabled(true);
		m_ui->sendPCCheckBox->setEnabled(true);
	}
	if(sw_rev >= 0x0201)
	{
		m_ui->gen2PopulationTab->setEnabled(true);
		m_ui->initialSlotsLabel->setEnabled(true);
		m_ui->initialSlotsSlider->setEnabled(true);
		m_ui->initialSlotsValueLabel->setEnabled(true);
		m_ui->minimalSlotsLabel->setEnabled(true);
		m_ui->minimalSlotsSlider->setEnabled(true);
		m_ui->minimalSlotsValueLabel->setEnabled(true);
		m_ui->maximalSlotsLabel->setEnabled(true);
		m_ui->maximalSlotsSlider->setEnabled(true);
		m_ui->maximalSlotsValueLabel->setEnabled(true);
		m_ui->slotsAdjustLabel->setEnabled(true);
		m_ui->slotsAdjustComboBox->setEnabled(true);
		m_ui->sessionLabel->setEnabled(true);
		m_ui->sessionComboBox->setEnabled(true);
		m_ui->inventoryRoundsLabel->setEnabled(true);
		m_ui->inventoryRoundsSpinBox->setEnabled(true);
	}
	if(sw_rev >= 0x0206)
	{
		m_ui->selMask1_useGroupBox->setEnabled(true);
		m_ui->selMask2_useGroupBox->setEnabled(true);
	}
    if(sw_rev >= 0x0221)
    {
        m_ui->sendRN16Label->setEnabled(true);
        m_ui->sendRN16CheckBox->setEnabled(true);
        m_ui->nxpBrandIdCheckBox->setEnabled(true);
    }


	bool ok = readSettingsFromReader(pb);

	loadRfSettings();

	return ok;
}



void CRfePurRfSettings::loadRfSettings( )
{
	const RF_SETTINGS& set = m_settings;

	m_ui->freqProfileBox->setCurrentIndex(0);
	m_ui->freqRandomHoppingBox->setChecked(set.frequencyMode);
	QString freqString;
	m_currentFrequencies.clear();
	foreach(uint freq, set.frequencyList)
	{
		freqString += QString::number(freq) + "\n";
		m_currentFrequencies.insert((double)freq/1000.0, true);
	}
	loadFrequencyProfileTable();

	m_ui->lbtProfileBox->setCurrentIndex(0);
	m_lbt_current = set.lbtParams;
	loadLbtParams(m_lbt_current);

	m_ui->attenuationSlider->setMaximum(set.uhfMaxAttenuation);
	m_ui->attenuationSlider->setValue(set.uhfAttenuation);
	setAttenuationLabel(m_ui->attenuationSlider->value());

	m_sensitivityOffset = set.uhfMaxSensitivity * (-1);
	short diff = set.uhfMinSensitivity - set.uhfMaxSensitivity;
	m_ui->sensitivitySlider->setMaximum( diff );
	m_ui->sensitivitySlider->setValue(set.uhfSensitivity + m_sensitivityOffset);
	setSensitivityLabel(m_ui->sensitivitySlider->value());

	m_ui->modulationDepthSlider->setValue(set.uhfModulationDepth);
	setModulationDepthLabel(m_ui->modulationDepthSlider->value());

	m_ui->linkFreqeuncyBox->setCurrentIndex(set.gen2LinkFrequency);
	m_ui->codingBox->setCurrentIndex(set.gen2Coding);
	m_ui->epcSizeSlider->setValue(set.gen2EpcSize/2);
	setEpcSizeLabel(m_ui->epcSizeSlider->value());
	m_ui->sendHandleCheckBox->setChecked(set.gen2SendHandle);
	m_ui->sendPCCheckBox->setChecked(set.gen2SendPC);
    m_ui->sendRN16CheckBox->setChecked(set.gen2SendRN16);

	m_ui->initialSlotsSlider->setValue(set.gen2InitialQ);
	setInitialSlotsLabel(m_ui->initialSlotsSlider->value());
	m_ui->minimalSlotsSlider->setValue(set.gen2MinimalQ);
	setMinimalSlotsLabel(m_ui->minimalSlotsSlider->value());
	m_ui->maximalSlotsSlider->setValue(set.gen2MaximalQ);
	setMaximalSlotsLabel(m_ui->maximalSlotsSlider->value());

	m_ui->slotsAdjustComboBox->setCurrentIndex(set.gen2QMethod);
	m_ui->sessionComboBox->setCurrentIndex(set.gen2Session);
	m_ui->inventoryRoundsSpinBox->setValue(set.gen2InvRounds);

	m_ui->selMask1_useGroupBox->setChecked(set.gen2SelectionMask1.size > 0);
	m_ui->selMask1_memBankComboBox->setCurrentIndex(set.gen2SelectionMask1.memBank-1);
	if(m_ui->selMask1_memBankComboBox->currentIndex() == -1)
		m_ui->selMask1_memBankComboBox->setCurrentIndex(0);
	m_ui->selMask1_addressSpinBox->setValue(set.gen2SelectionMask1.address);
	m_ui->selMask1_countSpinBox->setValue(set.gen2SelectionMask1.size);
	setSelectionMask1Mask(set.gen2SelectionMask1.size);
	m_ui->selMask1_maskLineEdit->setText(QrfeGlobal::bytesToString(set.gen2SelectionMask1.mask));
	if(m_ui->selMask1_useGroupBox->isChecked())
	{
		m_ui->selMask1_memBankComboBox->setEnabled(true);
		m_ui->selMask1_addressSpinBox->setEnabled(true);
		m_ui->selMask1_countSpinBox->setEnabled(true);
		m_ui->selMask1_maskLineEdit->setEnabled(true);
	}

	m_ui->selMask2_useGroupBox->setChecked(set.gen2SelectionMask2.size > 0);
	m_ui->selMask2_memBankComboBox->setCurrentIndex(set.gen2SelectionMask2.memBank-1);
	if(m_ui->selMask2_memBankComboBox->currentIndex() == -1)
		m_ui->selMask2_memBankComboBox->setCurrentIndex(0);
	m_ui->selMask2_addressSpinBox->setValue(set.gen2SelectionMask2.address);
	m_ui->selMask2_countSpinBox->setValue(set.gen2SelectionMask2.size);
	setSelectionMask2Mask(set.gen2SelectionMask2.size);
	m_ui->selMask2_maskLineEdit->setText(QrfeGlobal::bytesToString(set.gen2SelectionMask2.mask));
	if(m_ui->selMask2_useGroupBox->isChecked())
	{
		m_ui->selMask2_memBankComboBox->setEnabled(true);
		m_ui->selMask2_addressSpinBox->setEnabled(true);
		m_ui->selMask2_countSpinBox->setEnabled(true);
		m_ui->selMask2_maskLineEdit->setEnabled(true);
	}

    m_ui->nxpBrandIdCheckBox->setChecked(set.gen2CustomNxpBrandID);
}

bool CRfePurRfSettings::canReadAntennaSpec ( )
{
	if(m_ui->selMask1_countSpinBox->value() > 0 && !m_ui->selMask1_maskLineEdit->hasAcceptableInput())
	{
		QMessageBox::warning(m_parent, "Input Error", "The entered selection mask #1 is not valid.");
		return false;
	}

	if(m_ui->selMask2_countSpinBox->value() > 0 && !m_ui->selMask2_maskLineEdit->hasAcceptableInput())
	{
		QMessageBox::warning(m_parent, "Input Error", "The entered selection mask #2 is not valid.");
		return false;
	}

	return true;
}

void CRfePurRfSettings::readAntennaSpec( )
{
	RF_SETTINGS& set = m_settings;

	set.frequencyList = readFreqeuncyTable();
	set.frequencyMode = m_ui->freqRandomHoppingBox->isChecked();

	set.lbtParams = readLbtParams();

	set.uhfAttenuation = m_ui->attenuationSlider->value();
	set.uhfSensitivity = m_ui->sensitivitySlider->value() - m_sensitivityOffset;
	set.uhfModulationDepth = m_ui->modulationDepthSlider->value();

	set.gen2LinkFrequency = m_ui->linkFreqeuncyBox->currentIndex();
	set.gen2Coding = m_ui->codingBox->currentIndex();
	set.gen2EpcSize = m_ui->epcSizeSlider->value();
	set.gen2SendHandle = m_ui->sendHandleCheckBox->isChecked();
    set.gen2SendPC = m_ui->sendPCCheckBox->isChecked();
    set.gen2SendRN16 = m_ui->sendRN16CheckBox->isChecked();
    set.gen2InitialQ = m_ui->initialSlotsSlider->value();
	set.gen2MinimalQ = m_ui->minimalSlotsSlider->value();
	set.gen2MaximalQ = m_ui->maximalSlotsSlider->value();
	set.gen2QMethod = m_ui->slotsAdjustComboBox->currentIndex();
	set.gen2Session = m_ui->sessionComboBox->currentIndex();
	set.gen2InvRounds = m_ui->inventoryRoundsSpinBox->value();

	set.gen2SelectionMask1.memBank = m_ui->selMask1_memBankComboBox->currentIndex()+1;
	set.gen2SelectionMask1.address = m_ui->selMask1_addressSpinBox->value();
	if(m_ui->selMask1_useGroupBox->isChecked())
	{
		set.gen2SelectionMask1.size = m_ui->selMask1_countSpinBox->value();
		set.gen2SelectionMask1.mask = QrfeGlobal::stringToBytes(m_ui->selMask1_maskLineEdit->text());
	}
	else
	{
		set.gen2SelectionMask1.size = 0;
		set.gen2SelectionMask1.mask = QByteArray();
	}

	set.gen2SelectionMask2.memBank = m_ui->selMask2_memBankComboBox->currentIndex()+1;
	set.gen2SelectionMask2.address = m_ui->selMask2_addressSpinBox->value();
	if(m_ui->selMask2_useGroupBox->isChecked())
	{
		set.gen2SelectionMask2.size = m_ui->selMask2_countSpinBox->value();
		set.gen2SelectionMask2.mask = QrfeGlobal::stringToBytes(m_ui->selMask2_maskLineEdit->text());
	}
	else
	{
		set.gen2SelectionMask2.size = 0;
		set.gen2SelectionMask2.mask = QByteArray();
	}


    set.gen2CustomNxpBrandID = m_ui->nxpBrandIdCheckBox->isChecked();
}




void CRfePurRfSettings::addFrequencyEntry()
{
	bool ok = false;
	double freq = 0;

	if(!Permissions::d->readerFrequencyUnlimited())
	{
        QString regulatory = QInputDialog::getItem(m_parent, "Frequency", "Choose the appropriate regulatory", QStringList() << "ETSI" << "ETSI Upper" << "FCC" << "Japan", 0, false, &ok);
		if(!ok)
			return;

		if(regulatory == "ETSI")
			freq = QInputDialog::getDouble(m_parent, "Frequency", "Insert the new frequency", 866.00, 865.0, 868.0, 2, &ok);
        else if(regulatory == "ETSI Upper")
            freq = QInputDialog::getDouble(m_parent, "Frequency", "Insert the new frequency", 915.00, 921.0, 916.3, 2, &ok);
        else if(regulatory == "FCC")
			freq = QInputDialog::getDouble(m_parent, "Frequency", "Insert the new frequency", 915.00, 902.0, 928.0, 2, &ok);
		else if(regulatory == "Japan")
			freq = QInputDialog::getDouble(m_parent, "Frequency", "Insert the new frequency", 918.00, 916.0, 923.4, 2, &ok);
		else
			return;
	}
	else
		freq = QInputDialog::getDouble(m_parent, "Frequency", "Insert the new frequency", 866.00, 800.0, 1000.0, 3, &ok);

	if(ok){
		m_currentFrequencies.insert(freq, true);
		loadFrequencyProfileTable();
	}
}

void CRfePurRfSettings::loadFrequencyProfileTable()
{
	m_ui->frequencyTableWidget->clearContents();
	m_ui->frequencyTableWidget->setRowCount(0);
	foreach(QCheckBox* box, m_frequencyCheckBoxes)
		delete box;
	m_frequencyCheckBoxes.clear();


	QMap<double, bool>* map = 0;
	switch(m_ui->freqProfileBox->currentIndex())
	{
	case 0:
		map = &m_currentFrequencies;
		m_ui->freqAddChannelButton->setEnabled(true);
		break;
    case 1:
        map = &m_etsiFrequencies;
        m_ui->freqAddChannelButton->setEnabled(false);
        break;
    case 2:
        map = &m_etsiUpperFrequencies;
        m_ui->freqAddChannelButton->setEnabled(false);
        break;
    case 3:
		map = &m_fcc25Frequencies;
		m_ui->freqAddChannelButton->setEnabled(false);
		break;
    case 4:
		map = &m_fcc50Frequencies;
		m_ui->freqAddChannelButton->setEnabled(false);
		break;
    case 5:
		map = &m_japanFrequencies;
		m_ui->freqAddChannelButton->setEnabled(false);
		break;
	}

	if(map == 0)
		return;

	foreach(double freq, map->keys())
	{
		insertInFrequencyTable(map->value(freq), freq);
	}
}

void CRfePurRfSettings::insertInFrequencyTable(bool checked, double frequency)
{
	QCheckBox* box = new QCheckBox(m_ui->frequencyTableWidget);
	m_frequencyCheckBoxes.append(box);
	box->setChecked(checked);

	QTableWidgetItem* frequ = new QTableWidgetItem(QString::number(frequency) + " MHz");

	m_ui->frequencyTableWidget->insertRow(m_ui->frequencyTableWidget->rowCount());
	m_ui->frequencyTableWidget->setCellWidget(m_ui->frequencyTableWidget->rowCount()-1, 0, box);
	m_ui->frequencyTableWidget->setItem(m_ui->frequencyTableWidget->rowCount()-1, 1, frequ);
	m_ui->frequencyTableWidget->setRowHeight(m_ui->frequencyTableWidget->rowCount()-1, 17);
}

QList<uint> CRfePurRfSettings::readFreqeuncyTable()
{
	QList<uint> frequencys;
	for(int i = 0; i < m_ui->frequencyTableWidget->rowCount(); i++)
	{
		if(((QCheckBox*)m_ui->frequencyTableWidget->cellWidget(i, 0))->isChecked())
		{
			QString str = m_ui->frequencyTableWidget->item(i, 1)->text();
			QStringList list = str.split(" ");

			bool ok = false;
			double freq = list.at(0).toDouble(&ok);
			if(!ok)
				continue;

			frequencys.append( (uint) (freq*1000));
		}
	}

	return frequencys;
}



void CRfePurRfSettings::loadLbtProfileTable()
{
	switch(m_ui->lbtProfileBox->currentIndex())
	{
	case 0:
		loadLbtParams(m_lbt_current);
		break;
	case 1:
		loadLbtParams(m_lbt_ETSI);
		break;
	case 2:
		loadLbtParams(m_lbt_FCC);
		break;
	}
}

void CRfePurRfSettings::loadLbtParams(const LBT_PARAMS& params)
{
	m_ui->lbtListenTimeBox->setValue(params.listenTime);
	m_ui->lbtIdleTimeBox->setValue(params.idleTime);
	m_ui->lbtMaxAllocationTimeBox->setValue(params.maxAllocTime);
	m_ui->lbtRssiThresholdSlider->setValue(params.rssiThreshold);
	setRssiThresholdLabel(m_ui->lbtRssiThresholdSlider->value());
}

LBT_PARAMS CRfePurRfSettings::readLbtParams()
{
	LBT_PARAMS p;
	p.listenTime = m_ui->lbtListenTimeBox->value();
	p.idleTime = m_ui->lbtIdleTimeBox->value();
	p.maxAllocTime = m_ui->lbtMaxAllocationTimeBox->value();
	p.rssiThreshold = m_ui->lbtRssiThresholdSlider->value();
	return p;
}



void CRfePurRfSettings::setAttenuationLabel ( int value )
{
	m_ui->attenuationLabel->setText(QString::number(value) + " steps");
}

void CRfePurRfSettings::setSensitivityLabel ( int value )
{
	m_ui->sensitivityLabel->setText(QString::number(value - m_sensitivityOffset) + " dBm");
}

void CRfePurRfSettings::setModulationDepthLabel ( int value )
{
	m_ui->modulationDepthLabel->setText(QString::number(value) + " %");
}

void CRfePurRfSettings::setRssiThresholdLabel( int value )
{
	m_ui->lbtRssiThresholdLabel->setText(QString::number(value) + " dBm");
}

void CRfePurRfSettings::setEpcSizeLabel ( int value )
{
	if(value != 0)
		m_ui->epcSizeValueLabel->setText(QString::number(value*2) + " Bytes");
	else
		m_ui->epcSizeValueLabel->setText("Dynamic");
}

void CRfePurRfSettings::setInitialSlotsLabel ( int value )
{
	m_ui->initialSlotsValueLabel->setText(QString::number(qPow(2, value)));
	if(m_ui->maximalSlotsSlider->value() < value)
	{
		m_ui->maximalSlotsSlider->setValue(value);
	}
	if(m_ui->minimalSlotsSlider->value() > value)
	{
		m_ui->minimalSlotsSlider->setValue(value);
	}
}

void CRfePurRfSettings::setMinimalSlotsLabel ( int value )
{
	m_ui->minimalSlotsValueLabel->setText(QString::number(qPow(2, value)));
	if(m_ui->maximalSlotsSlider->value() < value)
	{
		m_ui->maximalSlotsSlider->setValue(value);
	}
	if(m_ui->initialSlotsSlider->value() < value)
	{
		m_ui->initialSlotsSlider->setValue(value);
	}
}

void CRfePurRfSettings::setMaximalSlotsLabel ( int value )
{
	m_ui->maximalSlotsValueLabel->setText(QString::number(qPow(2, value)));
	if(m_ui->minimalSlotsSlider->value() > value)
	{
		m_ui->minimalSlotsSlider->setValue(value);
	}
	if(m_ui->initialSlotsSlider->value() > value)
	{
		m_ui->initialSlotsSlider->setValue(value);
	}
}

void CRfePurRfSettings::setSelectionMask1Editable ( bool checked )
{
	m_ui->selMask1_memBankComboBox->setEnabled(checked);
	m_ui->selMask1_addressSpinBox->setEnabled(checked);
	m_ui->selMask1_countSpinBox->setEnabled(checked);
	m_ui->selMask1_maskLineEdit->setEnabled(checked);
}

void CRfePurRfSettings::setSelectionMask1Mask ( int value )
{
	int byteCount = QrfeGlobal::bitCountTobyteCount(value);
	QStringList l;
	for(int i = 0; i < byteCount; i++)
		l << "HH";
	m_ui->selMask1_maskLineEdit->setInputMask(l.join("-") + ";");

	if(m_settings.gen2SelectionMask1.mask.size() < byteCount)
	{
		m_settings.gen2SelectionMask1.mask.append(QByteArray(byteCount-m_settings.gen2SelectionMask1.mask.size(), (char)0x00));
	}

	if(m_settings.gen2SelectionMask1.mask.size() > byteCount)
	{
		m_settings.gen2SelectionMask1.mask.resize(byteCount);
	}

	m_ui->selMask1_maskLineEdit->setText(QrfeGlobal::bytesToString(m_settings.gen2SelectionMask1.mask));
}

void CRfePurRfSettings::setSelectionMask2Editable ( bool checked )
{
	m_ui->selMask2_memBankComboBox->setEnabled(checked);
	m_ui->selMask2_addressSpinBox->setEnabled(checked);
	m_ui->selMask2_countSpinBox->setEnabled(checked);
	m_ui->selMask2_maskLineEdit->setEnabled(checked);
}

void CRfePurRfSettings::setSelectionMask2Mask ( int value )
{
	int byteCount = QrfeGlobal::bitCountTobyteCount(value);
	QStringList l;
	for(int i = 0; i < byteCount; i++)
		l << "HH";
	m_ui->selMask2_maskLineEdit->setInputMask(l.join("-") + ";");

	if(m_settings.gen2SelectionMask2.mask.size() < byteCount)
	{
		m_settings.gen2SelectionMask2.mask.append(QByteArray(byteCount-m_settings.gen2SelectionMask2.mask.size(), (char)0x00));
	}

	if(m_settings.gen2SelectionMask2.mask.size() > byteCount)
	{
		m_settings.gen2SelectionMask2.mask.resize(byteCount);
	}

	m_ui->selMask2_maskLineEdit->setText(QrfeGlobal::bytesToString(m_settings.gen2SelectionMask2.mask));
}



bool CRfePurRfSettings::writeSettingsToReader( QrfeProgressDialog* pb)
{
	QrfeGlobal::Result res;
	bool err = false;

	readAntennaSpec();

	RF_SETTINGS& set = m_settings;

	res = m_reader->setAttenuation(set.uhfAttenuation);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Wrote attenuation");
	else{
		infoAppend("ERR: Could not write attenuation"); err = true;
	}
	pb->increasePorgressBar();

	if(m_ui->sensitivitySlider->isEnabled())
	{
		res = m_reader->setSensitivity(set.uhfSensitivity, set.uhfSensitivity);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote sensitivity");
		else{
			infoAppend("ERR: Could not write sensitivity"); err = true;
		}
		pb->increasePorgressBar();
	}

	res = m_reader->setModulationDepth(set.uhfModulationDepth);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Wrote modulation depth");
	else{
		infoAppend("ERR: Could not write modulation depth"); err = true;
	}
	pb->increasePorgressBar();

	res = m_reader->setFrequency(set.frequencyMode, set.frequencyList);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Wrote frequency");
	else{
		infoAppend("ERR: Could not write freqeuncy"); err = true;
	}
	pb->increasePorgressBar();

	if(m_ui->lbtTab->isEnabled())
	{
		res = m_reader->setLbtParams(set.lbtParams.listenTime, set.lbtParams.idleTime, set.lbtParams.maxAllocTime, set.lbtParams.rssiThreshold);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote LBT params");
		else{
			infoAppend("ERR: Could not write LBT params"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->linkFreqeuncyBox->isEnabled())
	{
		res = m_reader->setLinkFrequency(set.gen2LinkFrequency);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Link Frequency");
		else{
			infoAppend("ERR: Could not write Gen2 Link Frequency"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->codingBox->isEnabled())
	{
		res = m_reader->setCoding(set.gen2Coding);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Coding");
		else{
			infoAppend("ERR: Could not write Gen2 Coding"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->epcSizeSlider->isEnabled())
	{
		res = m_reader->setEpcSize(set.gen2EpcSize*2);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 EPC size");
		else{
			infoAppend("ERR: Could not write Gen2 EPC size"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sendHandleCheckBox->isEnabled())
	{
		res = m_reader->setSendHandle(set.gen2SendHandle);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Send Handle");
		else{
			infoAppend("ERR: Could not write Gen2 Send Handle"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sendPCCheckBox->isEnabled())
	{
		res = m_reader->setSendPC(set.gen2SendPC);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Send PC");
		else{
			infoAppend("ERR: Could not write Gen2 Send PC"); err = true;
		}
		pb->increasePorgressBar();
	}

    if(m_ui->sendRN16CheckBox->isEnabled())
    {
        res = m_reader->setSendRN16(set.gen2SendRN16);
        if(res == QrfeGlobal::RES_OK)
            infoAppend("OK:  Wrote Gen2 Send RN16");
        else{
            infoAppend("ERR: Could not write Gen2 Send RN16"); err = true;
        }
        pb->increasePorgressBar();
    }

	if(m_ui->initialSlotsSlider->isEnabled())
	{
		res = m_reader->setQ(set.gen2InitialQ, set.gen2MinimalQ, set.gen2MaximalQ);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Initial Q");
		else{
			infoAppend("ERR: Could not write Gen2 Q"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->slotsAdjustComboBox->isEnabled())
	{
		res = m_reader->setQMethod(set.gen2QMethod);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Q Method");
		else{
			infoAppend("ERR: Could not write Gen2 Q Method"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sessionComboBox->isEnabled())
	{
		res = m_reader->setSession(set.gen2Session);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Session");
		else{
			infoAppend("ERR: Could not write Gen2 Session"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->inventoryRoundsSpinBox->isEnabled())
	{
		res = m_reader->setInventoryRounds(set.gen2InvRounds);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Inventory Rounds");
		else{
			infoAppend("ERR: Could not write Gen2 Inventory Rounds"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->selMask1_useGroupBox->isEnabled())
	{
		res = m_reader->setSelectionMask1(set.gen2SelectionMask1.memBank, set.gen2SelectionMask1.address, set.gen2SelectionMask1.size, set.gen2SelectionMask1.mask);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Selection Mask #1");
		else{
			infoAppend("ERR: Could not write Gen2 Selection Mask #1"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->selMask2_useGroupBox->isEnabled())
	{
		res = m_reader->setSelectionMask2(set.gen2SelectionMask2.memBank, set.gen2SelectionMask2.address, set.gen2SelectionMask2.size, set.gen2SelectionMask2.mask);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Wrote Gen2 Selection Mask #2");
		else{
			infoAppend("ERR: Could not write Gen2 Selection Mask #2"); err = true;
		}
		pb->increasePorgressBar();
	}

    if(m_ui->nxpBrandIdCheckBox->isEnabled())
    {
        res = m_reader->setQueryNxpBrandID(set.gen2CustomNxpBrandID);
        if(res == QrfeGlobal::RES_OK)
            infoAppend("OK:  Wrote Gen2 Query NXP Brand ID");
        else{
            infoAppend("ERR: Could not write Gen2 Query NXP Brand ID"); err = true;
        }
        pb->increasePorgressBar();
    }

	if(err)
		showNOK();
	else
		showOK();

	return !err;
}

bool CRfePurRfSettings::readSettingsFromReader( QrfeProgressDialog* pb)
{
	QrfeGlobal::Result res;
	bool err = false;

	RF_SETTINGS& set = m_settings;

	res = m_reader->getAttenuation(set.uhfMaxAttenuation, set.uhfAttenuation);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Read attenuation");
	else{
		infoAppend("ERR: Could not read attenuation"); err = true;
	}
	pb->increasePorgressBar();

	if(m_ui->sensitivitySlider->isEnabled())
	{
		res = m_reader->getSensitivity(set.uhfMaxSensitivity, set.uhfMinSensitivity, set.uhfSensitivity);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read sensitivity");
		else{
			infoAppend("ERR: Could not read sensitivity"); err = true;
		}
		pb->increasePorgressBar();
	}

	res = m_reader->modulationDepth(set.uhfModulationDepth);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Read modulation depth");
	else{
		infoAppend("ERR: Could not read modulation depth"); err = true;
	}
	pb->increasePorgressBar();

	res = m_reader->getFrequency(set.frequencyMode, set.freqeuncyMaximum, set.frequencyList);
	if(res == QrfeGlobal::RES_OK)
		infoAppend("OK:  Read frequency");
	else{
		infoAppend("ERR: Could not read frequency"); err = true;
	}
	pb->increasePorgressBar();

	if(m_ui->lbtTab->isEnabled())
	{
		res = m_reader->getLbtParams(set.lbtParams.listenTime, set.lbtParams.idleTime, set.lbtParams.maxAllocTime, set.lbtParams.rssiThreshold);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read lbt params");
		else{
			infoAppend("ERR: Could not read lbt params"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->linkFreqeuncyBox->isEnabled())
	{
		res = m_reader->linkFrequency(set.gen2LinkFrequency);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Link Frequency");
		else{
			infoAppend("ERR: Could not read Gen2 Link Frequency"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->codingBox->isEnabled())
	{
		res = m_reader->coding(set.gen2Coding);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Coding");
		else{
			infoAppend("ERR: Could not read Gen2 Coding"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->epcSizeSlider->isEnabled())
	{
		res = m_reader->epcSize(set.gen2EpcSize);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 EPC Size");
		else{
			infoAppend("ERR: Could not read Gen2 EPC Size"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sendHandleCheckBox->isEnabled())
	{
		res = m_reader->sendHandle(set.gen2SendHandle);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Send Handle");
		else{
			infoAppend("ERR: Could not read Gen2 Send Handle"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sendPCCheckBox->isEnabled())
	{
		res = m_reader->sendPC(set.gen2SendPC);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Send PC");
		else{
			infoAppend("ERR: Could not read Gen2 Send PC"); err = true;
		}
		pb->increasePorgressBar();
	}

    if(m_ui->sendRN16CheckBox->isEnabled())
    {
        res = m_reader->sendRN16(set.gen2SendRN16);
        if(res == QrfeGlobal::RES_OK)
            infoAppend("OK:  Read Gen2 Send RN16");
        else{
            infoAppend("ERR: Could not read Gen2 Send RN16"); err = true;
        }
        pb->increasePorgressBar();
    }

	if(m_ui->initialSlotsSlider->isEnabled())
	{
		res = m_reader->q(set.gen2InitialQ, set.gen2MinimalQ, set.gen2MaximalQ);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Initial Q");
		else{
			infoAppend("ERR: Could not read Gen2 Q"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->slotsAdjustComboBox->isEnabled())
	{
		res = m_reader->qMethod(set.gen2QMethod);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Q Method");
		else{
			infoAppend("ERR: Could not read Gen2 Q Method"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->sessionComboBox->isEnabled())
	{
		res = m_reader->session(set.gen2Session);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Session");
		else{
			infoAppend("ERR: Could not read Gen2 Session"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->inventoryRoundsSpinBox->isEnabled())
	{
		res = m_reader->inventoryRounds(set.gen2InvRounds);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Inventory Rounds");
		else{
			infoAppend("ERR: Could not read Gen2 Inventory Rounds"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->selMask1_useGroupBox->isEnabled())
	{
		res = m_reader->selectionMask1(set.gen2SelectionMask1.memBank, set.gen2SelectionMask1.address, set.gen2SelectionMask1.size, set.gen2SelectionMask1.mask);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Selection Mask #1");
		else{
			infoAppend("ERR: Could not read Gen2 Selection Mask #1"); err = true;
		}
		pb->increasePorgressBar();
	}

	if(m_ui->selMask2_useGroupBox->isEnabled())
	{
		res = m_reader->selectionMask2(set.gen2SelectionMask2.memBank, set.gen2SelectionMask2.address, set.gen2SelectionMask2.size, set.gen2SelectionMask2.mask);
		if(res == QrfeGlobal::RES_OK)
			infoAppend("OK:  Read Gen2 Selection Mask #2");
		else{
			infoAppend("ERR: Could not read Gen2 Selection Mask #2"); err = true;
		}
		pb->increasePorgressBar();
	}

    if(m_ui->nxpBrandIdCheckBox->isEnabled())
    {
        res = m_reader->queryNxpBrandID(set.gen2CustomNxpBrandID);
        if(res == QrfeGlobal::RES_OK)
            infoAppend("OK:  Read Gen2 Query NXP Brand ID");
        else{
            infoAppend("ERR: Could not read Gen2 Query NXP Brand ID"); err = true;
        }
        pb->increasePorgressBar();
    }

	return !err;
}
