# Copyright (C) 2022 Justin Schuh <code@justinschuh.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.

[gcode_macro _check_kinematic_limits]
gcode:
  {% set toolhead = printer.toolhead %}
  {% if params.X and (params.X|float < toolhead.axis_minimum.x or
                      params.X|float > toolhead.axis_maximum.x) %}
    {action_raise_error("X[%.3f] must be between %.3f and %.3f."
                        | format(params.X|float, toolhead.axis_minimum.x,
                                 toolhead.axis_maximum.x))}
  {% elif params.Y and (params.Y|float < toolhead.axis_minimum.y or
                        params.Y|float > toolhead.axis_maximum.y) %}
    {action_raise_error("Y[%.3f] must be between %.3f and %.3f."
                        | format(params.Y|float, toolhead.axis_minimum.y,
                                 toolhead.axis_maximum.y))}
  {% elif params.Z and (params.Z|float < toolhead.axis_minimum.z or
                        params.Z|float > toolhead.axis_maximum.z) %}
    {action_raise_error("Z[%.3f] must be between %.3f and %.3f."
                        | format(params.Z|float, toolhead.axis_minimum.z,
                                 toolhead.axis_maximum.z))}
  {% elif params.E and (params.E|float|abs > printer.configfile.settings[
                          "extruder"].max_extrude_only_distance) %}
    {action_raise_error("E[%.4f] exceeds max_extrude_only_distance[%.4f]."
       | format(params.E|float|abs, printer.configfile.settings[
                                      "extruder"].max_extrude_only_distance))}
  {% endif %}

[gcode_macro g28]
description: Wraps the G28 command to add the Marlin "O" parameter so that already homed axes will not be homed again. See the Klipper documentation on G28 for the behavior of the other parameters.
  Usage: G28 [O] ...
rename_existing: G28.6245197
gcode:
  {% set do_homing = True %}
  {% if 'O' in params %}
    # No axes means home them all, so add the list in before pruning.
    {% if params|select('in', 'XYZ')|list|length == 0 %}
      {% for k in 'XYZ' %}
        {% set dummy = params.__setitem__(k, '') %}
      {% endfor %}
    {% endif %}
    # Prune out the already homed axes.
    {% for k in params|select('in', 'XYZ')|list %}
      {% if k|lower in printer.toolhead.homed_axes %}
        {% set dummy = params.__delitem__(k) %}
      {% endif %}
    {% endfor %}
    {% set dummy = params.__delitem__('O') %}
    # If we don't have anything left we can skip homing.
    {% set do_homing = params|select('in', 'XYZ')|list|length > 0 %}
  {% else %}
  {% endif %}

  {% if do_homing %}
    G28.6245197{% for k in params %}{' ' ~ k ~ params[k]}{% endfor %}
  {% endif %}
