#pragma once
#include "../../System/IOPorts/gpu_io.hpp"
#include "linked_elements.hpp"
#include "primitive_support_types.hpp"

namespace JabyEngine {
    namespace GPU {
        struct TexPage : public internal::LinkedElementCreator<TexPage> {
            static constexpr bool is_render_primitive = true;

            GPU_IO_Values::GP0 value;

            static constexpr TexPage create(const PositionU16& tex_pos, TextureColorMode tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) {
                return TexPage{.value = GPU_IO_Values::GP0::TexPage(tex_pos, transparency, tex_color, dither, false)};
            }
        };

        struct CPU2VRAM {
            static constexpr bool is_render_primitive = true;
            
            GPU_IO_Values::GP0 cmd;
            GPU_IO_Values::GP0 pos;
            GPU_IO_Values::GP0 size;

            static constexpr CPU2VRAM create(const AreaU16& dst) {
                return CPU2VRAM{
                    .cmd  = GPU_IO_Values::GP0::CPU2VRAMBlitting(),
                    .pos  = GPU_IO_Values::GP0::PostionTopLeft(dst.position),
                    .size = GPU_IO_Values::GP0::WidthHeight(dst.size)
                };
            }
        };

        struct VRAM2VRAM {
            static constexpr bool is_render_primitive = true;
            
            GPU_IO_Values::GP0 cmd;
            GPU_IO_Values::GP0 src_pos;
            GPU_IO_Values::GP0 dst_pos;
            GPU_IO_Values::GP0 size;

            static constexpr VRAM2VRAM create(const AreaU16& src, const PositionU16& dst) {
                return VRAM2VRAM{
                    .cmd     = GPU_IO_Values::GP0::VRAM2VRAMBlitting(),
                    .src_pos = GPU_IO_Values::GP0::PostionTopLeft(src.position),
                    .dst_pos = GPU_IO_Values::GP0::PostionTopLeft(dst),
                    .size    = GPU_IO_Values::GP0::WidthHeight(src.size)
                };
            }
        };
    }
}