(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
                         -****************+.
               .-=++*+::*###############*-
           :=+##*+=-::*##**############=
        .=*#*=:    .+#*=+############+.
       =##+.      +#+-=############*-:
     :*#+.      =+-.=#############- =#*.
    -##-      -=..+#############*:.  ---.
   -##:     .: .+################= :+#*-:.
  .##-        :==========*#####= :*#*- -#*
  =##                   -####*:-*#*-   .##:
  +#+                  -###*--*#*-      *#=
  *#+                 +###==*#*:        *#=
  +#*                *##+=*#*-          ##-
  :##.             .*##*##*:           -##.
   +#*            -#####*:             *#=
    *#+          =####+:             .*#+
     +#*.       +###+.              :##=
      -##+.    *##+:              :+#*:
        =*#+..*#+:             .-*#*-
          :-:#+::.        .:-=*##+:
           -+..+*###****####*+-.
          :.      ..:::::..
        ____                   _
       / ___| _ __   __ _ _ __| | __
       \___ \| '_ \ / _` | '__| |/ /
        ___) | |_) | (_| | |  |   <
       |____/| .__/ \__,_|_|  |_|\_\
             |_|   Game Toolkit™

Copyright © 2024-present tinyBigGAMES™ LLC
         All Rights Reserved.

Website: https://tinybiggames.com
Email  : support@tinybiggames.com

See LICENSE for license information
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)

unit UIMGUI01;

interface

uses
  System.SysUtils,
  SGT.Deps,
  SGT.Deps.Ext,
  SGT.OGL,
  SGT.Core,
  SGT.Lua,
  SGT.LuaDebugger,
  UCommon;

procedure Demo();

implementation

// The 'ContentScaledEvent' procedure handles the event triggered when the window content is scaled.
// It resizes the default font based on the new scale values.
procedure ContentScaledEvent(const ASender: Pointer; const AScaleX, AScaleY: Single; const AUserData: Pointer);
var
  LFontAtlas: PImFontAtlas; // Pointer to the ImFontAtlas object used by ImGui.
begin
  LFontAtlas := AUserData; // Cast the user data pointer to an ImFontAtlas pointer.
  ImFontAtlas_ResizeDefaultFont(LFontAtlas, 16 * AScaleX); // Resize the default font based on the new scale factor.
end;

// The 'Demo' procedure demonstrates the use of ImGui within a window, handling font resizing, and rendering UI components.
procedure Demo();
var
  LWindow: TWindow;            // Represents the window where the ImGui content and text will be rendered.
  LFont: TFont;                // Represents the font used for displaying non-ImGui text.
  LPos: TPoint;                // Represents the position on the window for text rendering.
  io: PImGuiIO;                // Pointer to the ImGui IO structure used for configuration and input handling.
  show_demo_window: Boolean;   // Boolean flag to control the visibility of the ImGui demo window.
  clear_color: ImVec4;         // Color used to clear the window background.
  color: TColor;               // TColor structure used for window background color.
  LScale: SGT.Core.TPoint;     // Represents the scaling factor of the window content.

  // The 'ResizeFont' procedure adjusts the default font size based on the current window scale.
  procedure ResizeFont();
  begin
    LWindow.GetScale(LScale); // Get the current scale of the window.
    ImFontAtlas_ResizeDefaultFont(io.Fonts, 16 * LScale.x); // Resize the default font based on the window scale.
  end;

begin
  show_demo_window := True; // Initially set the demo window to be visible.
  clear_color.x := 0.45;    // Set the initial background color (red component).
  clear_color.y := 0.55;    // Set the initial background color (green component).
  clear_color.z := 0.60;    // Set the initial background color (blue component).
  clear_color.w := 1.0;     // Set the initial background color (alpha component).

  // Initialize the window with the title 'SGT: IMGUI #01'.
  LWindow := TWindow.Init('SGT: IMGUI #01');

  // Create an ImGui context and configure the IO settings.
  igCreateContext(nil);
  io := igGetIO();
  io.ConfigFlags := ImGuiConfigFlags_NavEnableKeyboard or
                    ImGuiConfigFlags_NavEnableGamepad or
                    ImGuiConfigFlags_DockingEnable;

  // Set the event handler for content scaling, which resizes the font when the scale changes.
  LWindow.SetContentScaledEvent(nil, ContentScaledEvent, io.Fonts);

  // Initialize ImGui with GLFW for window management and OpenGL2 for rendering.
  ImGui_ImplGlfw_InitForOpenGL(LWindow.GetHandle(), true);
  ImGui_ImplOpenGL2_Init();

  // Resize the default font based on the current scale.
  ResizeFont();

  // Load the default font for non-ImGui text rendering.
  LFont := TFont.LoadDefault(LWindow, 10);

  // Main loop to keep the window running until the user closes it.
  while not LWindow.ShouldClose() do
  begin
    // Start processing a new frame.
    LWindow.StartFrame();

      // Start a new ImGui frame for rendering ImGui content.
      ImGui_ImplOpenGL2_NewFrame();
      ImGui_ImplGlfw_NewFrame();
      igNewFrame();

      // Render the ImGui demo window if the flag is set.
      if show_demo_window then
        igShowDemoWindow(@show_demo_window);

      // Render a simple ImGui window with text and a checkbox.
      if igBegin('Hello, world!', nil, ImGuiWindowFlags_AlwaysAutoResize) then
      begin
        igText('This is some useful text.');
        igCheckbox('Demo Window', @show_demo_window);
        igEnd();
      end;

      // Check if the ESC key was pressed. If so, set the window to close.
      if Lwindow.GetKey(KEY_ESCAPE, isWasPressed) then
        LWindow.SetShouldClose(True);

      // Start drawing on the window.
      LWindow.StartDrawing();

        // Convert ImGui clear color to TColor and clear the window background.
        Color.Red := clear_color.x;
        Color.Green := clear_color.y;
        Color.Blue := clear_color.z;
        Color.Alpha := clear_color.w;
        LWindow.Clear(Color);

        // Render the ImGui content to the window.
        igRender();
        ImGui_ImplOpenGL2_RenderDrawData(igGetDrawData());

        // Set the initial position for text rendering.
        LPos := Math.Point(3, 20);

        // Draw the current frame rate and quit instruction using the default font.
        LFont.DrawText(LWindow, LPos.X, LPos.Y, 0, WHITE, haLeft, 'fps %d', [FrameLimitTimer.FrameRate()]);
        LFont.DrawText(LWindow, LPos.X, LPos.Y, 0, GREEN, haLeft, Utils.HudTextItem('Quit', 'ESC'), [FrameLimitTimer.FrameRate()]);

      // Finish drawing on the window.
      LWindow.EndDrawing();

    // End processing the frame.
    LWindow.EndFrame();
  end;

  // Shut down ImGui and free the resources.
  ImGui_ImplOpenGL2_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  igDestroyContext(nil);

  // Free the font resources after the loop ends.
  LFont.Free();

  // Free the window resources after the loop ends.
  LWindow.Free();
end;


end.
