#include "tim_helper.hpp"
#include <stdio.hpp>

namespace JabyEngine {
    namespace FileProcessor {
        namespace {
            using GPU::AreaU16;

            struct BlockInfo {
                uint32_t size;
                uint16_t x;
                uint16_t y;
                uint16_t w;
                uint16_t h;
            };

            struct TIMState : public TIMFileProcessor::GenericTIM {
                static TIMState create() {
                    TIMState state;
                    return state;
                }

                virtual Progress parse_header(State::CDDataProcessor& data_proc) override {
                    static constexpr auto HEADER_SIZE = 2*sizeof(uint32_t);

                    if(data_proc.data_bytes >= (HEADER_SIZE + sizeof(BlockInfo))) {
                        static constexpr auto HAS_CLUT_BIT = (0x1 << 3);

                        data_proc.processed(sizeof(uint32_t));
                        const auto flag = data_proc.simple_read_r<uint32_t>();
                        
                        if(flag & HAS_CLUT_BIT) {
                            const auto block_info = data_proc.simple_read_r<BlockInfo>();
                            this->clut_area = AreaU16::create(block_info.x, block_info.y, block_info.w, block_info.h);
                        }

                        else {
                            this->clut_area = AreaU16::create(0, 0, 0, 0);
                        }
                        return Progress::Done;
                    }
                    return Progress::Error;
                }

                virtual Progress pre_data_parsing(State::CDDataProcessor& data_proc) {
                    if(data_proc.data_bytes >= sizeof(BlockInfo)) {
                        const auto block_info = data_proc.simple_read_r<BlockInfo>();
                        this->tex_area = AreaU16::create(block_info.x, block_info.y, block_info.w, block_info.h);
                        return Progress::Done;
                    }
                    return Progress::InProgress;
                }
            };
        }

        State create(const uint32_t* data_adr, const TIM& file) {
            using Callback = Progress(*)(State::CDDataProcessor& data_proc, TIMState& simple_tim);
            return State::from(TIMState::create(), data_adr, reinterpret_cast<Callback>(TIMFileProcessor::parse_header));
        }
    }
}