#include "BCodeTerminalProtocolBM.h"

BCodeTerminalProtocolBM::BCodeTerminalProtocolBM(QObject* parent) : DeviceProtocolBase(parent)
{

}

BCodeTerminalProtocolBM::~BCodeTerminalProtocolBM()
{

}

// 解析数据
bool BCodeTerminalProtocolBM::parseDeviceFrameData(QByteArray rawData, DeviceFrameBaseDto * frameData, int frameType)
{
    if (frameType == BCODE_TERMINAL_FRAME_TYPE::STATUS_FRAME)
    {
        qint8 length = rawData.mid(1, 2).toInt(0, 16) + 1;
        QByteArray content = rawData.mid(19, length - 24);
        int outBdcByte = 0;
        int outBacByte = 0;
        QString outStr = "";

        ((BCodeTerminalStatusDto *) frameData)->devStatus = content.at(0);
        ((BCodeTerminalStatusDto *) frameData)->bdcInStatus = content.at(2);
        ((BCodeTerminalStatusDto *) frameData)->bacInStatus = content.at(3);
        ((BCodeTerminalStatusDto *) frameData)->fiveInStatus = content.at(4);

        outBdcByte = content.mid(6, 1).toInt(0, 16);
        outBacByte = content.mid(5, 1).toInt(0, 16);
        for (int i = 0; i < 4; i++)
        {
            ((BCodeTerminalStatusDto *) frameData)->bdcOutStatusList.append(QString("%1").arg(outBdcByte % 2));
            ((BCodeTerminalStatusDto *) frameData)->bacOutStatusList.append(QString("%1").arg(outBacByte % 2));

            outBdcByte = outBdcByte / 2;
            outBacByte = outBacByte / 2;
        }

        ((BCodeTerminalStatusDto *) frameData)->ref = content.at(7);
        ((BCodeTerminalStatusDto *) frameData)->track = content.at(8);
        ((BCodeTerminalStatusDto *) frameData)->bacRange = content.mid(9, 4).toFloat();
        ((BCodeTerminalStatusDto *) frameData)->bacRatio = content.mid(13, 1).toInt();

        ((BCodeTerminalStatusDto *)frameData)->frameType = B_CODE_TERMINAL_STATUS_FRAME_TYPE;

        return true;
    } else if (frameType == BCODE_TERMINAL_FRAME_TYPE::CMDREP_FRAME)
    {
        qint8 length = rawData.mid(1, 2).toInt(0, 16);
        QByteArray content = rawData.mid(length - 6, 1);

        ((CommandReplyDto *)frameData)->cmdStatus = content == "1" ? 1 : 0;

        return true;
    }
    return false;
}

QByteArray BCodeTerminalProtocolBM::generateSettingCommand(QString devCode, QString commandType, QString valueSet)
{
    QByteArray commandBytes;

    commandBytes.append("3");
    commandBytes.append("1304-20").append(0x20);
    commandBytes.append(devCode);
    commandBytes.append(commandType);
    if (commandType == "1")
    {
        commandBytes.append(valueSet);
    } else if (commandType == "2")
    {
        QStringList valueList = valueSet.split(",");
        if (valueList.at(0).size() > 4)
        {
            commandBytes.append(valueList.at(0).right(4));
        } else if (valueList.at(0).size() < 4)
        {
            commandBytes.append(4 - valueList.at(0).size(), '0');
            commandBytes.append(valueList.at(0));
        } else
        {
            commandBytes.append(valueList.at(0));
        }

        commandBytes.append(valueList.at(1).right(1));
    }
    commandBytes.append(this->buildCRC16(commandBytes));
    commandBytes.append("*");

    commandBytes.prepend(QString::number(commandBytes.size() + 3, 16).toUpper().toLocal8Bit());
    commandBytes.prepend("$");

    return commandBytes;
}

DeviceFrameBaseDto * BCodeTerminalProtocolBM::frameFactory(int frameType)
{
    DeviceFrameBaseDto * frameData = 0;
    switch (frameType) {
        case BCodeTerminalProtocolBM::BCODE_TERMINAL_FRAME_TYPE::STATUS_FRAME :
            frameData = new BCodeTerminalStatusDto();
            break;

        case BCodeTerminalProtocolBM::BCODE_TERMINAL_FRAME_TYPE::CMDREP_FRAME :
            frameData = new CommandReplyDto();
            break;

        default:
            frameData = nullptr;
            break;
    }

    return frameData;
}

//
QList<QByteArray> BCodeTerminalProtocolBM::extractFrameList(QByteArray rawData)
{
    QList<QByteArray> resultList;
    while (rawData.endsWith(QByteArray("*")) == true && rawData.startsWith("$") == true)
    {
        QByteArray ba;
        int start = rawData.indexOf("$");
        int end = rawData.indexOf("*", start);
        qint8 length = end - start + 1;
//        qint8 length = rawData.mid(1, 2).toInt(0, 16) + 1;
        if (rawData.at(0) == '$' && rawData.at(length - 1) == '*')
        {
            ba.append(rawData.mid(0, length));
            resultList.append(ba);
            ba.clear();
            rawData = rawData.mid(length, rawData.size() - length);
        } else
        {
            break;
        }
    }

    return resultList;
}

// 检测帧格式，帧头帧尾
int BCodeTerminalProtocolBM::checkFrame(QByteArray rawData)
{
    if (rawData.at(0) == '$' && rawData.at(rawData.size() - 1) == '*')
    {
        if (rawData.at(3) == '2' && rawData.at(20) == '2')
        {
            return BCODE_TERMINAL_FRAME_TYPE::STATUS_FRAME;
        } else if (rawData.at(3) == '4')
        {
            return BCODE_TERMINAL_FRAME_TYPE::CMDREP_FRAME;
        }
    }

    return BCODE_TERMINAL_FRAME_TYPE::UNKNOW_FRAME;
}
