// This is a Zig version of a raylib example from
// https://github.com/raysan5/raylib/
// It is distributed under the same license as the original - unmodified zlib/libpng license
// Header from the original source code follows below:

///*******************************************************************************************
//*
//*   raylib [shapes] example - draw rectangle rounded (with gui options)
//*
//*   Example originally created with raylib 2.5, last time updated with raylib 2.5
//*
//*   Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
//*
//*   Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
//*   BSD-like license that allows static linking with closed source software
//*
//*   Copyright (c) 2018-2023 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
//*
//********************************************************************************************/

// Download raygui.h from https://github.com/raysan5/raygui/tree/master/src and copy it to this project's folder.
// Build with `zig build-exe main.zig -idirafter ./ -lc -lraylib`

// WARNING: unless this bug in Zig transtale - https://github.com/ziglang/zig/issues/15408 - has been fixed,
// you're going to see errors similar to this:

// /home/archie/.cache/zig/o/c95bc39f271b884ec25d6b2251a68075/cimport.zig:7631:27: error: incompatible types: 'c_int' and 'f32'
//                     value += (GetMouseDelta().y / (scrollbar.height - slider.height)) * @floatFromInt(valueRange);
//                     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /home/archie/.cache/zig/o/c95bc39f271b884ec25d6b2251a68075/cimport.zig:7631:21: note: type 'c_int' here
//                     value += (GetMouseDelta().y / (scrollbar.height - slider.height)) * @floatFromInt(valueRange);
//                     ^~~~~
// /home/archie/.cache/zig/o/c95bc39f271b884ec25d6b2251a68075/cimport.zig:7631:87: note: type 'f32' here
//                     value += (GetMouseDelta().y / (scrollbar.height - slider.height)) * @floatFromInt(valueRange);
//                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Zig incorrectly skips type coercion when translating certain C code in raygui.h.
// As a workaround, edit raygui.h you have downloaded to this example's folder:
// Find the body of the function that causes Zig translate-c to stumble (currently it's `static int GuiScrollBar`, on line 4442),
// then within it, find the lines that are causing the issue (currently lines 4516, 4517):
//
// if (isVertical) value += (GetMouseDelta().y/(scrollbar.height - slider.height)*valueRange);
// else value += (GetMouseDelta().x/(scrollbar.width - slider.width)*valueRange);

// below them, two more lines (currently lines 4553, 4554):
//
// if (isVertical) value += (GetMouseDelta().y/(scrollbar.height - slider.height)*valueRange);
// else value += (GetMouseDelta().x/(scrollbar.width - slider.width)*valueRange);

// Add explicit type cast `(int)` to the value added to `value` variable in each of the 4 lines like this:
//
// if (isVertical) value += (int)(GetMouseDelta().y/(scrollbar.height - slider.height)*valueRange);
// else value += (int)(GetMouseDelta().x/(scrollbar.width - slider.width)*valueRange);

// This should fix the issue.

// Alternatively, edit the lines in cimport.zig mentioned in the error message, manually adding necessary type coercion:
// value += @intFromFloat((GetMouseDelta().y / (scrollbar.height - slider.height)) * @floatFromInt(valueRange));
//
// Also correct the lines below it:
// value += (GetMouseDelta().x / (scrollbar.width - slider.width)) * @floatFromInt(valueRange);
// Add similar type coercion:
// value += @intFromFloat((GetMouseDelta().x / (scrollbar.width - slider.width)) * @floatFromInt(valueRange));
//
// Apply the same modification to each line where it is needed.
//
// Save cimport.zig and build the project again, it should compile without errors.

// You may need to do this again, if cimport.zig is regenerated by Zig :(

const c = @cImport(
{
    @cInclude("raylib.h");
    //@cDefine("RAYGUI_IMPLEMENTATION", {}); - Moved to raygui_impl.c
    //                                         Here we only need raygui declarations, not actual function bodies.
    @cInclude("raygui.h"); // Required for GUI controls
});

pub fn main() void
{
    const screen_width = 800;
    const screen_height = 450;

    c.InitWindow(screen_width, screen_height, "raylib [shapes] example - draw rectangle rounded");
    defer c.CloseWindow(); // Close window and OpenGL context

    var roundness: f32 = 0.2;
    var width: f32 = 200.0;
    var height: f32 = 100.0;
    var segments: f32 = 0.0;
    var line_thick: f32 = 1.0;

    var draw_rect = false;
    var draw_rounded_rect = true;
    var draw_rounded_lines = false;

    c.SetTargetFPS(60);

    while (!c.WindowShouldClose()) // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        const rec = c.Rectangle{ .x = @as(f32, @floatFromInt(c.GetScreenWidth() - @as(c_int, @intFromFloat(width)) - 250)) / 2.0,
                                 .y = @as(f32, @floatFromInt(c.GetScreenHeight() - @as(c_int, @intFromFloat(height)))) / 2.0,
                                 .width = width,
                                 .height = height };
        //----------------------------------------------------------------------------------

        // Draw
        //---------------------------------------------------------------------------------
        c.BeginDrawing();
        defer c.EndDrawing();

        c.ClearBackground(c.RAYWHITE);

        c.DrawLine(560, 0, 560, c.GetScreenHeight(), c.Fade(c.LIGHTGRAY, 0.6));
        c.DrawRectangle(560, 0, c.GetScreenWidth() - 500, c.GetScreenHeight(), c.Fade(c.LIGHTGRAY, 0.3));

        if (draw_rect) c.DrawRectangleRec(rec, c.Fade(c.GOLD, 0.6));
        if (draw_rounded_rect) c.DrawRectangleRounded(rec, roundness, @intFromFloat(segments), c.Fade(c.MAROON, 0.2));
        if (draw_rounded_lines) c.DrawRectangleRoundedLines(rec, roundness, @intFromFloat(segments), line_thick, c.Fade(c.MAROON, 0.4));

        // Draw GUI controls
        //------------------------------------------------------------------------------
        _ = c.GuiSliderBar(.{ .x = 640.0, .y = 40.0, .width = 105.0, .height = 20.0 }, "Width", null,
                           &width, 0.0, @as(f32, @floatFromInt(c.GetScreenWidth())) - 300.0);
        _ = c.GuiSliderBar(.{ .x = 640.0, .y = 70.0, .width = 105.0, .height = 20.0 }, "Height", null,
                           &height, 0.0, @as(f32, @floatFromInt(c.GetScreenHeight())) - 50.0);
        _ = c.GuiSliderBar(.{ .x = 640.0, .y = 140.0, .width = 105.0, .height = 20.0 }, "Roundness", null,
                           &roundness, 0.0, 1.0);
        _ = c.GuiSliderBar(.{ .x = 640.0, .y = 170.0, .width = 105.0, .height = 20.0 }, "Thickness", null,
                           &line_thick, 0.0, 20.0);
        _ = c.GuiSliderBar(.{ .x = 640.0, .y = 240.0, .width = 105.0, .height = 20.0 }, "Segments", null,
                           &segments, 0.0, 60.0);

        _ = c.GuiCheckBox(.{ .x = 640.0, .y = 320.0, .width = 20.0, .height = 20.0 }, "DrawRoundedRect",
                          &draw_rounded_rect);
        _ = c.GuiCheckBox(.{ .x = 640.0, .y = 350.0, .width = 20.0, .height = 20.0 }, "DrawRoundedLines",
                          &draw_rounded_lines);
        _ = c.GuiCheckBox(.{ .x = 640.0, .y = 380.0, .width = 20.0, .height = 20.0 }, "DrawRect",
                          &draw_rect);
        //------------------------------------------------------------------------------

        // @ptrCast -> [*c]const u8: https://github.com/ziglang/zig/issues/16234
        // -- This code causes Zig compiler (0.11.0-dev.3859+88284c124) to segfault, see
        // -- https://github.com/ziglang/zig/issues/16197
        //c.DrawText(c.TextFormat("MODE: %s", @ptrCast(if (segments >= 4) "MANUAL" else "AUTO")), 640, 280, 10,
        //           if (segments >= 4) c.MAROON else c.DARKGRAY);
        // -- This does not
        const text = if (segments >= 4) "MODE: MANUAL" else "MODE: AUTO";
        c.DrawText(text, 640, 280, 10, if (segments >= 4) c.MAROON else c.DARKGRAY);

        c.DrawFPS(10, 10);
        //---------------------------------------------------------------------------------
    }
}
