# /!\ Autogenerated code, modifications will be lost /!\
# see `generation/generate_bindings.py`

from godot._hazmat.gdnative_api_struct cimport *
from godot._hazmat.gdapi cimport pythonscript_gdapi10 as gdapi10
from godot._hazmat.conversion cimport *
from godot.builtins cimport *

from enum import IntFlag


__ERR_MSG_BINDING_NOT_AVAILABLE = "No Godot binding available"


class Error(IntFlag):
    OK = godot_error.GODOT_OK
    FAILED = godot_error.GODOT_FAILED
    ERR_UNAVAILABLE = godot_error.GODOT_ERR_UNAVAILABLE
    ERR_UNCONFIGURED = godot_error.GODOT_ERR_UNCONFIGURED
    ERR_UNAUTHORIZED = godot_error.GODOT_ERR_UNAUTHORIZED
    ERR_PARAMETER_RANGE_ERROR = godot_error.GODOT_ERR_PARAMETER_RANGE_ERROR
    ERR_OUT_OF_MEMORY = godot_error.GODOT_ERR_OUT_OF_MEMORY
    ERR_FILE_NOT_FOUND = godot_error.GODOT_ERR_FILE_NOT_FOUND
    ERR_FILE_BAD_DRIVE = godot_error.GODOT_ERR_FILE_BAD_DRIVE
    ERR_FILE_BAD_PATH = godot_error.GODOT_ERR_FILE_BAD_PATH
    ERR_FILE_NO_PERMISSION = godot_error.GODOT_ERR_FILE_NO_PERMISSION
    ERR_FILE_ALREADY_IN_USE = godot_error.GODOT_ERR_FILE_ALREADY_IN_USE
    ERR_FILE_CANT_OPEN = godot_error.GODOT_ERR_FILE_CANT_OPEN
    ERR_FILE_CANT_WRITE = godot_error.GODOT_ERR_FILE_CANT_WRITE
    ERR_FILE_CANT_READ = godot_error.GODOT_ERR_FILE_CANT_READ
    ERR_FILE_UNRECOGNIZED = godot_error.GODOT_ERR_FILE_UNRECOGNIZED
    ERR_FILE_CORRUPT = godot_error.GODOT_ERR_FILE_CORRUPT
    ERR_FILE_MISSING_DEPENDENCIES = godot_error.GODOT_ERR_FILE_MISSING_DEPENDENCIES
    ERR_FILE_EOF = godot_error.GODOT_ERR_FILE_EOF
    ERR_CANT_OPEN = godot_error.GODOT_ERR_CANT_OPEN
    ERR_CANT_CREATE = godot_error.GODOT_ERR_CANT_CREATE
    ERR_QUERY_FAILED = godot_error.GODOT_ERR_QUERY_FAILED
    ERR_ALREADY_IN_USE = godot_error.GODOT_ERR_ALREADY_IN_USE
    ERR_LOCKED = godot_error.GODOT_ERR_LOCKED
    ERR_TIMEOUT = godot_error.GODOT_ERR_TIMEOUT
    ERR_CANT_CONNECT = godot_error.GODOT_ERR_CANT_CONNECT
    ERR_CANT_RESOLVE = godot_error.GODOT_ERR_CANT_RESOLVE
    ERR_CONNECTION_ERROR = godot_error.GODOT_ERR_CONNECTION_ERROR
    ERR_CANT_ACQUIRE_RESOURCE = godot_error.GODOT_ERR_CANT_ACQUIRE_RESOURCE
    ERR_CANT_FORK = godot_error.GODOT_ERR_CANT_FORK
    ERR_INVALID_DATA = godot_error.GODOT_ERR_INVALID_DATA
    ERR_INVALID_PARAMETER = godot_error.GODOT_ERR_INVALID_PARAMETER
    ERR_ALREADY_EXISTS = godot_error.GODOT_ERR_ALREADY_EXISTS
    ERR_DOES_NOT_EXIST = godot_error.GODOT_ERR_DOES_NOT_EXIST
    ERR_DATABASE_CANT_READ = godot_error.GODOT_ERR_DATABASE_CANT_READ
    ERR_DATABASE_CANT_WRITE = godot_error.GODOT_ERR_DATABASE_CANT_WRITE
    ERR_COMPILATION_FAILED = godot_error.GODOT_ERR_COMPILATION_FAILED
    ERR_METHOD_NOT_FOUND = godot_error.GODOT_ERR_METHOD_NOT_FOUND
    ERR_LINK_FAILED = godot_error.GODOT_ERR_LINK_FAILED
    ERR_SCRIPT_FAILED = godot_error.GODOT_ERR_SCRIPT_FAILED
    ERR_CYCLIC_LINK = godot_error.GODOT_ERR_CYCLIC_LINK
    ERR_INVALID_DECLARATION = godot_error.GODOT_ERR_INVALID_DECLARATION
    ERR_DUPLICATE_SYMBOL = godot_error.GODOT_ERR_DUPLICATE_SYMBOL
    ERR_PARSE_ERROR = godot_error.GODOT_ERR_PARSE_ERROR
    ERR_BUSY = godot_error.GODOT_ERR_BUSY
    ERR_SKIP = godot_error.GODOT_ERR_SKIP
    ERR_HELP = godot_error.GODOT_ERR_HELP
    ERR_BUG = godot_error.GODOT_ERR_BUG
    ERR_PRINTER_ON_FIRE = godot_error.GODOT_ERR_PRINTER_ON_FIRE


class VariantType(IntFlag):
    NIL = godot_variant_type.GODOT_VARIANT_TYPE_NIL
    BOOL = godot_variant_type.GODOT_VARIANT_TYPE_BOOL
    INT = godot_variant_type.GODOT_VARIANT_TYPE_INT
    REAL = godot_variant_type.GODOT_VARIANT_TYPE_REAL
    STRING = godot_variant_type.GODOT_VARIANT_TYPE_STRING
    VECTOR2 = godot_variant_type.GODOT_VARIANT_TYPE_VECTOR2
    RECT2 = godot_variant_type.GODOT_VARIANT_TYPE_RECT2
    VECTOR3 = godot_variant_type.GODOT_VARIANT_TYPE_VECTOR3
    TRANSFORM2D = godot_variant_type.GODOT_VARIANT_TYPE_TRANSFORM2D
    PLANE = godot_variant_type.GODOT_VARIANT_TYPE_PLANE
    QUAT = godot_variant_type.GODOT_VARIANT_TYPE_QUAT
    AABB = godot_variant_type.GODOT_VARIANT_TYPE_AABB
    BASIS = godot_variant_type.GODOT_VARIANT_TYPE_BASIS
    TRANSFORM = godot_variant_type.GODOT_VARIANT_TYPE_TRANSFORM
    COLOR = godot_variant_type.GODOT_VARIANT_TYPE_COLOR
    NODE_PATH = godot_variant_type.GODOT_VARIANT_TYPE_NODE_PATH
    RID = godot_variant_type.GODOT_VARIANT_TYPE_RID
    OBJECT = godot_variant_type.GODOT_VARIANT_TYPE_OBJECT
    DICTIONARY = godot_variant_type.GODOT_VARIANT_TYPE_DICTIONARY
    ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_ARRAY
    POOL_BYTE_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY
    POOL_INT_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_INT_ARRAY
    POOL_REAL_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_REAL_ARRAY
    POOL_STRING_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_STRING_ARRAY
    POOL_VECTOR2_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_VECTOR2_ARRAY
    POOL_VECTOR3_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_VECTOR3_ARRAY
    POOL_COLOR_ARRAY = godot_variant_type.GODOT_VARIANT_TYPE_POOL_COLOR_ARRAY


class VariantOperator(IntFlag):
    EQUAL = godot_variant_operator.GODOT_VARIANT_OP_EQUAL
    NOT_EQUAL = godot_variant_operator.GODOT_VARIANT_OP_NOT_EQUAL
    LESS = godot_variant_operator.GODOT_VARIANT_OP_LESS
    LESS_EQUAL = godot_variant_operator.GODOT_VARIANT_OP_LESS_EQUAL
    GREATER = godot_variant_operator.GODOT_VARIANT_OP_GREATER
    GREATER_EQUAL = godot_variant_operator.GODOT_VARIANT_OP_GREATER_EQUAL
    ADD = godot_variant_operator.GODOT_VARIANT_OP_ADD
    SUBTRACT = godot_variant_operator.GODOT_VARIANT_OP_SUBTRACT
    MULTIPLY = godot_variant_operator.GODOT_VARIANT_OP_MULTIPLY
    DIVIDE = godot_variant_operator.GODOT_VARIANT_OP_DIVIDE
    NEGATE = godot_variant_operator.GODOT_VARIANT_OP_NEGATE
    POSITIVE = godot_variant_operator.GODOT_VARIANT_OP_POSITIVE
    MODULE = godot_variant_operator.GODOT_VARIANT_OP_MODULE
    STRING_CONCAT = godot_variant_operator.GODOT_VARIANT_OP_STRING_CONCAT
    SHIFT_LEFT = godot_variant_operator.GODOT_VARIANT_OP_SHIFT_LEFT
    SHIFT_RIGHT = godot_variant_operator.GODOT_VARIANT_OP_SHIFT_RIGHT
    BIT_AND = godot_variant_operator.GODOT_VARIANT_OP_BIT_AND
    BIT_OR = godot_variant_operator.GODOT_VARIANT_OP_BIT_OR
    BIT_XOR = godot_variant_operator.GODOT_VARIANT_OP_BIT_XOR
    BIT_NEGATE = godot_variant_operator.GODOT_VARIANT_OP_BIT_NEGATE
    AND = godot_variant_operator.GODOT_VARIANT_OP_AND
    OR = godot_variant_operator.GODOT_VARIANT_OP_OR
    XOR = godot_variant_operator.GODOT_VARIANT_OP_XOR
    NOT = godot_variant_operator.GODOT_VARIANT_OP_NOT
    IN = godot_variant_operator.GODOT_VARIANT_OP_IN
    MAX = godot_variant_operator.GODOT_VARIANT_OP_MAX


### Classes ###

{% from 'class.tmpl.pyx' import render_class, render_class_gdapi_ptrs_init -%}
{%- for cls in classes %}
{{ render_class(cls) }}
{%- endfor %}

### Global constants ###

{% for key, value in constants.items() %}
{{key}} = {{value}}
{% endfor %}

### Class&singletons needed for Pythonscript bootstrap ###

# Godot classes&singletons are not all available when loading Pythonscript.
# Hence greedy loading is done only for items needed for Pythonscript
# bootstrap.
# The remaining loading will be achieved when loading the first python script
# (where at this point Godot should have finished it initialization).

{% set early_needed_bindings = ["_OS", "_ProjectSettings"] %}
cdef godot_object *_ptr
{% for cls in classes %}
{% if cls.name in early_needed_bindings %}
{{ render_class_gdapi_ptrs_init(cls) }}
{% if cls.singleton %}
_ptr = gdapi10.godot_global_get_singleton("{{ cls.singleton }}")
if _ptr != NULL:
    {{ cls.singleton }} = {{ cls.name }}.from_ptr(_ptr)
else:
    print("ERROR: cannot load singleton `{{ cls.singleton }}` required for Pythonscript init")
{% endif %}
{% endif %}
{% endfor %}

### Remining bindings late intialization ###

cdef bint _bindings_initialized = False

{% for cls in classes %}
{% if cls.name not in early_needed_bindings %}
{% if cls.singleton %}
{{ cls.singleton }} = {{ cls.name }}.from_ptr(NULL)
{% endif %}
{% endif %}
{% endfor %}

cdef void _initialize_bindings():
    global _bindings_initialized
    if _bindings_initialized:
        return

{%- for cls in classes %}
{%- if cls.name not in early_needed_bindings %}
    {{ render_class_gdapi_ptrs_init(cls)  | indent }}
{%- if cls.singleton %}
    global {{ cls.singleton }}
    (<{{ cls["name"] }}>{{ cls.singleton }})._gd_ptr = gdapi10.godot_global_get_singleton("{{ cls.singleton }}")
    if (<{{ cls["name"] }}>{{ cls.singleton }})._gd_ptr == NULL:
        print('Cannot retreive singleton {{ cls.singleton }}')
{%- endif %}
{%- endif %}
{%- endfor %}

    _bindings_initialized = True
