#include "vertexShader.hpp"
#include <cstdlib>
#include <netlog.h>

namespace render::kernel
{

VertexShader::VertexShader(const char *path, ShaderPatcher *patcher)
{
    this->patcher = patcher;

    FILE *file = fopen(path, "rb");
    fseek(file, 0, SEEK_END);
    int size = ftell(file);
    fseek(file, 0, SEEK_SET);
    SceGxmProgram *buf = (SceGxmProgram *)malloc(size);
    fread(buf, 1, size, file);
    fclose(file);

    int error = sceGxmShaderPatcherRegisterProgram(this->patcher->GetPatcher(), buf, &this->id);
    // netlog("vertex register %d", error);
    // free(buf);

    this->program = sceGxmShaderPatcherGetProgramFromId(this->id);
}

VertexShader::~VertexShader()
{
}

const SceGxmProgramParameter *VertexShader::GetParam(const char *name)
{
    return sceGxmProgramFindParameterByName(this->program, name);
}

unsigned int VertexShader::GetParamIndex(const char *name)
{
    const SceGxmProgramParameter *param = this->GetParam(name);
    return sceGxmProgramParameterGetResourceIndex(param);
}

void VertexShader::Assembly()
{
    int error = sceGxmShaderPatcherCreateVertexProgram(
        this->patcher->GetPatcher(), this->id,
        this->attribs.data(), this->attribs.size(),
        &this->stream, 1,
        &this->vProgram);

    // netlog("vertex assembly %d", error);
}

void VertexShader::Bind(SceGxmContext *context)
{
    sceGxmSetVertexProgram(context, this->vProgram);
}

void VertexShader::SetDefaultUniform(SceGxmContext *context, const SceGxmProgramParameter *param, unsigned int count, const float *data)
{
    void *buffer;
    sceGxmReserveVertexDefaultUniformBuffer(context, &buffer);
    sceGxmSetUniformDataF(buffer, param, 0, count, data);
}

} // namespace render::kernel