#include "PacketTypes.h"

namespace PacketTypes
{
    bool BasePack::checkAddress() { return true; };
    void BasePack::set(IR_FOX::PackInfo *packInfo, uint16_t id)
    {
        this->packInfo = packInfo;
        this->id = id;

        if (checkAddress())
        {
            isAvailable = true;
            isRawAvailable = true;
#ifdef IRDEBUG_INFO
            Serial.print("  OK  ");
#endif
        }
        else
        {
            isRawAvailable = true;
#ifdef IRDEBUG_INFO
            Serial.print("  NOT-OK  ");
#endif
        }
    }

    uint16_t BasePack::_getAddrFrom(BasePack *obj)
    {
        return (obj->packInfo->buffer[obj->addressFromOffset] << 8) | obj->packInfo->buffer[obj->addressFromOffset + 1];
    };
    uint16_t BasePack::_getAddrTo(BasePack *obj)
    {
        return (obj->packInfo->buffer[obj->addressToOffset] << 8) | obj->packInfo->buffer[obj->addressToOffset + 1];
    };

    uint8_t BasePack::_getDataSize(BasePack *obj)
    {
        return obj->packInfo->packSize - crcBytes - obj->DataOffset;
    };
    uint8_t *BasePack::_getDataPrt(BasePack *obj)
    {
        return obj->packInfo->buffer + obj->DataOffset;
    };
    uint8_t BasePack::_getDataRawSize(BasePack *obj)
    {
        return obj->packInfo->packSize;
    };

    bool BasePack::available()
    {
        if (isAvailable)
        {
            isAvailable = false;
            isRawAvailable = false;
            return true;
        }
        else
        {
            return false;
        }
    };
    bool BasePack::availableRaw()
    {
        if (isRawAvailable)
        {
            isRawAvailable = false;
            return true;
        }
        else
        {
            return false;
        }
    };

    bool Data::checkAddress()
    {
        bool ret;
        IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret);
        return ret;
    }

    bool DataBack::checkAddress()
    {
        bool ret;
        if (getMsgType() == IR_MSG_BACK_TO)
        {
            DataOffset = 5;
            IR_FOX::checkAddressRuleApply((packInfo->buffer[addressToOffset] << 8) | packInfo->buffer[addressToOffset + 1], this->id, ret);
        }
        else
        {
            DataOffset = 3;
            ret = true;
        }
        return ret;
    }

    bool Accept::checkAddress() { return true; }

    bool Request::checkAddress()
    {
        bool ret;
        IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret);
        return ret;
    }
}