#pragma once

#include <iostream>

#include "../core.h"

#include "ItemKind2.h"
#include "ItemKind3.h"

namespace flyff {
    struct __attribute__((packed)) ItemProperty {
        static constexpr uint32_t COOLDOWN_FOOD = 0x00;
        static constexpr uint32_t COOLDOWN_REFRESHER = 0x03;
        static constexpr uint32_t COOLDOWN_VITALDRINK = 0x04;

        static constexpr uint32_t RECOVERY_COOLDOWN_INDEX[] = {0x03, 0x04, 0x00,
                                                               0x00, 0x01};

        union {
            DEFINE_MEMBER(0, const flyff::String, model);
            DEFINE_MEMBER(12, const uint32_t, id);

            DEFINE_MEMBER(60, const uint32_t, heal_hp);

            // Has to be bigger that 0 to be considered for cooldown.
            DEFINE_MEMBER(112, const int32_t, cooldown_time);

            DEFINE_MEMBER(156, const flyff::String, name);
            DEFINE_MEMBER(168, const flyff::String, icon);
            DEFINE_MEMBER(180, const flyff::String, description);

            DEFINE_MEMBER(244, const uint32_t, required_level);

            DEFINE_MEMBER(348, const ItemKind2, item_kind2);
            DEFINE_MEMBER(352, const ItemKind3, item_kind3);

            const MinimumSize<456> size;
        };

        bool is_food() const {
            static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400;

            if (item_kind2 == ItemKind2::Recovery) {
                const uint32_t cd = static_cast<uint32_t>(item_kind3) - RECOVERY_SUB_CATEGORY_START;
                if (cd < 5) {
                    return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_FOOD;
                }
            }

            return false;
        }

        bool is_quest() const { return item_kind2 == ItemKind2::Quest; }
    };

}  // namespace flyff