{% import "pybind11.cpp.j2" as pybind11 %}

// This file is autogenerated. DO NOT EDIT
#include <robotpy_build.h>

{% for inc in data.extra_includes_first %}
#include <{{ inc }}>
{% endfor %}

#include <{{ header.rel_fname }}>

{% for inc in type_caster_includes %}
#include <{{ inc }}>
{% endfor %}

{% if x_has_operators %}
#include <pybind11/operators.h>
{% endif %}

{% for using in header.using.values() if using.using_type != "typealias" %}
using {{ using.raw_type }};
{% endfor %}

{% for cls in header.classes
   if not cls.data.ignore and cls.x_has_trampoline %}
#define RPYGEN_ENABLE_{{ cls.x_qualname_ }}_PROTECTED_CONSTRUCTORS
#include <rpygen/{{ cls.x_qualname_ }}.hpp>
{% endfor %}

{% for tmpl_data in templates.values() %}
#include <rpygen/{{ tmpl_data.x_qualname_ }}.hpp>
{% endfor %}

{% for inc in data.extra_includes %}
#include <{{ inc }}>
{% endfor %}

{#
  Ordering of the initialization function

  - namespace/typealiases
  - global enums
  - templates (because CRTP)
  - class declarations
  - class enums
  - class methods
  - global methods
#}

void init_{{ mod_fn }}(py::module &m) {

{# namespaces/typealiases #}
{% for cls in header.classes if not cls.data.ignore and cls.template is not defined %}
  {{ pybind11.cls_using(cls) }}
{% endfor %}

{# subpackages #}
{% for pkg, vname in subpackages.items() %}
  auto {{ vname }} = m.def_submodule("{{ pkg }}");
{% endfor %}

{# define global enums in case they are used as default args #}  
{% for enum in header.enums %}
  {{ pybind11.genenum(enum.x_module_var, enum) }}
{% endfor %}

{# templates #}
{% for name, tmpl_data in templates.items() %}
  rpygen::bind_{{ tmpl_data.x_qualname_ }}<{{ tmpl_data.params | join(', ') }}>(m, "{{ name }}");
{% endfor %}

{# class declarations #}
{%- for cls in header.classes
   if not cls.parent and not cls.data.ignore and cls.template is not defined %}
  {{ pybind11.cls_decl(cls, cls.x_varname, '"' + cls.x_name + '"') }}
{% endfor %}

{# class methods #}
{%- for cls in header.classes
   if not cls.parent and not cls.data.ignore and cls.template is not defined %}
  {{ pybind11.cls_methods(cls, cls.x_varname) }}
{% endfor %}

{# global methods #}
{%- if header.functions %}
  {% for fn in header.functions if not fn.data.ignore -%}
    {{ fn.x_module_var }}{{ pybind11.genmethod(None, fn, None) }};
  {% endfor %};
{% endif %}

{% if data.inline_code %}

  {{ data.inline_code }}
{% endif %}
}
