#include "pollingwindow.h"
#include "ui_pollingwindow.h"
#include "mainwindow.h"
#include "qjsonarray.h"
#include "qjsondocument.h"
#include "qjsonobject.h"
#include "qjsonvalue.h"
#include "QMessageBox"
#include "hexvalidator.h"

pollingwindow::pollingwindow(QWidget *parent,  QString cfg) :
    QDialog(parent),
    ui(new Ui::pollingwindow)
{
    ui->setupUi(this);
    configContent = cfg;

    ui->teDefinedCustomText->setEnabled(false);
    ui->teUndefinedCustomText->setEnabled(false);

    ui->edKey0->setValidator( new HexValidator(this) );
    ui->edKey1->setValidator( new HexValidator(this) );
    ui->edKey2->setValidator( new HexValidator(this) );
    ui->edKey3->setValidator( new HexValidator(this) );
    ui->edKey4->setValidator( new HexValidator(this) );
    ui->DsAppId->setValidator( new HexValidator(this) );

    json = QJsonDocument::fromJson(cfg.toUtf8());

    const QJsonValue v = json["rfid"];
    int hardware_ver = json["hardware_version"].toInt();

    //gpio options
    ui->cbDefinedGpio->clear();
    ui->cbUndefinedGpio->clear();

    switch (hardware_ver)
    {
        case C1_HARDWARE:
            ui->cbDefinedGpio->addItem("None");
            ui->cbDefinedGpio->addItem("GPIO 4");
            ui->cbDefinedGpio->addItem("GPIO 5");
            ui->cbDefinedGpio->addItem("GPIO 16");
            ui->cbDefinedGpio->addItem("GPIO 17");
            ui->cbUndefinedGpio->addItem("None");
            ui->cbUndefinedGpio->addItem("GPIO 4");
            ui->cbUndefinedGpio->addItem("GPIO 5");
            ui->cbUndefinedGpio->addItem("GPIO 16");
            ui->cbUndefinedGpio->addItem("GPIO 17");
        break;
        case C1_V2_HARDWARE:
        case C1_BALLERS_HARDWARE:
            ui->cbDefinedGpio->addItem("None");
            ui->cbDefinedGpio->addItem("GPIO 2");
            ui->cbDefinedGpio->addItem("GPIO 21");
            ui->cbDefinedGpio->addItem("GPIO 32");
            ui->cbDefinedGpio->addItem("GPIO 33");
            ui->cbUndefinedGpio->addItem("None");
            ui->cbUndefinedGpio->addItem("GPIO 2");
            ui->cbUndefinedGpio->addItem("GPIO 21");
            ui->cbUndefinedGpio->addItem("GPIO 32");
            ui->cbUndefinedGpio->addItem("GPIO 33");
        break;
        case C1_MODULE_HARDWARE:
        case C1_MODULEv2_HARDWARE:
            ui->cbDefinedGpio->addItem("None");
            ui->cbDefinedGpio->addItem("GPIO 14");
            ui->cbDefinedGpio->addItem("GPIO 15");
            ui->cbDefinedGpio->addItem("GPIO 26");
            ui->cbUndefinedGpio->addItem("None");
            ui->cbUndefinedGpio->addItem("GPIO 14");
            ui->cbUndefinedGpio->addItem("GPIO 15");
            ui->cbUndefinedGpio->addItem("GPIO 26");
            break;
        case C1_MUX_HARDWARE:
        case C1_MUXv2_HARDWARE:
            ui->cbAnt1->setEnabled(true);
            ui->cbAnt2->setEnabled(true);
            ui->cbAnt3->setEnabled(true);
            ui->cbAnt4->setEnabled(true);
            ui->cbAnt5->setEnabled(true);
            ui->cbAnt6->setEnabled(true);
            ui->cbAnt7->setEnabled(true);
            ui->cbAnt8->setEnabled(true);
            ui->cbKnownTagsOnAll->setEnabled(true);
        break;
        case C2_V1_HARDWARE:
        ui->cbDefinedGpio->addItem("None");
        ui->cbDefinedGpio->addItem("GPIO 1");
        ui->cbDefinedGpio->addItem("GPIO 2");
        ui->cbDefinedGpio->addItem("GPIO 3");
        ui->cbDefinedGpio->addItem("GPIO 4");
        ui->cbDefinedGpio->addItem("GPIO 5");
        ui->cbDefinedGpio->addItem("GPIO 6");
        ui->cbUndefinedGpio->addItem("None");
        ui->cbUndefinedGpio->addItem("GPIO 1");
        ui->cbUndefinedGpio->addItem("GPIO 2");
        ui->cbUndefinedGpio->addItem("GPIO 3");
        ui->cbUndefinedGpio->addItem("GPIO 4");
        ui->cbUndefinedGpio->addItem("GPIO 5");
        ui->cbUndefinedGpio->addItem("GPIO 6");
        ui->cbReadTagMemory->removeItem(2);
        ui->WidgetRfidPower->setVisible(false);
        break;
        case C1_10X_HARDWARE:
        break;
    }

    switch (hardware_ver)
    {
        case C1_HARDWARE:
        case C1_V2_HARDWARE:
        case C1_BALLERS_HARDWARE:
        case C1_MODULEv2_HARDWARE:
        case C1_MUX_HARDWARE:
        case C1_MUXv2_HARDWARE:
        case C2_V1_HARDWARE:
            ui->cbDefinedLed->addItem("None");
            ui->cbDefinedLed->addItem("Red");
            ui->cbDefinedLed->addItem("Green");
            ui->cbDefinedLed->addItem("Blue");
            ui->cbDefinedLed->addItem("White");

            ui->cbUndefinedLed->addItem("None");
            ui->cbUndefinedLed->addItem("Red");
            ui->cbUndefinedLed->addItem("Green");
            ui->cbUndefinedLed->addItem("Blue");
            ui->cbUndefinedLed->addItem("White");
        break;
        case C1_MODULE_HARDWARE:
            ui->cbDefinedLed->addItem("None");
            ui->cbDefinedLed->addItem("Green");
            ui->cbUndefinedLed->addItem("None");
            ui->cbUndefinedLed->addItem("Green");
            break;
        case C1_10X_HARDWARE:
        break;
    }

    if (v.isObject())
    {
        int intVal = 0;
        QString stmp;

        QStringList color = {"None", "Red", "Green", "Blue", "White"};
        intVal = v["tech_support"].toInt();
        ui->cbMifareEn->setChecked((intVal & 0x01) == 0x01);
        ui->cbIcodeEn->setChecked((intVal & 0x10) == 0x10);

        ui->cbRfidPower->setCurrentIndex(v["rfid_power"].toInt());

        ui->cbPollingEn->setChecked(v["polling_enabled"].toInt() == 1);
        ui->sbPollingTimeout->setValue(v["polling_timeout"].toInt());
        ui->sbIgnoreLast->setValue(v["ignore_timeout"].toInt());
        ui->cbKnownTagsOnAll->setChecked(v["check_all_ant"].toInt() == 1);

        ui->cbReadTagMemory->setCurrentIndex(v["read_memory_en"].toInt());

        on_cbReadTagMemory_currentIndexChanged(v["read_memory_en"].toInt());

        ui->sbReadBlockNo->setValue(v["read_memory_no"].toInt());
        ui->sbReadBlockCount->setValue(v["read_memory_count"].toInt());
        ui->sbKeyNo->setValue(v["read_memory_keyno"].toInt());
        ui->cbMifareKey->setCurrentIndex(v["read_memory_keyab"].toInt());

        //desfire polling read
        stmp.setNum(v["read_df_app_id"].toInt(), 16);
        ui->DsAppId->setText(stmp);
        ui->DsReaderAuthKey->setValue(v["read_df_reader_key"].toInt());
        ui->DsCardAuthKey->setValue(v["read_df_card_key"].toInt());
        ui->DsAuthType->setCurrentIndex(v["read_df_auth_type"].toInt());
        ui->DsCommType->setCurrentIndex(v["read_df_comm_mode"].toInt());
        ui->DsFileId->setValue(v["read_df_file_id"].toInt());
        ui->DsFileOffset->setValue(v["read_df_file_offset"].toInt());
        ui->DsNumberOfBytes->setValue(v["read_df_file_len"].toInt());

        QJsonValue scenario = v["known_tag"];
        QString gpio = "GPIO " + QString::number(scenario["gpio"].toInt());
        ui->cbDefinedGpio->setCurrentText(gpio);
        ui->cbDefinedGpioAction->setCurrentIndex(scenario["gpio_level"].toInt());
        ui->cbDefinedAsyncPacket->setCurrentIndex(scenario["message"].toInt());
        ui->cbDefinedLed->setCurrentText(color[scenario["led_color"].toInt()]);
        ui->sbDefinedDuration->setValue(scenario["timeout"].toInt());
        ui->teDefinedCustomText->setText(scenario["message_format"].toString());

        scenario = v["unknown_tag"];
        gpio = "GPIO " + QString::number(scenario["gpio"].toInt());
        ui->cbUndefinedGpio->setCurrentText(gpio);
        ui->cbUndefinedGpioAction->setCurrentIndex(scenario["gpio_level"].toInt());
        ui->cbUndefinedAsyncPacket->setCurrentIndex(scenario["message"].toInt());
        ui->cbUndefinedLed->setCurrentText(color[scenario["led_color"].toInt()]);
        ui->sbUndefinedDuration->setValue(scenario["timeout"].toInt());
        ui->teUndefinedCustomText->setText(scenario["message_format"].toString());

        intVal = v["selected_antennas"].toInt();
        ui->cbAnt1->setChecked((intVal & 0x01) > 0);
        ui->cbAnt2->setChecked((intVal & 0x02) > 0);
        ui->cbAnt3->setChecked((intVal & 0x04) > 0);
        ui->cbAnt4->setChecked((intVal & 0x08) > 0);
        ui->cbAnt5->setChecked((intVal & 0x10) > 0);
        ui->cbAnt6->setChecked((intVal & 0x20) > 0);
        ui->cbAnt7->setChecked((intVal & 0x40) > 0);
        ui->cbAnt8->setChecked((intVal & 0x80) > 0);

        ui->cbKeyType0->setCurrentIndex(v["keyType0"].toInt());
        ui->cbKeyType1->setCurrentIndex(v["keyType1"].toInt());
        ui->cbKeyType2->setCurrentIndex(v["keyType2"].toInt());
        ui->cbKeyType3->setCurrentIndex(v["keyType3"].toInt());
        ui->cbKeyType4->setCurrentIndex(v["keyType4"].toInt());

        ui->edKey0->setText(v["key0"].toString());
        ui->edKey1->setText(v["key1"].toString());
        ui->edKey2->setText(v["key2"].toString());
        ui->edKey3->setText(v["key3"].toString());
        ui->edKey4->setText(v["key4"].toString());
    }
    else
    {
        //dupa
        QMessageBox::information(this, "Waring", "Something went wrong. Please check if you have latest firmware in the device", QMessageBox::Ok);
        this->close();
    }
    on_cbReadTagMem_stateChanged(0);
    on_cbKeyType0_currentIndexChanged(0);
    on_cbKeyType1_currentIndexChanged(0);
    on_cbKeyType2_currentIndexChanged(0);
    on_cbKeyType3_currentIndexChanged(0);
    on_cbKeyType4_currentIndexChanged(0);
}

#define PH_KEYSTORE_KEY_TYPE_AES128         0x00U   /**< AES 128 Key [16]. */
#define PH_KEYSTORE_KEY_TYPE_AES192         0x01U   /**< AES 192 Key [24]. */
#define PH_KEYSTORE_KEY_TYPE_AES256         0x02U   /**< AES 256 Key [32]. */
#define PH_KEYSTORE_KEY_TYPE_DES            0x03U   /**< DES Single Key.   */
#define PH_KEYSTORE_KEY_TYPE_2K3DES         0x04U   /**< 2 Key Triple Des. */
#define PH_KEYSTORE_KEY_TYPE_3K3DES         0x05U   /**< 3 Key Triple Des. */
#define PH_KEYSTORE_KEY_TYPE_MIFARE         0x06U   /**< MIFARE (R) Key. */

uint16_t getKeySize(uint16_t wKeyType)
{
    switch (wKeyType)
    {
        case PH_KEYSTORE_KEY_TYPE_MIFARE:
            return 12;

        case PH_KEYSTORE_KEY_TYPE_DES:
            return 16;

        case PH_KEYSTORE_KEY_TYPE_2K3DES:
        case PH_KEYSTORE_KEY_TYPE_AES128:
            return 16;

        case PH_KEYSTORE_KEY_TYPE_3K3DES:
        case PH_KEYSTORE_KEY_TYPE_AES192:
            return 24;

        case PH_KEYSTORE_KEY_TYPE_AES256:
            return 32;

        default:
            return 0;
    }
}

pollingwindow::~pollingwindow()
{
    delete ui;
}

void pollingwindow::on_buttonBox_accepted()
{

}

void pollingwindow::on_cbMifareEn_stateChanged(int arg1)
{
    if (ui->cbMifareEn->isChecked() == false && ui->cbIcodeEn->isChecked() == false)
    {
        ui->cbIcodeEn->setChecked(true);
    }
}

void pollingwindow::on_cbIcodeEn_stateChanged(int arg1)
{
    if (ui->cbMifareEn->isChecked() == false && ui->cbIcodeEn->isChecked() == false)
    {
        ui->cbMifareEn->setChecked(true);
    }
}

void pollingwindow::on_cbReadTagMem_stateChanged(int arg1)
{

}

void pollingwindow::on_cbKeyType0_currentIndexChanged(int index)
{
    ui->edKey0->setMaxLength(getKeySize(ui->cbKeyType0->currentIndex())*3);
}

void pollingwindow::on_cbKeyType1_currentIndexChanged(int index)
{
    ui->edKey1->setMaxLength(getKeySize(ui->cbKeyType1->currentIndex())*3);
}

void pollingwindow::on_cbKeyType2_currentIndexChanged(int index)
{
    ui->edKey2->setMaxLength(getKeySize(ui->cbKeyType2->currentIndex())*3);
}

void pollingwindow::on_cbKeyType3_currentIndexChanged(int index)
{
    ui->edKey3->setMaxLength(getKeySize(ui->cbKeyType3->currentIndex())*3);
}

void pollingwindow::on_cbKeyType4_currentIndexChanged(int index)
{
    ui->edKey4->setMaxLength(getKeySize(ui->cbKeyType4->currentIndex())*3);
}

void pollingwindow::on_btOK_clicked()
{
    //store all data in the json file
    QJsonObject rootObject = json.object();
    QJsonObject v = rootObject["rfid"].toObject();

    int intVal = 0;

    //lets validate keys
    QString key;
    int keyType;

    if (ui->cbMifareEn->isChecked())
    {
        intVal |= 0x01;
    }

    if (ui->cbIcodeEn->isChecked())
    {
        intVal |= 0x10;
    }

    v["tech_support"] = intVal;
    if (ui->cbPollingEn->isChecked())
        v["polling_enabled"] = 1;
    else
        v["polling_enabled"] = 0;

    v["rfid_power"] = ui->cbRfidPower->currentIndex();
    v["polling_timeout"] = ui->sbPollingTimeout->value();
    v["ignore_timeout"] =  ui->sbIgnoreLast->value();
    v["read_memory_en"] = ui->cbReadTagMemory->currentIndex();

    v["read_memory_no"] = ui->sbReadBlockNo->value();
    v["read_memory_count"] = ui->sbReadBlockCount->value();
    v["read_memory_keyno"] = ui->sbKeyNo->value();
    v["read_memory_keyab"] = ui->cbMifareKey->currentIndex();

    if (ui->cbKnownTagsOnAll->isChecked())
    {
        v["check_all_ant"] = 1;
    }
    else
    {
        v["check_all_ant"] = 0;
    }

    bool bStatus = false;
    int nHex = ui->DsAppId->text().remove(" ").toUInt(&bStatus,16);
    v["read_df_app_id"] = nHex;
    v["read_df_reader_key"] = ui->DsReaderAuthKey->value();
    v["read_df_card_key"] = ui->DsCardAuthKey->value();
    v["read_df_auth_type"] = ui->DsAuthType->currentIndex();
    v["read_df_comm_mode"] = ui->DsCommType->currentIndex();
    v["read_df_file_id"] = ui->DsFileId->value();
    v["read_df_file_offset"] = ui->DsFileOffset->value();
    v["read_df_file_len"] = ui->DsNumberOfBytes->value();

    QJsonObject known = v["known_tag"].toObject();

    known["gpio"] = ui->cbDefinedGpio->currentText().remove(0,5).toInt();
    known["gpio_level"] = ui->cbDefinedGpioAction->currentIndex();
    known["message"] =  ui->cbDefinedAsyncPacket->currentIndex();
    known["message_format"] = ui->teDefinedCustomText->text();

    if (ui->cbDefinedLed->currentText() == "Red")
        intVal = 1;
    else if (ui->cbDefinedLed->currentText() == "Green")
        intVal = 2;
    else if (ui->cbDefinedLed->currentText() == "Blue")
        intVal = 3;
    else if (ui->cbDefinedLed->currentText() == "White")
        intVal = 4;
    else
        intVal = 0;

    known["led_color"] = intVal;
    known["timeout"] = ui->sbDefinedDuration->value();

    QJsonObject unknown = v["unknown_tag"].toObject();

    unknown["gpio"] = ui->cbUndefinedGpio->currentText().remove(0,5).toInt();
    unknown["gpio_level"] = ui->cbUndefinedGpioAction->currentIndex();
    unknown["message"] =  ui->cbUndefinedAsyncPacket->currentIndex();
    unknown["message_format"] = ui->teUndefinedCustomText->text();

    if (ui->cbUndefinedLed->currentText() == "Red")
        intVal = 1;
    else if (ui->cbUndefinedLed->currentText() == "Green")
        intVal = 2;
    else if (ui->cbUndefinedLed->currentText() == "Blue")
        intVal = 3;
    else if (ui->cbUndefinedLed->currentText() == "White")
        intVal = 4;
    else
        intVal = 0;

    unknown["led_color"] = intVal;
    unknown["timeout"] =  ui->sbUndefinedDuration->value();

    v.remove("known_tag");
    v.insert("known_tag", known);
    v.remove("unknown_tag");
    v.insert("unknown_tag", unknown);

    intVal = 0;
    if (ui->cbAnt1->isChecked()) intVal |= 0x01;
    if (ui->cbAnt2->isChecked()) intVal |= 0x02;
    if (ui->cbAnt3->isChecked()) intVal |= 0x04;
    if (ui->cbAnt4->isChecked()) intVal |= 0x08;
    if (ui->cbAnt5->isChecked()) intVal |= 0x10;
    if (ui->cbAnt6->isChecked()) intVal |= 0x20;
    if (ui->cbAnt7->isChecked()) intVal |= 0x40;
    if (ui->cbAnt8->isChecked()) intVal |= 0x80;

    v["selected_antennas"] = intVal;

    key = ui->edKey0->text().remove(QChar(' '), Qt::CaseSensitive);
    keyType = ui->cbKeyType0->currentIndex();

    if (getKeySize(keyType) * 2 != key.length())
    {
        ui->edKey0->setFocus();
        ui->tabs->setCurrentIndex(1);
        QMessageBox::information(this, "Waring", "Please provide the correct key 0", QMessageBox::Ok);
        return;
    }
    v["key0"] = key;
    v["keyType0"] = keyType;


    key = ui->edKey1->text().remove(QChar(' '), Qt::CaseSensitive);
    keyType = ui->cbKeyType1->currentIndex();
    if (getKeySize(keyType) * 2 != key.length())
    {
        ui->edKey1->setFocus();
        ui->tabs->setCurrentIndex(1);
        QMessageBox::information(this, "Waring", "Please provide the correct key 1", QMessageBox::Ok);
        return;
    }
    v["key1"] = key;
    v["keyType1"] = keyType;


    key = ui->edKey2->text().remove(QChar(' '), Qt::CaseSensitive);
    keyType = ui->cbKeyType2->currentIndex();
    if (getKeySize(keyType) * 2 != key.length())
    {
        ui->edKey2->setFocus();
        ui->tabs->setCurrentIndex(1);
        QMessageBox::information(this, "Waring", "Please provide the correct key 2", QMessageBox::Ok);
        return;
    }
    v["key2"] = key;
    v["keyType2"] = keyType;


    key = ui->edKey3->text().remove(QChar(' '), Qt::CaseSensitive);
    keyType = ui->cbKeyType3->currentIndex();
    if (getKeySize(keyType) * 2 != key.length())
    {
        ui->edKey3->setFocus();
        ui->tabs->setCurrentIndex(1);
        QMessageBox::information(this, "Waring", "Please provide the correct key 3", QMessageBox::Ok);
        return;
    }
    v["key3"] = key;
    v["keyType3"] = keyType;

    key = ui->edKey4->text().remove(QChar(' '), Qt::CaseSensitive);
    keyType = ui->cbKeyType4->currentIndex();
    if (getKeySize(keyType) * 2 != key.length())
    {
        ui->edKey4->setFocus();
        ui->tabs->setCurrentIndex(1);
        QMessageBox::information(this, "Waring", "Please provide the correct key 4", QMessageBox::Ok);
        return;
    }
    v["key4"] = key;
    v["keyType4"] = keyType;

    rootObject.remove("rfid");
    rootObject.insert("rfid", v);

     json.setObject(rootObject);

    configContent = json.toJson();
    emit updateConfiguration(configContent);

    this->close();
}

void pollingwindow::on_btCancel_clicked()
{
    this->close();
}

void pollingwindow::on_cbDefinedAsyncPacket_currentIndexChanged(int index)
{
    if (index == 4)
    {
        ui->teDefinedCustomText->setEnabled(true);
    }
    else
    {
        ui->teDefinedCustomText->setEnabled(false);
    }
}

void pollingwindow::on_cbUndefinedAsyncPacket_currentIndexChanged(int index)
{
    if (index == 4)
    {
        ui->teUndefinedCustomText->setEnabled(true);
    }
    else
    {
        ui->teUndefinedCustomText->setEnabled(false);
    }
}

void pollingwindow::on_pushButton_clicked()
{
    QMessageBox::information(this, "Info", "%u -	tag UID\n%a - 	antenna index\n%m - 	memory content (only if reading memory is setup correctly)\n%i - 	idx msg/tag counter since restart\n%t - 	timestamp in milliseconds\n<CR> - 	Carriage return\n<LF> - 	Line feed", QMessageBox::Ok);
}

void pollingwindow::on_pushButton_2_clicked()
{
    QMessageBox::information(this, "Info", "%u -	tag UID\n%a - 	antenna index\n%m - 	memory content (only if reading memory is setup correctly)\n%i - 	idx msg/tag counter since restart\n%t - 	timestamp in milliseconds\n<CR> - 	Carriage return\n<LF> - 	Line feed", QMessageBox::Ok);
}

void pollingwindow::on_cbReadTagMemory_activated(int index)
{

}

void pollingwindow::on_cbReadTagMemory_currentIndexChanged(int index)
{
    if (index == 1)
    {
        ui->WidgetRead_1->setVisible(true);
        ui->WidgetRead_2->setVisible(true);
        ui->WidgetRead_3->setVisible(true);
        ui->WidgetRead_4->setVisible(true);
    }
    else
    {
        ui->WidgetRead_1->setVisible(false);
        ui->WidgetRead_2->setVisible(false);
        ui->WidgetRead_3->setVisible(false);
        ui->WidgetRead_4->setVisible(false);
    }

    //desfire
    if (index == 2)
    {
        ui->WidgetDesfire_1->setVisible(true);
        ui->WidgetDesfire_2->setVisible(true);
        ui->WidgetDesfire_3->setVisible(true);
        ui->WidgetDesfire_4->setVisible(true);
        ui->WidgetDesfire_5->setVisible(true);
        ui->WidgetDesfire_6->setVisible(true);
        ui->WidgetDesfire_7->setVisible(true);
        ui->WidgetDesfire_8->setVisible(true);
    }
    else
    {
        ui->WidgetDesfire_1->setVisible(false);
        ui->WidgetDesfire_2->setVisible(false);
        ui->WidgetDesfire_3->setVisible(false);
        ui->WidgetDesfire_4->setVisible(false);
        ui->WidgetDesfire_5->setVisible(false);
        ui->WidgetDesfire_6->setVisible(false);
        ui->WidgetDesfire_7->setVisible(false);
        ui->WidgetDesfire_8->setVisible(false);
    }
}

QString pollingwindow::byte2hexstring(uint8_t value)
{
    QString hexValue;

    if (value < 16)
    {
        hexValue = QString( "0%1" ).arg( value, 1, 16 ).toUpper();
    }
    else
    {
        hexValue = QString( "%1" ).arg( value, 1, 16 ).toUpper();
    }

    return hexValue;
}

void pollingwindow::binaryProtocolFrameComplete(uint8_t *header, size_t hlen, uint8_t *buff, size_t len)
{
    Q_UNUSED(header);
    Q_UNUSED(hlen);

    len -= 2;

    switch (buff[0])
    {
    case CMD_ACK:
        switch (buff[1])
        {
            case CMD_KNOWN_LIST:
            if (len > 4)
            {
                uint8_t cmd[5];
                QString uid;

                cmd[0] = CMD_KNOWN_LIST;
                cmd[1] = 1;

                uid = QString( "[%1] " ).arg(byte2hexstring(buff[2]));

                for (size_t k=3; k < len; k++)
                {
                    uid += QString( "%1" ).arg(byte2hexstring(buff[k]));
                }

                ui->lvTags->addItem(uid);
                emit binaryFrameSend(cmd,2);
            }
            else
            {
                if (buff[2] == 0 || buff[2] == 1)
                {
                    ui->labKnownTags->setText(QString( "Known tag list - %1" ).arg(ui->lvTags->count()));
                }

                if (buff[2] == 0x03 || buff[2] == 0x02) //tag added or list cleared
                {
                    QString suid;
                    uint8_t cmd[20];
                    uint8_t idx = 0;
                    if (updatePos < ui->lvTags->count())
                    {
                        suid = ui->lvTags->item(updatePos)->text();
                        suid = suid.remove(" ").remove("[").remove("]");

                        QByteArray hex = QByteArray::fromHex(suid.toLatin1());

                        cmd[idx++] = CMD_KNOWN_LIST;
                        cmd[idx++] = 0x03;

                        for (int k=0; k < hex.count(); k++)
                        {
                            cmd[idx++] = (uint8_t)hex.at(k);
                        }

                        updatePos++;
                        emit binaryFrameSend(cmd,idx);
                    }
                    else
                    {
                        QMessageBox::information(this, "Info", "Tag list updated on the device", QMessageBox::Ok);
                    }
                }
            }
            break;
        case CMD_GET_UID:
            if (len > 4)
            {
                QString uid;

                uid = QString( "[%1] " ).arg(byte2hexstring(buff[3]));

                for (size_t k=4; k < len; k++)
                {
                    uid += QString( "%1" ).arg(byte2hexstring(buff[k]));
                }

                ui->lvTags->addItem(uid);
            }
            ui->labKnownTags->setText(QString( "Known tag list - %1" ).arg(ui->lvTags->count()));
            break;
        }
        break;
    }
}

void pollingwindow::on_btGetList_clicked()
{
    uint8_t cmd[5];

    ui->labKnownTags->setText("Known tag list - updating please wait...");
    qApp->processEvents();

    cmd[0] = CMD_KNOWN_LIST;
    cmd[1] = 0;

    ui->lvTags->clear();

    emit binaryFrameSend(cmd,2);
}

void pollingwindow::on_btAdd_clicked()
{
    uint8_t cmd[5];

    cmd[0] = CMD_GET_TAG_COUNT;

    emit binaryFrameSend(cmd,1);
}

void pollingwindow::on_btDelete_clicked()
{
    for(auto item: ui->lvTags->selectedItems())
    {
        delete item;
    }
}

void pollingwindow::on_btWrite2Device_clicked()
{
    uint8_t cmd[5];

    updatePos = 0;

    cmd[0] = CMD_KNOWN_LIST;
    cmd[1] = 0x02;

    emit binaryFrameSend(cmd,2);
}
