// 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 circle sector (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 circle sector");
    defer c.CloseWindow(); // Close window and OpenGL context

    const center = c.Vector2{ .x = @as(f32, @floatFromInt(c.GetScreenWidth() - 300)) / 2.0, .y = @as(f32, @floatFromInt(c.GetScreenHeight())) / 2.0 };

    var outer_radius: f32 = 180.0;
    var start_angle: f32 = 0.0;
    var end_angle: f32 = 180.0;
    var segments: f32 = 0.0;
    var min_segments: i32 = 4;

    c.SetTargetFPS(60);

    while (!c.WindowShouldClose()) // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        // NOTE: All variables update happens inside GUI control functions
        //----------------------------------------------------------------------------------

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

        c.ClearBackground(c.RAYWHITE);

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

        c.DrawCircleSector(center, outer_radius, start_angle, end_angle, @intFromFloat(segments), c.Fade(c.MAROON, 0.3));
        c.DrawCircleSectorLines(center, outer_radius, start_angle, end_angle, @intFromFloat(segments), c.Fade(c.MAROON, 0.6));

        // Draw GUI controls
        //------------------------------------------------------------------------------
        _ = c.GuiSliderBar(.{ .x = 600.0, .y = 40.0, .width = 120.0, .height = 20.0 },
                           "StartAngle", null, &start_angle, 0.0, 720.0);
        _ = c.GuiSliderBar(.{ .x = 600.0, .y = 70.0, .width = 120.0, .height = 20.0 },
                           "EndAngle", null, &end_angle, 0.0, 720.0);

        _ = c.GuiSliderBar(.{ .x = 600.0, .y = 140.0, .width = 120.0, .height = 20.0 },
                           "Radius", null, &outer_radius, 0.0, 200.0);
        _ = c.GuiSliderBar(.{ .x = 600.0, .y = 170.0, .width = 120.0, .height = 20.0 },
                           "Segments", null, &segments, 0.0, 100.0);
        //------------------------------------------------------------------------------

        min_segments = @intFromFloat(@ceil((end_angle - start_angle) / 90.0));
        // @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",
        //                        if (@as(i32, @intFromFloat(segments)) >= min_segments) "MANUAL" else "AUTO"),
        //           600, 200, 10, if (@as(i32, @intFromFloat(segments)) >= min_segments) c.MAROON else c.DARKGRAY);
        // -- This does not
        const text = if (@as(i32, @intFromFloat(segments)) >= min_segments) "MODE: MANUAL" else "MODE: AUTO";
        c.DrawText(text, 600, 200, 10, if (@as(i32, @intFromFloat(segments)) >= min_segments) c.MAROON else c.DARKGRAY);
        c.DrawFPS(10, 10);
        //---------------------------------------------------------------------------------
    }
}
