//-----------------------------------------------------------------------------
// ZIG Notes:
//   Add cimgui_memory_editor.h to your cInclude list.
//   Add cimgui_memory_editor.cpp to your build/tasks compile list.
//
// ZIG Example:
// var mem_edit = im.MemoryEditor {
//   // Settings
//   .Open = true,
//   .ReadOnly = false,
//   .Cols = 16,
//   .OptShowOptions = true,
//   .OptShowDataPreview = false,
//   .OptShowHexII = false,
//   .OptShowAscii = true,
//   .OptGreyOutZeroes = true,
//   .OptUpperCaseHex = true,
//   .OptMidColsCount = 8,
//   .OptAddrDigitsCount = 0,
//   .OptFooterExtraHeight = 0.0,
//   .HighlightColor = im.IM_COL32(255, 255, 255, 50),
//   .ReadFn = null,
//   .WriteFn = null,
//   .HighlightFn = null,
// };
// var mem_data: [1000]c_char = std.mem.zeroes([1000]c_char);
// ...while (!done) ...
//   ...
//   im.ImGui_NewFrame();
//
//   im.MemoryEditor_DrawWindow(&mem_edit, "Memory Editor", &mem_data, mem_data.len);
// ...
//-----------------------------------------------------------------------------



// THIS FILE HAS BEEN AUTO-GENERATED BY THE 'DEAR BINDINGS' GENERATOR.
// **DO NOT EDIT DIRECTLY**
// https://github.com/dearimgui/dear_bindings

// THIS FILE HAS BEEN AUTO-GENERATED BY THE 'DEAR BINDINGS' GENERATOR.
// **DO NOT EDIT DIRECTLY**
// https://github.com/dearimgui/dear_bindings

// Mini memory editor for Dear ImGui (to embed in your game/tools)
// Get latest version at http://www.github.com/ocornut/imgui_club
//
// Right-click anywhere to access the Options menu!
// You can adjust the keyboard repeat delay/rate in ImGuiIO.
// The code assume a mono-space font for simplicity!
// If you don't use the default font, use ImGui::PushFont()/PopFont() to switch to a mono-space font before calling this.
//
// Usage:
//   // Create a window and draw memory editor inside it:
//   static MemoryEditor mem_edit_1;
//   static char data[0x10000];
//   size_t data_size = 0x10000;
//   mem_edit_1.DrawWindow("Memory Editor", data, data_size);
//
// Usage:
//   // If you already have a window, use DrawContents() instead:
//   static MemoryEditor mem_edit_2;
//   ImGui::Begin("MyWindow")
//   mem_edit_2.DrawContents(this, sizeof(*this), (size_t)this);
//   ImGui::End();
//
// Changelog:
// - v0.10: initial version
// - v0.23 (2017/08/17): added to github. fixed right-arrow triggering a byte write.
// - v0.24 (2018/06/02): changed DragInt("Rows" to use a %d data format (which is desirable since imgui 1.61).
// - v0.25 (2018/07/11): fixed wording: all occurrences of "Rows" renamed to "Columns".
// - v0.26 (2018/08/02): fixed clicking on hex region
// - v0.30 (2018/08/02): added data preview for common data types
// - v0.31 (2018/10/10): added OptUpperCaseHex option to select lower/upper casing display [@samhocevar]
// - v0.32 (2018/10/10): changed signatures to use void* instead of unsigned char*
// - v0.33 (2018/10/10): added OptShowOptions option to hide all the interactive option setting.
// - v0.34 (2019/05/07): binary preview now applies endianness setting [@nicolasnoble]
// - v0.35 (2020/01/29): using ImGuiDataType available since Dear ImGui 1.69.
// - v0.36 (2020/05/05): minor tweaks, minor refactor.
// - v0.40 (2020/10/04): fix misuse of ImGuiListClipper API, broke with Dear ImGui 1.79. made cursor position appears on left-side of edit box. option popup appears on mouse release. fix MSVC warnings where _CRT_SECURE_NO_WARNINGS wasn't working in recent versions.
// - v0.41 (2020/10/05): fix when using with keyboard/gamepad navigation enabled.
// - v0.42 (2020/10/14): fix for . character in ASCII view always being greyed out.
// - v0.43 (2021/03/12): added OptFooterExtraHeight to allow for custom drawing at the bottom of the editor [@leiradel]
// - v0.44 (2021/03/12): use ImGuiInputTextFlags_AlwaysOverwrite in 1.82 + fix hardcoded width.
// - v0.50 (2021/11/12): various fixes for recent dear imgui versions (fixed misuse of clipper, relying on SetKeyboardFocusHere() handling scrolling from 1.85). added default size.
//
// Todo/Bugs:
// - This is generally old/crappy code, it should work but isn't very good.. to be rewritten some day.
// - PageUp/PageDown are supported because we use _NoNav. This is a good test scenario for working out idioms of how to mix natural nav and our own...
// - Arrows are being sent to the InputText() about to disappear which for LeftArrow makes the text cursor appear at position 1 for one frame.
// - Using InputText() is awkward and maybe overkill here, consider implementing something custom.

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdint.h>
#ifdef _MSC_VER
#define _PRISizeT   "I"
#define ImSnprintf  _snprintf
#else
#define _PRISizeT   "z"
#define ImSnprintf  snprintf
#endif // #ifdef _MSC_VER
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4996)  // warning C4996: 'sprintf': This function or variable may be unsafe.
#endif // #ifdef _MSC_VER

#ifndef CIMGUI_API
#define CIMGUI_API
#endif // #ifndef CIMGUI_API
#ifndef CIMGUI_IMPL_API
#define CIMGUI_IMPL_API              CIMGUI_API
#endif // #ifndef CIMGUI_IMPL_API

typedef unsigned int        ImU32;
typedef struct MemoryEditor_Sizes_t
{
    int   AddrDigitsCount;
    float LineHeight;
    float GlyphWidth;
    float HexCellWidth;
    float SpacingBetweenMidCols;
    float PosHexStart;
    float PosHexEnd;
    float PosAsciiStart;
    float PosAsciiEnd;
    float WindowWidth;
} MemoryEditor_Sizes;

typedef enum
{
  DataFormat_Bin   = 0,
  DataFormat_Dec   = 1,
  DataFormat_Hex   = 2,
  DataFormat_COUNT,
} DataFormat;

typedef struct MemoryEditor_t
{
    // Settings
    bool          Open;                                 // = true   // set to false when DrawWindow() was closed. ignore if not using DrawWindow().
    bool          ReadOnly;                             // = false  // disable any editing.
    int           Cols;                                 // = 16     // number of columns to display.
    bool          OptShowOptions;                       // = true   // display options button/context menu. when disabled, options will be locked unless you provide your own UI for them.
    bool          OptShowDataPreview;                   // = false  // display a footer previewing the decimal/binary/hex/float representation of the currently selected bytes.
    bool          OptShowHexII;                         // = false  // display values in HexII representation instead of regular hexadecimal: hide null/zero bytes, ascii values as ".X".
    bool          OptShowAscii;                         // = true   // display ASCII representation on the right side.
    bool          OptGreyOutZeroes;                     // = true   // display null/zero bytes using the TextDisabled color.
    bool          OptUpperCaseHex;                      // = true   // display hexadecimal values as "FF" instead of "ff".
    int           OptMidColsCount;                      // = 8      // set to 0 to disable extra spacing between every mid-cols.
    int           OptAddrDigitsCount;                   // = 0      // number of addr digits to display (default calculated based on maximum displayed addr).
    float         OptFooterExtraHeight;                 // = 0      // space to reserve at the bottom of the widget to add custom widgets
    ImU32         HighlightColor;                       //          // background color of highlighted bytes.
    ImU8 (*ReadFn)(const ImU8* data, size_t off);       // = 0      // optional handler to read bytes.
    void (*WriteFn)(ImU8* data, size_t off, ImU8 d);    // = 0      // optional handler to write bytes.
    bool (*HighlightFn)(const ImU8* data, size_t off);  //= 0      // optional handler to return Highlight property (to support non-contiguous highlighting).

    // [Internal State]
    bool          ContentsWidthChanged;
    size_t        DataPreviewAddr;
    size_t        DataEditingAddr;
    bool          DataEditingTakeFocus;
    char          DataInputBuf[32];
    char          AddrInputBuf[32];
    size_t        GotoAddr;
    size_t        HighlightMin, HighlightMax;
    int           PreviewEndianess;
    ImGuiDataType PreviewDataType;
} MemoryEditor;
//CIMGUI_API MemoryEditor*        MemoryEditor_Loader(void);
CIMGUI_API void        MemoryEditor_GotoAddrAndHighlight(MemoryEditor* self, size_t addr_min, size_t addr_max);
CIMGUI_API void        MemoryEditor_CalcSizes(MemoryEditor* self, MemoryEditor_Sizes* s, size_t mem_size, size_t base_display_addr);
// Standalone Memory Editor window
CIMGUI_API void        MemoryEditor_DrawWindow(MemoryEditor* self, const char* title, void* mem_data, size_t mem_size);                                             // Implied base_display_addr = 0x0000
CIMGUI_API void        MemoryEditor_DrawWindowEx(MemoryEditor* self, const char* title, void* mem_data, size_t mem_size, size_t base_display_addr /* = 0x0000 */);
// Memory Editor contents only
CIMGUI_API void        MemoryEditor_DrawContents(MemoryEditor* self, void* mem_data_void, size_t mem_size);                                                         // Implied base_display_addr = 0x0000
CIMGUI_API void        MemoryEditor_DrawContentsEx(MemoryEditor* self, void* mem_data_void, size_t mem_size, size_t base_display_addr /* = 0x0000 */);
CIMGUI_API void        MemoryEditor_DrawOptionsLine(MemoryEditor* self, MemoryEditor_Sizes s, void* mem_data, size_t mem_size, size_t base_display_addr);
CIMGUI_API void        MemoryEditor_DrawPreviewLine(MemoryEditor* self, MemoryEditor_Sizes s, void* mem_data_void, size_t mem_size, size_t base_display_addr);
// Utilities for Data Preview
CIMGUI_API const char* MemoryEditor_DataTypeGetDesc(const MemoryEditor* self, ImGuiDataType data_type);
CIMGUI_API size_t      MemoryEditor_DataTypeGetSize(const MemoryEditor* self, ImGuiDataType data_type);
CIMGUI_API const char* MemoryEditor_DataFormatGetDesc(const MemoryEditor* self, DataFormat data_format);
CIMGUI_API bool        MemoryEditor_IsBigEndian(const MemoryEditor* self);
CIMGUI_API void*       MemoryEditor_EndianessCopyBigEndian(MemoryEditor* self, void* _dst, void* _src, size_t s, int is_little_endian);
CIMGUI_API void*       MemoryEditor_EndianessCopyLittleEndian(MemoryEditor* self, void* _dst, void* _src, size_t s, int is_little_endian);
CIMGUI_API void*       MemoryEditor_EndianessCopy(const MemoryEditor* self, void* dst, void* src, size_t size);
CIMGUI_API const char* MemoryEditor_FormatBinary(const MemoryEditor* self, const uint8_t* buf, int width);
// [Internal]
CIMGUI_API void        MemoryEditor_DrawPreviewData(const MemoryEditor* self, size_t addr, const ImU8* mem_data, size_t mem_size, ImGuiDataType data_type, DataFormat data_format, char* out_buf, size_t out_buf_size);

#undef _PRISizeT
#undef ImSnprintf
#ifdef _MSC_VER
#pragma warning (pop)
#endif // #ifdef _MSC_VER
#ifdef __cplusplus
} // End of extern "C" block
#endif
