/*
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely.
*/

#include <SDL3/SDL.h>
#include <SDL3/SDL_test.h>
#include <SDL3/SDL_main.h>

#ifdef SDL_PLATFORM_EMSCRIPTEN
#include <emscripten/emscripten.h>
#endif

#define WINDOW_WIDTH  640
#define WINDOW_HEIGHT 480

#define TEXT_START_X 6.0f
#define TEXT_START_Y 6.0f
#define TEXT_LINE_ADVANCE FONT_CHARACTER_SIZE * 2

static SDL_Window *window;
static SDL_Renderer *renderer;
static const char *renderer_name;
static SDL_Colorspace colorspace = SDL_COLORSPACE_SRGB;
static const char *colorspace_name = "sRGB";
static int renderer_count = 0;
static int renderer_index = 0;
static int stage_index = 0;
static int done;
static float HDR_headroom = 1.0f;

enum
{
    StageClearBackground,
    StageDrawBackground,
    StageBlendDrawing,
    StageBlendTexture,
    StageGradientDrawing,
    StageGradientTexture,
    StageCount
};

static void FreeRenderer(void)
{
    SDLTest_CleanupTextDrawing();
    SDL_DestroyRenderer(renderer);
    renderer = NULL;
}

static void UpdateHDRState(void)
{
    SDL_PropertiesID props;
    SDL_bool HDR_enabled;

    props = SDL_GetDisplayProperties(SDL_GetDisplayForWindow(window));
    HDR_enabled = SDL_GetBooleanProperty(props, SDL_PROP_DISPLAY_HDR_ENABLED_BOOLEAN, SDL_FALSE);

    SDL_Log("HDR %s\n", HDR_enabled ? "enabled" : "disabled");

    if (HDR_enabled) {
        props = SDL_GetRendererProperties(renderer);
        if (SDL_GetNumberProperty(props, SDL_PROP_RENDERER_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB) != SDL_COLORSPACE_SRGB_LINEAR) {
            SDL_Log("Run with --colorspace linear to display HDR colors\n");
        }
        HDR_headroom = SDL_GetFloatProperty(props, SDL_PROP_RENDERER_HDR_HEADROOM_FLOAT, 1.0f);
    }
}

static void CreateRenderer(void)
{
    SDL_PropertiesID props;
    SDL_RendererInfo info;

    props = SDL_CreateProperties();
    SDL_SetProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window);
    SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, SDL_GetRenderDriver(renderer_index));
    SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, colorspace);
    renderer = SDL_CreateRendererWithProperties(props);
    SDL_DestroyProperties(props);
    if (!renderer) {
        SDL_Log("Couldn't create renderer: %s\n", SDL_GetError());
        return;
    }

    SDL_GetRendererInfo(renderer, &info);
    SDL_Log("Created renderer %s\n", info.name);
    renderer_name = info.name;

    UpdateHDRState();
}

static void NextRenderer( void )
{
    if (renderer_count <= 0) {
        return;
    }

    ++renderer_index;
    if (renderer_index == renderer_count) {
        renderer_index = 0;
    }
    FreeRenderer();
    CreateRenderer();
}

static void PrevRenderer(void)
{
    if (renderer_count <= 0) {
        return;
    }

    --renderer_index;
    if (renderer_index == -1) {
        renderer_index += renderer_count;
    }
    FreeRenderer();
    CreateRenderer();
}

static void NextStage(void)
{
    if (StageCount <= 0) {
        return;
    }

    ++stage_index;
    if (stage_index == StageCount) {
        stage_index = 0;
    }
}

static void PrevStage(void)
{
    --stage_index;
    if (stage_index == -1) {
        stage_index += StageCount;
    }
}

static SDL_bool ReadPixel(int x, int y, SDL_Color *c)
{
    SDL_Surface *surface;
    SDL_Rect r;
    SDL_bool result = SDL_FALSE;

    r.x = x;
    r.y = y;
    r.w = 1;
    r.h = 1;

    surface = SDL_RenderReadPixels(renderer, &r);
    if (surface) {
        if (SDL_ReadSurfacePixel(surface, 0, 0, &c->r, &c->g, &c->b, &c->a) == 0) {
            result = SDL_TRUE;
        } else {
            SDL_Log("Couldn't read pixel: %s\n", SDL_GetError());
        }
        SDL_DestroySurface(surface);
    } else {
        SDL_Log("Couldn't read back pixels: %s\n", SDL_GetError());
    }
    return result;
}

static void DrawText(float x, float y, const char *fmt, ...)
{
    char *text;

    va_list ap;
    va_start(ap, fmt);
    SDL_vasprintf(&text, fmt, ap);
    va_end(ap);

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDLTest_DrawString(renderer, x + 1.0f, y + 1.0f, text);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDLTest_DrawString(renderer, x, y, text);
    SDL_free(text);
}

static void RenderClearBackground(void)
{
    /* Draw a 50% gray background.
     * This will be darker when using sRGB colors and lighter using linear colors
     */
    SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
    SDL_RenderClear(renderer);

    /* Check the renderered pixels */
    SDL_Color c;
    if (!ReadPixel(0, 0, &c)) {
        return;
    }

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Clear 50%% Gray Background");
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b);
    y += TEXT_LINE_ADVANCE;
    if (c.r != 128) {
        DrawText(x, y, "Incorrect background color, unknown reason");
        y += TEXT_LINE_ADVANCE;
    }
}

static void RenderDrawBackground(void)
{
    /* Draw a 50% gray background.
     * This will be darker when using sRGB colors and lighter using linear colors
     */
    SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
    SDL_RenderFillRect(renderer, NULL);

    /* Check the renderered pixels */
    SDL_Color c;
    if (!ReadPixel(0, 0, &c)) {
        return;
    }

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Draw 50%% Gray Background");
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b);
    y += TEXT_LINE_ADVANCE;
    if (c.r != 128) {
        DrawText(x, y, "Incorrect background color, unknown reason");
        y += TEXT_LINE_ADVANCE;
    }
}

static void RenderBlendDrawing(void)
{
    SDL_Color a = { 238, 70, 166, 255 }; /* red square */
    SDL_Color b = { 147, 255, 0, 255 };  /* green square */
    SDL_FRect rect;

    /* Draw a green square blended over a red square
     * This will have different effects based on whether sRGB colorspaces and sRGB vs linear blending is used.
     */
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);
    rect.x = WINDOW_WIDTH / 3;
    rect.y = 0;
    rect.w = WINDOW_WIDTH / 3;
    rect.h = WINDOW_HEIGHT;
    SDL_SetRenderDrawColor(renderer, a.r, a.g, a.b, a.a);
    SDL_RenderFillRect(renderer, &rect);

    rect.x = 0;
    rect.y = WINDOW_HEIGHT / 3;
    rect.w = WINDOW_WIDTH;
    rect.h = WINDOW_HEIGHT / 6;
    SDL_SetRenderDrawColor(renderer, b.r, b.g, b.b, b.a);
    SDL_RenderFillRect(renderer, &rect);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(renderer, b.r, b.g, b.b, 128);
    rect.y += WINDOW_HEIGHT / 6;
    SDL_RenderFillRect(renderer, &rect);

    SDL_Color ar, br, cr;
    if (!ReadPixel(WINDOW_WIDTH / 2, 0, &ar) ||
        !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 3, &br) ||
        !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, &cr)) {
        return;
    }

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Draw Blending");
    y += TEXT_LINE_ADVANCE;
    if (cr.r == 199 && cr.g == 193 && cr.b == 121) {
        DrawText(x, y, "Correct blend color, blending in linear space");
    } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) ||
               (cr.r == 191 && cr.g == 162 && cr.b == 82)) {
        DrawText(x, y, "Correct blend color, blending in sRGB space");
    } else if (cr.r == 214 && cr.g == 156 && cr.b == 113) {
        DrawText(x, y, "Incorrect blend color, blending in PQ space");
    } else {
        DrawText(x, y, "Incorrect blend color, unknown reason");
    }
    y += TEXT_LINE_ADVANCE;
}

static void RenderBlendTexture(void)
{
    SDL_Color color_a = { 238, 70, 166, 255 }; /* red square */
    SDL_Color color_b = { 147, 255, 0, 255 };  /* green square */
    SDL_Texture *a;
    SDL_Texture *b;
    SDL_FRect rect;

    /* Draw a green square blended over a red square
     * This will have different effects based on whether sRGB colorspaces and sRGB vs linear blending is used.
     */
    a = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1);
    SDL_UpdateTexture(a, NULL, &color_a, sizeof(color_a));
    b = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1);
    SDL_UpdateTexture(b, NULL, &color_b, sizeof(color_b));

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);
    rect.x = WINDOW_WIDTH / 3;
    rect.y = 0;
    rect.w = WINDOW_WIDTH / 3;
    rect.h = WINDOW_HEIGHT;
    SDL_RenderTexture(renderer, a, NULL, &rect);

    rect.x = 0;
    rect.y = WINDOW_HEIGHT / 3;
    rect.w = WINDOW_WIDTH;
    rect.h = WINDOW_HEIGHT / 6;
    SDL_RenderTexture(renderer, b, NULL, &rect);
    rect.y += WINDOW_HEIGHT / 6;
    SDL_SetTextureBlendMode(b, SDL_BLENDMODE_BLEND);
    SDL_SetTextureAlphaModFloat(b, 128 / 255.0f);
    SDL_RenderTexture(renderer, b, NULL, &rect);

    SDL_Color ar, br, cr;
    if (!ReadPixel(WINDOW_WIDTH / 2, 0, &ar) ||
        !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 3, &br) ||
        !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, &cr)) {
        return;
    }

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Texture Blending");
    y += TEXT_LINE_ADVANCE;
    if (cr.r == 199 && cr.g == 193 && cr.b == 121) {
        DrawText(x, y, "Correct blend color, blending in linear space");
    } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) ||
               (cr.r == 191 && cr.g == 162 && cr.b == 82)) {
        DrawText(x, y, "Correct blend color, blending in sRGB space");
    } else {
        DrawText(x, y, "Incorrect blend color, unknown reason");
    }
    y += TEXT_LINE_ADVANCE;

    SDL_DestroyTexture(a);
    SDL_DestroyTexture(b);
}

static void DrawGradient(float x, float y, float width, float height, float start, float end)
{
    float xy[8];
    const int xy_stride = 2 * sizeof(float);
    SDL_FColor color[4];
    const int color_stride = sizeof(SDL_FColor);
    const int num_vertices = 4;
    const int indices[6] = { 0, 1, 2, 0, 2, 3 };
    const int num_indices = 6;
    const int size_indices = 4;
    float minx, miny, maxx, maxy;
    SDL_FColor min_color = { start, start, start, 1.0f };
    SDL_FColor max_color = { end, end, end, 1.0f };

    minx = x;
    miny = y;
    maxx = minx + width;
    maxy = miny + height;

    xy[0] = minx;
    xy[1] = miny;
    xy[2] = maxx;
    xy[3] = miny;
    xy[4] = maxx;
    xy[5] = maxy;
    xy[6] = minx;
    xy[7] = maxy;

    color[0] = min_color;
    color[1] = max_color;
    color[2] = max_color;
    color[3] = min_color;

    SDL_RenderGeometryRawFloat(renderer, NULL, xy, xy_stride, color, color_stride, NULL, 0, num_vertices, indices, num_indices, size_indices);
}

static void RenderGradientDrawing(void)
{
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Draw SDR and HDR gradients");
    y += TEXT_LINE_ADVANCE;

    y += TEXT_LINE_ADVANCE;

    DrawText(x, y, "SDR gradient");
    y += TEXT_LINE_ADVANCE;
    DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f);
    y += 64.0f;

    y += TEXT_LINE_ADVANCE;
    y += TEXT_LINE_ADVANCE;

    if (HDR_headroom > 1.0f) {
        DrawText(x, y, "HDR gradient");
    } else {
        DrawText(x, y, "No HDR headroom, HDR and SDR gradient are the same");
    }
    y += TEXT_LINE_ADVANCE;
    /* Drawing is in the sRGB colorspace, so we need to use the color scale, which is applied in linear space, to get into high dynamic range */
    SDL_SetRenderColorScale(renderer, HDR_headroom);
    DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f);
    SDL_SetRenderColorScale(renderer, 1.0f);
    y += 64.0f;
}

static SDL_Texture *CreateGradientTexture(int width, float start, float end)
{
    SDL_Texture *texture;
    float *pixels;

    /* Floating point textures are in the linear colorspace by default */
    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA128_FLOAT, SDL_TEXTUREACCESS_STATIC, width, 1);
    if (!texture) {
        return NULL;
    }

    pixels = (float *)SDL_malloc(width * sizeof(float) * 4);
    if (pixels) {
        int i;
        float length = (end - start);

        for (i = 0; i < width; ++i) {
            float v = (start + (length * i) / width);
            pixels[i * 4 + 0] = v;
            pixels[i * 4 + 1] = v;
            pixels[i * 4 + 2] = v;
            pixels[i * 4 + 3] = 1.0f;
        }
        SDL_UpdateTexture(texture, NULL, pixels, width * sizeof(float) * 4);
        SDL_free(pixels);
    }
    return texture;
}

static void DrawGradientTexture(float x, float y, float width, float height, float start, float end)
{
    SDL_FRect rect = { x, y, width, height };
    SDL_Texture *texture = CreateGradientTexture((int)width, start, end);
    SDL_RenderTexture(renderer, texture, NULL, &rect);
    SDL_DestroyTexture(texture);
}

static void RenderGradientTexture(void)
{
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);

    float x = TEXT_START_X;
    float y = TEXT_START_Y;
    DrawText(x, y, "%s %s", renderer_name, colorspace_name);
    y += TEXT_LINE_ADVANCE;
    DrawText(x, y, "Test: Texture SDR and HDR gradients");
    y += TEXT_LINE_ADVANCE;

    y += TEXT_LINE_ADVANCE;

    DrawText(x, y, "SDR gradient");
    y += TEXT_LINE_ADVANCE;
    DrawGradientTexture(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f);
    y += 64.0f;

    y += TEXT_LINE_ADVANCE;
    y += TEXT_LINE_ADVANCE;

    if (HDR_headroom > 1.0f) {
        DrawText(x, y, "HDR gradient");
    } else {
        DrawText(x, y, "No HDR headroom, HDR and SDR gradient are the same");
    }
    y += TEXT_LINE_ADVANCE;
    /* The gradient texture is in the linear colorspace, so we can use the HDR_headroom value directly */
    DrawGradientTexture(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, HDR_headroom);
    y += 64.0f;
}

static void loop(void)
{
    SDL_Event event;

    /* Check for events */
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_EVENT_KEY_DOWN) {
            switch (event.key.keysym.sym) {
            case SDLK_ESCAPE:
                done = 1;
                break;
            case SDLK_SPACE:
            case SDLK_RIGHT:
                NextStage();
                break;
            case SDLK_LEFT:
                PrevStage();
                break;
            case SDLK_DOWN:
                NextRenderer();
                break;
            case SDLK_UP:
                PrevRenderer();
                break;
            default:
                break;
            }
        } else if (event.type == SDL_EVENT_DISPLAY_HDR_STATE_CHANGED) {
            UpdateHDRState();
        } else if (event.type == SDL_EVENT_QUIT) {
            done = 1;
        }
    }

    if (renderer) {
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);

        switch (stage_index) {
        case StageClearBackground:
            RenderClearBackground();
            break;
        case StageDrawBackground:
            RenderDrawBackground();
            break;
        case StageBlendDrawing:
            RenderBlendDrawing();
            break;
        case StageBlendTexture:
            RenderBlendTexture();
            break;
        case StageGradientDrawing:
            RenderGradientDrawing();
            break;
        case StageGradientTexture:
            RenderGradientTexture();
            break;
        }

        SDL_RenderPresent(renderer);
    }
    SDL_Delay(100);

#ifdef SDL_PLATFORM_EMSCRIPTEN
    if (done) {
        emscripten_cancel_main_loop();
    }
#endif
}

static void LogUsage(const char *argv0)
{
    SDL_Log("Usage: %s [--renderer renderer] [--colorspace colorspace]\n", argv0);
}

int main(int argc, char *argv[])
{
    int return_code = 1;
    int i;

    for (i = 1; i < argc; ++i) {
        if (SDL_strcmp(argv[i], "--renderer") == 0) {
            if (argv[i + 1]) {
                renderer_name = argv[i + 1];
                ++i;
            } else {
                LogUsage(argv[0]);
                goto quit;
            }
        } else if (SDL_strcmp(argv[i], "--colorspace") == 0) {
            if (argv[i + 1]) {
                colorspace_name = argv[i + 1];
                if (SDL_strcasecmp(colorspace_name, "sRGB") == 0) {
                    colorspace = SDL_COLORSPACE_SRGB;
                } else if (SDL_strcasecmp(colorspace_name, "linear") == 0) {
                    colorspace = SDL_COLORSPACE_SRGB_LINEAR;
/* Not currently supported
                } else if (SDL_strcasecmp(colorspace_name, "HDR10") == 0) {
                    colorspace = SDL_COLORSPACE_HDR10;
*/
                } else {
                    SDL_Log("Unknown colorspace %s\n", argv[i + 1]);
                    goto quit;
                }
                ++i;
            } else {
                LogUsage(argv[0]);
                goto quit;
            }
        } else {
            LogUsage(argv[0]);
            goto quit;
        }
    }

    window = SDL_CreateWindow("SDL colorspace test", WINDOW_WIDTH, WINDOW_HEIGHT, 0);
    if (!window) {
        SDL_Log("Couldn't create window: %s\n", SDL_GetError());
        return_code = 2;
        goto quit;
    }

    renderer_count = SDL_GetNumRenderDrivers();
    SDL_Log("There are %d render drivers:\n", renderer_count);
    for (i = 0; i < renderer_count; ++i) {
        const char *name = SDL_GetRenderDriver(i);

        if (renderer_name && SDL_strcasecmp(renderer_name, name) == 0) {
            renderer_index = i;
        }
        SDL_Log("    %s\n", name);
    }
    CreateRenderer();

    /* Main render loop */
    done = 0;

#ifdef SDL_PLATFORM_EMSCRIPTEN
    emscripten_set_main_loop(loop, 0, 1);
#else
    while (!done) {
        loop();
    }
#endif
    return_code = 0;
quit:
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return return_code;
}
