<commit_before>package imgui

import gli_.hasnt
import glm_.BYTES
import glm_.f
import glm_.func.common.max
import glm_.glm
import glm_.vec2.Vec2
import glm_.vec4.Vec4
import imgui.ImGui.io
import imgui.ImGui.shadeVertsLinearUV
import imgui.imgui.g
import imgui.internal.*
import kool.*
import java.nio.ByteBuffer
import java.util.Stack
import kotlin.math.sqrt
import imgui.internal.DrawCornerFlag as Dcf
import uno.kotlin.plusAssign

/** Draw callbacks for advanced uses.
 *  NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
 *  you can poke into the draw list for that! Draw callback may be useful for example to:
 *      A) Change your GPU render state,
 *      B) render a complex 3D scene inside a UI element without an intermediate texture/render target, etc.    */
typealias DrawCallback = (DrawList, DrawCmd) -> Unit

/** A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
 *
 *  Typically, 1 command = 1 gpu draw call (unless command is a callback)
 *
 *  Pre 1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields. When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset'
 *  is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bits indices.*/
class DrawCmd {

    constructor()

    constructor(drawCmd: DrawCmd) {
        elemCount = drawCmd.elemCount
        clipRect put drawCmd.clipRect
        textureId = drawCmd.textureId
        userCallback = drawCmd.userCallback
    }

    /** Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's
     *  vtx_buffer[] array, indices in idx_buffer[].    */
    var elemCount = 0
    /** Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates */
    var clipRect = Vec4()
    /** User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions.
    Ignore if never using images or multiple fonts atlas.   */
    var textureId: TextureID? = null
    /** Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0.
     *  With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bits indices. */
    var vtxOffset = 0
    /** Start offset in index buffer. Always equal to sum of ElemCount drawn so far. */
    var idxOffset = 0
    /** If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. */
    var userCallback: DrawCallback? = null

    /** Special Draw callback value to request renderer back-end to reset the graphics/render state.
     *  The renderer back-end needs to handle this special value, otherwise it will crash trying to call a function at this address.
     *  This is useful for example if you submitted callbacks which you know have altered the render state and you want it to be restored.
     *  It is not done by default because they are many perfectly useful way of altering render state for imgui contents
     *  (e.g. changing shader/blending settings before an Image call). */
    var resetRenderState = false

    var userCallbackData: ByteBuffer? = null
//    void*           UserCallbackData;       // The draw callback code can access this.

    infix fun put(drawCmd: DrawCmd) {
        elemCount = drawCmd.elemCount
        clipRect put drawCmd.clipRect
        textureId = drawCmd.textureId
        userCallback = drawCmd.userCallback
    }
}

/** Vertex index
 *  (to allow large meshes with 16-bits indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end)
 *  (to use 32-bits indices: override with '#define ImDrawIdx unsigned int' in imconfig.h) */
typealias DrawIdx = Int

/** Vertex layout
 *
 *  A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) */
class DrawVert {

    var pos = Vec2()
    var uv = Vec2()
    var col = 0

    companion object {
        val size = 2 * Vec2.size + Int.BYTES
        val ofsPos = 0
        val ofsUv = Vec2.size
        val ofsCol = Vec2.size * 2
    }

    override fun toString() = "pos: $pos, uv: $uv, col: $col"
}

/** Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
 *
 *  Draw channels are used by the Columns API to "split" the render list into different channels while building, so
 *  items of each column can be batched together.
 *  You can also use them to simulate drawing layers and submit primitives in a different order than how they will be
 *  rendered.   */
class DrawChannel {

    val cmdBuffer = Stack<DrawCmd>()
    val idxBuffer = Stack<Int>()

    fun clear() {
        cmdBuffer.clear()
        idxBuffer.clear()
    }
}

//-----------------------------------------------------------------------------
// ImDrawListSplitter
//-----------------------------------------------------------------------------
// FIXME: This may be a little confusing, trying to be a little too low-level/optimal instead of just doing vector swap..
//-----------------------------------------------------------------------------
/** Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.<commit_msg>:construction:       ImDrawCallback: Allow to override the signature of ImDrawCallback by #define-ing it. This is meant to facilitate custom rendering back-ends passing local render-specific data to the draw callback.<commit_after>package imgui

import gli_.hasnt
import glm_.BYTES
import glm_.f
import glm_.func.common.max
import glm_.glm
import glm_.vec2.Vec2
import glm_.vec4.Vec4
import imgui.ImGui.io
import imgui.ImGui.shadeVertsLinearUV
import imgui.imgui.g
import imgui.internal.*
import kool.*
import java.nio.ByteBuffer
import java.util.Stack
import kotlin.math.sqrt
import imgui.internal.DrawCornerFlag as Dcf
import uno.kotlin.plusAssign

/** Draw callbacks for advanced uses.
 *  NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
 *  you can poke into the draw list for that! Draw callback may be useful for example to:
 *      A) Change your GPU render state,
 *      B) render a complex 3D scene inside a UI element without an intermediate texture/render target, etc.
 *  The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) { cmd.UserCallback(parent_list, cmd); } else { RenderTriangles() }'
 *  If you want to override the signature of ImDrawCallback, you can simply use e.g. '#define ImDrawCallback MyDrawCallback' (in imconfig.h) + update rendering back-end accordingly. */
typealias DrawCallback = (DrawList, DrawCmd) -> Unit

/** A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
 *
 *  Typically, 1 command = 1 gpu draw call (unless command is a callback)
 *
 *  Pre 1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields. When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset'
 *  is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bits indices.*/
class DrawCmd {

    constructor()

    constructor(drawCmd: DrawCmd) {
        elemCount = drawCmd.elemCount
        clipRect put drawCmd.clipRect
        textureId = drawCmd.textureId
        userCallback = drawCmd.userCallback
    }

    /** Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's
     *  vtx_buffer[] array, indices in idx_buffer[].    */
    var elemCount = 0
    /** Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates */
    var clipRect = Vec4()
    /** User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions.
    Ignore if never using images or multiple fonts atlas.   */
    var textureId: TextureID? = null
    /** Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0.
     *  With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bits indices. */
    var vtxOffset = 0
    /** Start offset in index buffer. Always equal to sum of ElemCount drawn so far. */
    var idxOffset = 0
    /** If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. */
    var userCallback: DrawCallback? = null

    /** Special Draw callback value to request renderer back-end to reset the graphics/render state.
     *  The renderer back-end needs to handle this special value, otherwise it will crash trying to call a function at this address.
     *  This is useful for example if you submitted callbacks which you know have altered the render state and you want it to be restored.
     *  It is not done by default because they are many perfectly useful way of altering render state for imgui contents
     *  (e.g. changing shader/blending settings before an Image call). */
    var resetRenderState = false

    var userCallbackData: ByteBuffer? = null
//    void*           UserCallbackData;       // The draw callback code can access this.

    infix fun put(drawCmd: DrawCmd) {
        elemCount = drawCmd.elemCount
        clipRect put drawCmd.clipRect
        textureId = drawCmd.textureId
        userCallback = drawCmd.userCallback
    }
}

/** Vertex index
 *  (to allow large meshes with 16-bits indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end)
 *  (to use 32-bits indices: override with '#define ImDrawIdx unsigned int' in imconfig.h) */
typealias DrawIdx = Int

/** Vertex layout
 *
 *  A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) */
class DrawVert {

    var pos = Vec2()
    var uv = Vec2()
    var col = 0

    companion object {
        val size = 2 * Vec2.size + Int.BYTES
        val ofsPos = 0f
        val ofsUv = Vec2.size
        val ofsCol = Vec2.size * 2
    }

    override fun toString() = "pos: $pos, uv: $uv, col: $col"
}

/** Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
 *
 *  Draw channels are used by the Columns API to "split" the render list into different channels while building, so
 *  items of each column can be batched together.
 *  You can also use them to simulate drawing layers and submit primitives in a different order than how they will be
 *  rendered.   */
class DrawChannel {

    val cmdBuffer = Stack<DrawCmd>()
    val idxBuffer = Stack<Int>()

    fun clear() {
        cmdBuffer.clear()
        idxBuffer.clear()
    }
}

//-----------------------------------------------------------------------------
// ImDrawListSplitter
//-----------------------------------------------------------------------------
// FIXME: This may be a little confusing, trying to be a little too low-level/optimal instead of just doing vector swap..
//-----------------------------------------------------------------------------
/** Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
{'fraction_non_alphanumeric': 0.109587852494577, 'fraction_numerical': 0.008329718004338394, 'mean_word_length': 2.7951926243002965, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '919097', 'n_tokens_mistral': 3167, 'n_tokens_neox': 3071, 'n_words': 1344}