#pragma once
#include <PSX/File/file_types.hpp>
#include <PSX/GPU/gpu_types.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>

namespace JabyEngine {
    using FontPrimitive = GPU::SPRT::Linked;

    struct FontInfo {
        struct RenderInfo {
            GPU::SizeU8 font_size;
            GPU::SizeU8 kern_size;

            static constexpr RenderInfo empty() {
                return RenderInfo{.font_size = Make::SizeU8(), .kern_size = Make::SizeU8()};
            }
        };

        GPU::SizeU16 texture_size;
        RenderInfo   render_info;

        static constexpr FontInfo create(GPU::SizeU16 texture_size, GPU::SizeU8 font_size, GPU::SizeU8 kern_size) {
            return FontInfo{.texture_size = texture_size, .render_info = {.font_size = font_size, .kern_size = kern_size}};
        }

        static constexpr FontInfo create(GPU::SizeU16 texture_size, GPU::SizeU8 font_size) {
            return FontInfo::create(texture_size, font_size, font_size);
        }

        constexpr GPU::SizeU16 get_font_size() const {
            return GPU::SizeU16::from(this->render_info.font_size);
        }

        constexpr GPU::SizeU16 get_kern_size() const {
            return GPU::SizeU16::from(this->render_info.kern_size);
        }

        template<size_t Size>
        constexpr size_t estimate_str_render_length(const char (&str)[Size]) const {
            return (Size - 1)*FontInfo::get_kern_size().width;
        }
    };

    struct Cursor {
        GPU::PositionI16 pos;
        uint8_t          wiggle_count;

        static constexpr Cursor create(GPU::PositionI16 pos, uint8_t wiggle_count = 0) {
            return Cursor{.pos = pos, .wiggle_count = wiggle_count};
        }

        constexpr Cursor& change_position(GPU::PositionI16 pos) {
            this->pos = pos;
            return *this;
        }
    };

    using Wiggle = GPU::PositionI8[8];
}
