#include "sim_display.h"
#include "graphics.h"
#include <conio.h>


static uint32_t pixelColor, backgroundColor;
static int scaleFactor, w, h;
uint8_t border;

#define    GET_BIT(x, bit)    ((x & (1 << bit)) >> bit)

void SIM_Display_INIT(int width, int height, uint32_t pixcolor, uint32_t backcolor, int scale, uint8_t b)
{
    w = width * scale;
    h = height * scale;
    pixelColor = pixcolor;
    backgroundColor = backcolor;
    scaleFactor = scale;
    border = b;
}

void SIM_Display_START()
{
    initgraph(w, h);
    setbkcolor(backgroundColor);
    setfillcolor(pixelColor);
    cleardevice();
}

void SIM_Display_STOP()
{
    closegraph();
}

void drawPixel(int oledX, int oledY)
{
    int startX = oledX * scaleFactor;
    int startY = oledY * scaleFactor;
    if (border) fillrectangle(startX + 1, startY + 1, startX + scaleFactor - 1, startY + scaleFactor - 1);
    else solidrectangle(startX, startY, startX + scaleFactor, startY + scaleFactor);
}


void SIM_OneColor_DrawFromBuffer(uint8_t* buf, uint16_t width, uint16_t height)
{
    BeginBatchDraw();
    cleardevice();
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            uint8_t byteData = buf[y * width + x];
            for (int i = 0; i < 8; i++)
            {
                uint8_t bit = GET_BIT(byteData, i);
                if (bit)drawPixel(x, y * 8 + i);
            }
        }
    }
    EndBatchDraw();
}

void SIM_Color_DrawFromBuffer(uint32_t* buf, uint16_t width, uint16_t height)
{
    BeginBatchDraw();
    cleardevice();
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            setfillcolor(*buf);
            drawPixel(x, y);
            buf++;
        }
    }
    EndBatchDraw();
}

void SIM_Color_ImgFromBuffer(uint32_t* buf, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
    BeginBatchDraw();
    cleardevice();
    for (int y_i = 0; y_i < height; y_i++)
    {
        for (int x_i = 0; x_i < width; x_i++)
        {
            setfillcolor(*buf);
            drawPixel(x + x_i, y + y_i);
            buf++;
        }
    }
    EndBatchDraw();
}

void SIM_Color_FillFromBuffer(uint32_t* buf, uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye)
{
    BeginBatchDraw();
    cleardevice();
    for (int y_i = ys; y_i < ye; y_i++)
    {
        for (int x_i = xs; x_i < xe; x_i++)
        {
            setfillcolor(*buf);
            drawPixel(x_i, y_i);
            buf++;
        }
    }
    EndBatchDraw();
}