#include "background.hpp"
#include <cmath>
#include <memory.h>

#include <psp2/gxm.h>

#include "kernel/fragmentShader.hpp"
#include "kernel/vertexShader.hpp"
#include "render.h"

#include "../netlog.h"
#include <vectors/vec2.h>

namespace render::background
{

struct BackgroundState {
    kernel::VertexShader *vshader;
    kernel::FragmentShader *fshader;

    kernel::GpuBuffer *vertexBuffer, *indexBuffer;
} state;

void Init()
{
    kernel::ShaderPatcher *patcher = render::GetShaderPatcher();

    state.vshader = new kernel::VertexShader("app0:/data/shaders/black_v.gxp", patcher);
    state.fshader = new kernel::FragmentShader("app0:/data/shaders/black_f.gxp", patcher);

    SceGxmVertexAttribute attrib;
    attrib.streamIndex = 0;
    attrib.offset = 0;
    attrib.format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
    attrib.componentCount = 2;
    attrib.regIndex = state.vshader->GetParamIndex("position");
    state.vshader->attribs.push_back(attrib);

    state.vshader->stream.stride = sizeof(vec2f);
    state.vshader->stream.indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;

    state.vshader->Assembly();

    state.vertexBuffer = new kernel::GpuBuffer(SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ, 4 * sizeof(vec2f));
    state.indexBuffer = new kernel::GpuBuffer(SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ, 6 * sizeof(uint16_t));

    vec2f *data = (vec2f *)state.vertexBuffer->data;
    uint16_t *index = (uint16_t *)state.indexBuffer->data;

    data[0] = vec2f{-1, -1};
    data[1] = vec2f{1, -1};
    data[2] = vec2f{-1, 1};
    data[3] = vec2f{1, 1};

    index[0] = 0;
    index[1] = 1;
    index[2] = 2;
    index[3] = 2;
    index[4] = 1;
    index[5] = 3;
}

void Free()
{
}

void Render()
{
    SceGxmContext *ctx = render::GetContext();

    state.vshader->Bind(ctx);
    state.fshader->Bind(ctx);

    int error = sceGxmSetVertexStream(ctx, 0, state.vertexBuffer->data);
    error = sceGxmDraw(ctx, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, state.indexBuffer->data, 6);
}

} // namespace render::background