#include "Renderer.h"
#include "Profiling.h"

#ifdef __APPLE__
#include "../m/MetalGfxInterface.h"
#else
#include "OpenGLGFXInterface.h"
#endif

#include <assert.h>

Renderer* Renderer::ptr = nullptr;

#define DUMMY_TEXTURE 0

void Renderer::create(void* gfx)
{
    ZoneScoped;
    Renderer::ptr = new Renderer(gfx);
}

void Renderer::destroy()
{
    ZoneScoped;
    delete Renderer::ptr;
    Renderer::ptr = nullptr;
}

Renderer::Renderer(void* gfx)
    : m_gfx(gfx)
{
    ZoneScoped;
}

Renderer::~Renderer()
{
    ZoneScoped;
}

void Renderer::addRect(float x, float y, float w, float h)
{
    ZoneScoped;
    addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, DUMMY_TEXTURE, 0.f, 0.f, 1.f, 1.f);
}

void Renderer::addRect(float x, float y, float w, float h, KDEStringHandle texture)
{
    ZoneScoped;
    addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, 0.f, 0.f, 1.f, 1.f);
}

void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a)
{
    ZoneScoped;
    addRect(x, y, w, h, r, g, b, a, DUMMY_TEXTURE, 0.f, 0.f, 1.f, 1.f);
}

void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a, KDEStringHandle texture)
{
    ZoneScoped;
    addRect(x, y, w, h, r, g, b, a, texture, 0.f, 0.f, 1.f, 1.f);
}

void Renderer::addRect(float x,
                       float y,
                       float w,
                       float h,
                       KDEStringHandle texture,
                       float src_x,
                       float src_y,
                       float src_w,
                       float src_h)
{
    ZoneScoped;
    addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, src_x, src_y, src_w, src_h);
}

void Renderer::addRect(float x,
                       float y,
                       float w,
                       float h,
                       float r,
                       float g,
                       float b,
                       float a,
                       KDEStringHandle texture,
                       float src_x,
                       float src_y,
                       float src_w,
                       float src_h)
{
    ZoneScoped;

    KDERect rect = {};
    rect.dst_p0_x = x;
    rect.dst_p0_y = y;
    rect.dst_p1_x = x + w;
    rect.dst_p1_y = y + h;
    rect.src_p0_x = src_x;
    rect.src_p0_y = src_y;
    rect.src_p1_x = src_x + src_w;
    rect.src_p1_y = src_y + src_h;
    rect.r = r;
    rect.g = g;
    rect.b = b;
    rect.a = a;
    rect.expand_r = 0;
    
#ifdef __APPLE__
    metalGfxPushRect(m_gfx, rect, texture);
#else
    openGLGfxPushRect((OpenGLGfx*)m_gfx, rect, texture);
#endif
}

void Renderer::addFontRect(float x,
                           float y,
                           float w,
                           float h,
                           float char_height,
                           KDEStringHandle font,
                           KDEStringHandle id,
                           float src_x0,
                           float src_y0,
                           float src_x1,
                           float src_y1)
{
    ZoneScoped;
    addFontRect(x, y, w, h, 0.f, 0.f, 0.f, 1.f, char_height, font, id, src_x0, src_y0, src_x1, src_y1);
}

void Renderer::addFontRect(float x,
                           float y,
                           float w,
                           float h,
                           float r,
                           float g,
                           float b,
                           float a,
                           float char_height,
                           KDEStringHandle font,
                           KDEStringHandle id,
                           float src_x0,
                           float src_y0,
                           float src_x1,
                           float src_y1)
{
    ZoneScoped;
    KDERect rect = {};
    rect.dst_p0_x = x;
    rect.dst_p0_y = y;
    rect.dst_p1_x = x + w;
    rect.dst_p1_y = y + h;
    rect.src_p0_x = src_x0;
    rect.src_p0_y = src_y0;
    rect.src_p1_x = src_x1;
    rect.src_p1_y = src_y1;
    rect.r = r;
    rect.g = g;
    rect.b = b;
    rect.a = a;
    rect.expand_r = 1;
    
    
#ifdef __APPLE__
    metalGfxPushFontRect(m_gfx, rect, char_height, font, id);
#else
    openGLGfxPushFontRect((OpenGLGfx*)m_gfx, rect, char_height, font, id);
#endif
}

void Renderer::renderFrame(float width, float height)
{
#if defined(_WIN32) || defined(__ANDROID__)
    openGLGfxRenderFrame((OpenGLGfx*)m_gfx, width, height);
#endif
}

void Renderer::getTextureSize(KDEStringHandle texture, unsigned int* w, unsigned int* h)
{
#ifdef __APPLE__
    
#else
    openGLGfxGetTextureSize((OpenGLGfx*)m_gfx, texture, w, h);
#endif
}
