"""ImGuizmo: Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
https://github.com/CedricGuillemet/ImGuizmo
"""
# ruff: noqa: F821
from typing import List, Optional, Any, overload
import enum
import numpy as np

from imgui_bundle.imgui import ImU32, ImDrawList, ImVec2Like

ImGuiContext = Any

ImGuiZoomSliderFlags = int
ImGuiZoomSliderFlags_None = im_zoom_slider.ImGuiZoomSliderFlags_.none  # noqa


# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  AUTOGENERATED CODE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <litgen_stub> // Autogenerated code below! Do not edit!
####################    <generated_from:ImGuizmoPure.h>    ####################
# THIS FILE WAS GENERATED AUTOMATICALLY. DO NOT EDIT.

#////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#                       ImGuizmoPure/ImGuizmoPure.h                                                            //
#//////////////////////////////////////////////////////////////////////////////////////////////////////////////
# Part of ImGui Bundle - MIT License - Copyright (c) 2022-2024 Pascal Thomet - https://github.com/pthom/imgui_bundle


#////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#                       ImGuizmo/ImGuizmo.h included by ImGuizmoPure/ImGuizmoPure.h                            //
#//////////////////////////////////////////////////////////////////////////////////////////////////////////////
# https://github.com/CedricGuillemet/ImGuizmo
# v1.91.3 WIP
#
# The MIT License(MIT)
#
# Copyright(c) 2021 Cedric Guillemet
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions :
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# -------------------------------------------------------------------------------------------
# History :
# 2019/11/03 View gizmo
# 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
# 2016/09/09 Hatched negative axis. Snapping. Documentation update.
# 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
# 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
# 2016/08/31 First version
#
# -------------------------------------------------------------------------------------------
# Future (no order):
#
# - Multi view
# - display rotation/translation/scale infos in local/world space and not only local
# - finish local/world matrix application
# - OPERATION as bitmask
#
# -------------------------------------------------------------------------------------------
# Example






#////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#                       ImGuizmoPure/ImGuizmoPure.h continued                                                  //
#//////////////////////////////////////////////////////////////////////////////////////////////////////////////






# <submodule im_guizmo>
class im_guizmo:  # Proxy class that introduces typings for the *submodule* im_guizmo
    pass  # (This corresponds to a C++ namespace. All method are static!)
    @staticmethod
    def set_drawlist(drawlist: Optional[ImDrawList] = None) -> None:
        """ call inside your own window and before Manipulate() in order to draw gizmo to that window.
         Or pass a specific ImDrawList to draw to (e.g. ImGui::GetForegroundDrawList()).
        """
        pass

    @staticmethod
    def begin_frame() -> None:
        """ call BeginFrame right after ImGui_XXXX_NewFrame();"""
        pass

    @staticmethod
    def set_im_gui_context(ctx: ImGuiContext) -> None:
        """ this is necessary because when imguizmo is compiled into a dll, and imgui into another
         globals are not shared between them.
         More details at https://stackoverflow.com/questions/19373061/what-happens-to-global-and-static-variables-in-a-shared-library-when-it-is-dynam
         expose method to set imgui context
        """
        pass

    @staticmethod
    @overload
    def is_over() -> bool:
        """ return True if mouse cursor is over any gizmo control (axis, plan or screen component)"""
        pass

    @staticmethod
    def is_using() -> bool:
        """ return True if mouse IsOver or if the gizmo is in moving state"""
        pass

    @staticmethod
    def is_using_view_manipulate() -> bool:
        """ return True if the view gizmo is in moving state"""
        pass
    @staticmethod
    def is_view_manipulate_hovered() -> bool:
        """ only check if your mouse is over the view manipulator - no matter whether it's active or not"""
        pass

    @staticmethod
    def is_using_any() -> bool:
        """ return True if any gizmo is in moving state"""
        pass

    @staticmethod
    def enable(enable: bool) -> None:
        """ enable/disable the gizmo. Stay in the state until next call to Enable.
         gizmo is rendered with gray half transparent color when disabled
        """
        pass

    # helper functions for manualy editing translation/rotation/scale with an input float
    # translation, rotation and scale float points to 3 floats each
    # Angles are in degrees (more suitable for human editing)
    # example:
    # float matrixTranslation[3], matrixRotation[3], matrixScale[3];
    # ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
    # ImGui::InputFloat3("Tr", matrixTranslation, 3);
    # ImGui::InputFloat3("Rt", matrixRotation, 3);
    # ImGui::InputFloat3("Sc", matrixScale, 3);
    # ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
    #
    # These functions have some numerical stability issues for now. Use with caution.

    @staticmethod
    def set_rect(x: float, y: float, width: float, height: float) -> None:
        pass
    @staticmethod
    def set_orthographic(is_orthographic: bool) -> None:
        """ default is False"""
        pass

    # Render a cube with face color corresponding to face normal. Usefull for debug/tests

    class OPERATION(enum.Enum):
        """ call it when you want a gizmo
         Needs view and projection matrices.
         matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
         translation is applied in world space
        """
        translate_x = enum.auto()   # (= (1u << 0))
        translate_y = enum.auto()   # (= (1u << 1))
        translate_z = enum.auto()   # (= (1u << 2))
        rotate_x = enum.auto()      # (= (1u << 3))
        rotate_y = enum.auto()      # (= (1u << 4))
        rotate_z = enum.auto()      # (= (1u << 5))
        rotate_screen = enum.auto() # (= (1u << 6))
        scale_x = enum.auto()       # (= (1u << 7))
        scale_y = enum.auto()       # (= (1u << 8))
        scale_z = enum.auto()       # (= (1u << 9))
        bounds = enum.auto()        # (= (1u << 10))
        scale_xu = enum.auto()      # (= (1u << 11))
        scale_yu = enum.auto()      # (= (1u << 12))
        scale_zu = enum.auto()      # (= (1u << 13))

        translate = enum.auto()     # (= OPERATION.translate_x | OPERATION.translate_y | OPERATION.translate_z)
        rotate = enum.auto()        # (= OPERATION.rotate_x | OPERATION.rotate_y | OPERATION.rotate_z | OPERATION.rotate_screen)
        scale = enum.auto()         # (= OPERATION.scale_x | OPERATION.scale_y | OPERATION.scale_z)
        scaleu = enum.auto()        # (= OPERATION.scale_xu | OPERATION.scale_yu | OPERATION.scale_zu)  # universal
        universal = enum.auto()     # (= OPERATION.translate | OPERATION.rotate | OPERATION.scaleu)


    class MODE(enum.Enum):
        local = enum.auto() # (= 0)
        world = enum.auto() # (= 1)



    @staticmethod
    def set_alternative_window(window: ImGuiWindow) -> None:
        pass

    @staticmethod
    def set_id(id: int) -> None:
        pass

    # ID stack/scopes
    # Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
    # - Those questions are answered and impacted by understanding of the ID stack system:
    #   - "Q: Why is my widget not reacting when I click on it?"
    #   - "Q: How can I have widgets with an empty label?"
    #   - "Q: How can I have multiple widgets with the same label?"
    # - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely
    #   want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
    # - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
    # - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
    #   whereas "str_id" denote a string that is only used as an ID and not normally displayed.
    @staticmethod
    @overload
    def push_id(str_id: str) -> None:
        """ push string into the ID stack (will hash string)."""
        pass
    @staticmethod
    @overload
    def push_id(str_id_begin: str, str_id_end: str) -> None:
        """ push string into the ID stack (will hash string)."""
        pass
    @staticmethod
    @overload
    def push_id(ptr_id: Any) -> None:
        """ push pointer into the ID stack (will hash pointer)."""
        pass
    @staticmethod
    @overload
    def push_id(int_id: int) -> None:
        """ push integer into the ID stack (will hash integer)."""
        pass
    @staticmethod
    def pop_id() -> None:
        """ pop from the ID stack."""
        pass
    @staticmethod
    @overload
    def get_id(str_id: str) -> ImGuiID:
        """ calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself"""
        pass
    @staticmethod
    @overload
    def get_id(str_id_begin: str, str_id_end: str) -> ImGuiID:
        pass
    @staticmethod
    @overload
    def get_id(ptr_id: Any) -> ImGuiID:
        pass

    # return True if the cursor is over the operation's gizmo
    @staticmethod
    @overload
    def is_over(op: OPERATION) -> bool:
        pass
    @staticmethod
    def set_gizmo_size_clip_space(value: float) -> None:
        pass

    @staticmethod
    def allow_axis_flip(value: bool) -> None:
        """ Allow axis to flip
         When True (default), the guizmo axis flip for better visibility
         When False, they always stay along the positive world/local axis
        """
        pass

    @staticmethod
    def set_axis_limit(value: float) -> None:
        """ Configure the limit where axis are hidden"""
        pass
    @staticmethod
    def set_axis_mask(x: bool, y: bool, z: bool) -> None:
        """ Set an axis mask to permanently hide a given axis (True -> hidden, False -> shown)"""
        pass
    @staticmethod
    def set_plane_limit(value: float) -> None:
        """ Configure the limit where planes are hiden"""
        pass

    class COLOR(enum.Enum):
        direction_x = enum.auto()           # (= 0)  # directionColor[0]
        direction_y = enum.auto()           # (= 1)  # directionColor[1]
        direction_z = enum.auto()           # (= 2)  # directionColor[2]
        plane_x = enum.auto()               # (= 3)  # planeColor[0]
        plane_y = enum.auto()               # (= 4)  # planeColor[1]
        plane_z = enum.auto()               # (= 5)  # planeColor[2]
        selection = enum.auto()             # (= 6)  # selectionColor
        inactive = enum.auto()              # (= 7)  # inactiveColor
        translation_line = enum.auto()      # (= 8)  # translationLineColor
        scale_line = enum.auto()            # (= 9)
        rotation_using_border = enum.auto() # (= 10)
        rotation_using_fill = enum.auto()   # (= 11)
        hatched_axis_lines = enum.auto()    # (= 12)
        text = enum.auto()                  # (= 13)
        text_shadow = enum.auto()           # (= 14)
        count = enum.auto()                 # (= 15)

    class Style:
        def __init__(self) -> None:
            pass

        translation_line_thickness: float     # Thickness of lines for translation gizmo
        translation_line_arrow_size: float    # Size of arrow at the end of lines for translation gizmo
        rotation_line_thickness: float        # Thickness of lines for rotation gizmo
        rotation_outer_line_thickness: float  # Thickness of line surrounding the rotation gizmo
        scale_line_thickness: float           # Thickness of lines for scale gizmo
        scale_line_circle_size: float         # Size of circle at the end of lines for scale gizmo
        hatched_axis_line_thickness: float    # Thickness of hatched axis lines
        center_circle_size: float             # Size of circle at the center of the translate/scale gizmo


    @staticmethod
    def get_style() -> Style:
        pass
    class Matrix16:
        values: np.ndarray  # ndarray[type=float, size=16] default:float()
        @overload
        def __init__(self) -> None:
            pass
        @overload
        def __init__(self, v: List[float]) -> None:
            pass
    class Matrix6:
        values: np.ndarray  # ndarray[type=float, size=6] default:float()
        @overload
        def __init__(self) -> None:
            pass
        @overload
        def __init__(self, v: List[float]) -> None:
            pass
    class Matrix3:
        values: np.ndarray  # ndarray[type=float, size=3] default:float()
        @overload
        def __init__(self) -> None:
            pass
        @overload
        def __init__(self, v: List[float]) -> None:
            pass

    class MatrixComponents:
        translation: Matrix3
        rotation: Matrix3
        scale: Matrix3
        def __init__(self) -> None:
            """Autogenerated default constructor"""
            pass

    # helper functions for manualy editing translation/rotation/scale with an input float
    # translation, rotation and scale float points to 3 floats each
    # Angles are in degrees (more suitable for human editing)
    # example:
    # float matrixTranslation[3], matrixRotation[3], matrixScale[3];
    # ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
    # ImGui::InputFloat3("Tr", matrixTranslation, 3);
    # ImGui::InputFloat3("Rt", matrixRotation, 3);
    # ImGui::InputFloat3("Sc", matrixScale, 3);
    # ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
    #
    # These functions have some numerical stability issues for now. Use with caution.
    @staticmethod
    def decompose_matrix_to_components(matrix: Matrix16) -> MatrixComponents:
        pass
    @staticmethod
    def recompose_matrix_from_components(matrix_components: MatrixComponents) -> Matrix16:
        pass

    # Render a cube with face color corresponding to face normal. Usefull for debug/tests
    @staticmethod
    def draw_cubes(view: Matrix16, projection: Matrix16, matrices: List[Matrix16]) -> None:
        pass
    @staticmethod
    def draw_grid(
        view: Matrix16,
        projection: Matrix16,
        matrix: Matrix16,
        grid_size: float
        ) -> None:
        pass

    @staticmethod
    def manipulate(
        view: Matrix16,
        projection: Matrix16,
        operation: OPERATION,
        mode: MODE,
        object_matrix: Matrix16,
        delta_matrix: Optional[Matrix16] = None,
        snap: Optional[Matrix3] = None,
        local_bounds: Optional[Matrix6] = None,
        bounds_snap: Optional[Matrix3] = None
        ) -> bool:
        """ Manipulate may change the objectMatrix parameter (return True if modified)"""
        pass

    @staticmethod
    @overload
    def view_manipulate(
        view: Matrix16,
        length: float,
        position: ImVec2Like,
        size: ImVec2Like,
        background_color: ImU32
        ) -> None:
        """
         Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en
         It seems to be a defensive patent in the US. I don't think it will bring troubles using it as
         other software are using the same mechanics. But just in case, you are now warned!

         ViewManipulate may change the view parameter
        """
        pass

    @staticmethod
    @overload
    def view_manipulate(
        view: Matrix16,
        projection: Matrix16,
        operation: OPERATION,
        mode: MODE,
        matrix: Matrix16,
        length: float,
        position: ImVec2Like,
        size: ImVec2Like,
        background_color: ImU32
        ) -> None:
        """ use this version if you did not call Manipulate before, and you are just using ViewManipulate.
         ViewManipulate may change the view parameter!
        """
        pass

# </submodule im_guizmo>
####################    </generated_from:ImGuizmoPure.h>    ####################

# </litgen_stub> // Autogenerated code end!
