#include "FrequencyTuningProtocolTX.h"

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

}

FrequencyTuningProtocolTX::~FrequencyTuningProtocolTX()
{

}

DeviceFrameBaseDto * FrequencyTuningProtocolTX::frameFactory(int frameType)
{
    DeviceFrameBaseDto * frameData = 0;
    switch (frameType) {
        case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::STATUS_FRAME :
            frameData = new FrequencyTuningStatusFreqDto();
            break;

        case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::LOCK_FRAME :
            frameData = new FrequencyTuningStatusLockDto();
            break;

        case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::CMDREP_FRAME:
            frameData = new CommandReplyDto();
            break;

        default:
            frameData = nullptr;
            break;
    }

    return frameData;
}

bool FrequencyTuningProtocolTX::parseDeviceFrameData(QByteArray rawData, DeviceFrameBaseDto * ftFrameData, int frameType)
{
    // get the raw data between ',' and '*'
    qint8 length = rawData.mid(1, 2).toInt(0, 16);
    QByteArray content = rawData.mid(20, length - 25);

    switch (frameType) {
    case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::STATUS_FRAME :
    {
        ((FrequencyTuningStatusFreqDto *)ftFrameData)->devStatus = content.at(0);
        QList<QByteArray> subValues = content.split(0x20);
        if (subValues.size() == 6)
        {
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->freqAdjust = subValues.at(1).toDouble();
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->freqAdjustAcc = subValues.at(2).toDouble();
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->phaseShift = subValues.at(3).toLongLong();
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->pulseWidth = subValues.at(4).toLongLong();
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->phaseAdjust = subValues.at(5).toDouble();
            ((FrequencyTuningStatusFreqDto *)ftFrameData)->frameType = FREQUENCY_TUNING_FREQ_FRAME_TYPE;
            return true;
        }
        return false;
    }
    case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::LOCK_FRAME :
    {
        ((FrequencyTuningStatusLockDto *)ftFrameData)->lockStatus = content.at(2);
        ((FrequencyTuningStatusLockDto *)ftFrameData)->frameType = FREQUENCY_TUNING_LOCK_FRAME_TYPE;
        return true;
    }
    case FrequencyTuningProtocolTX::FREQUENCY_TUNING_FRAME_TYPE::CMDREP_FRAME :
    {
        ((CommandReplyDto *)ftFrameData)->cmdStatus = content == "1" ? 1 : 0;
        return true;
    }
    default:
        break;
    }

    return false;
}

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

    commandBytes.append(commandType);
    commandBytes.append("BM1304-30");
    commandBytes.append(devCode);

    if (commandType == "3" || commandType =="4")
    {
        // 频率偏移设置 or 频率偏移步进量设置
        commandBytes.append(0x20);
        QString valueStr = QString::number(valueSet.toDouble(), 'e', 2).toUpper();
        if (valueSet.toDouble() >= 0)
        {
            valueStr.prepend('+');
        }
        commandBytes.append(valueStr);

    } else if (commandType == "5")
    {
        // PPS移相设置
        commandBytes.append(0x20);

        QString valueStr = QString("%1").arg(qAbs(valueSet.toLongLong()), 12, 10, QLatin1Char('0'));
        if (valueSet.toLongLong() >= 0)
        {
            valueStr.prepend('+');
        } else {
            valueStr.prepend("-");
        }
        commandBytes.append(valueStr);

    } else if (commandType == "6")
    {
        // PPS脉冲宽度设置
        commandBytes.append(0x20);
        QString valueStr = QString("%1").arg(valueSet.toLongLong(), 9, 10, QLatin1Char('0'));
        commandBytes.append(valueStr);

    } else if (commandType == "7")
    {
        // 相位步进量设置
        commandBytes.append(0x20);
        QString valueStr = QString("%1").arg(qAbs(valueSet.toDouble()), 14, 'f', 3, QLatin1Char('0'));
        if (valueSet.toDouble() >= 0)
        {
            valueStr.prepend('+');
        } else {
            valueStr.prepend('-');
        }
        commandBytes.append(valueStr);

    } else if (commandType == "8")
    {
        // PPS同步设置
        commandBytes.append(0x20).append("1");
    }

    commandBytes.append(0x20); //
    commandBytes.append(this->buildCRC16(commandBytes));
    commandBytes.append("*");

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

    return commandBytes;
}

QList<QByteArray> FrequencyTuningProtocolTX::extractFrameList(QByteArray rawData)
{
    QList<QByteArray> resultList;

    QByteArray ba;
    for (int i = 0; i < rawData.size(); i++)
    {
        ba.append(rawData.at(i));
        if (rawData.at(i) == '*')
        {
            resultList.append(ba);
            ba.clear();
        }
    }

    return resultList;
}

int FrequencyTuningProtocolTX::checkFrame(QByteArray rawData)
{
    // 帧尾不是*
    if (FREQ_TUNN_STATUS_FRAME_TAIL != rawData.at(rawData.size() - 1))
    {
        return FREQUENCY_TUNING_FRAME_TYPE::UNKNOW_FRAME;
    }

    // 帧头不是$
    if (FREQ_TUNN_STATUS_FRAME_HEAD == rawData.at(0))
    {
        if (rawData.at(3) == '2')
        {
            if (rawData.at(1+2+1+9+7+1) == '2')
            {
                return FREQUENCY_TUNING_FRAME_TYPE::LOCK_FRAME;
            } else if (rawData.at(1+2+1+9+7+1) == '3')
            {
                return FREQUENCY_TUNING_FRAME_TYPE::STATUS_FRAME;
            }
        } else if (rawData.at(3) == '9')
        {
            return FREQUENCY_TUNING_FRAME_TYPE::CMDREP_FRAME;
        } else
        {
            return FREQUENCY_TUNING_FRAME_TYPE::UNKNOW_FRAME;
        }
    } else
    {
        return FREQUENCY_TUNING_FRAME_TYPE::UNKNOW_FRAME;
    }
}
