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

# Enables pause/resume functionality
[gcode_macro pause]
description: Pauses the current print.
  Usage: PAUSE [X=<pos>] [Y=<pos>] [Z=<pos>] [E=<retract_length>] [B=<beeps>]
rename_existing: _KM_PAUSE_BASE
gcode:
  {% set km = printer["gcode_macro _km_globals"] %}
  # Retract length (negative)
  {% set E = (params.E|default(5))|float %}
  # Beeps
  {% set B = (params.B|default(10))|float %}

  {% if printer.virtual_sdcard.is_active %}
    {% set position = printer.gcode_move.gcode_position %}
    SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_x VALUE="{position.x}"
    SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_y VALUE="{position.y}"
    SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_z VALUE="{position.z}"
    SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_e VALUE="{E}"
    SAVE_GCODE_STATE NAME=_KM_PAUSE_OVERRIDE_STATE
    _KM_PAUSE_BASE
    M83
    G1 E{'%.4f' % -E} F{km.load_speed}
    PARK P=2{% for k in params|select("in", "XYZ") %}
      {' '~k~'="'~params[k]~'"'}
    {% endfor %}
    # Beep on pause if there's an M300 macro.
    {% if "output_pin beeper" in printer %}
      {% for i in range(B|int) %}
        M300 P100
        G4 P200
      {% endfor %}
    {% endif %}
  {% else %}
    { action_respond_info("Print from SD card is not in progress.") }
  {% endif %}

[gcode_macro m600]
description: Pauses the current print.
  Usage: M600 [B<beeps>] [E<pos>] [L<pos>] [R<temp>] [U<pos>] [X<pos>] [Y<pos>]
              [Z<pos>]
gcode:
  PAUSE P=2{% for k in params|select("in", "BEXYZ") %}{
      ' '~k~'="'~params[k]~'"'}{% endfor %}
  SET_GCODE_VARIABLE MACRO=_load_unload VARIABLE=is_printing VALUE="{0}"
  UNLOAD_FILAMENT{% if 'U' in params %} LENGTH={params.U}{% endif %}
  {% if 'R' in params %}M109 S{params.R}{% endif %}

[gcode_macro m601]
description: Pauses the current print.
  Usage: M601
gcode:
  PAUSE

[gcode_macro m602]
description: Resumes the currently paused print.
  Usage: M602
gcode:
  RESUME

[gcode_macro m24]
rename_existing: M24.6245197
gcode:
  {% if printer.pause_resume.is_paused %}
  RESUME
  {% else %}
  M24.6245197
  {% endif %}

[gcode_macro m25]
rename_existing: M25.6245197
gcode:
  PAUSE

[gcode_macro resume]
description: Resumes the currently paused print.
  Usage: RESUME [E<pos>]
rename_existing: _KM_RESUME_BASE
variable_saved_extruder_temp: 0
variable_saved_x: 0.0
variable_saved_y: 0.0
variable_saved_z: 0.0
variable_saved_e: 0.0
gcode:
  {% if printer.pause_resume.is_paused %}
    {% set km = printer["gcode_macro _km_globals"] %}
    # Warm the extruder back up if needed.
    {% set extruder = printer[printer.toolhead.extruder] %}
    {% if extruder.target <= printer.configfile.settings[
                               printer.toolhead.extruder].min_temp
                             | float + 0.5 %}
      M109 S{saved_extruder_temp}
    {% endif %}

    # If there's no saved_e assume we're completing a filament change and
    # retract enough to avoid drooling on the model.
    {% if 'E' not in params and not saved_e %}
      {% set saved_e = 5.0 %}
      G1 E{'%.4f' % -saved_e } F{km.load_speed}
    {% endif %}

    SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_extruder_temp VALUE="{0}"
    G90
    # Move back to last position before unretracting.
    G0 X{saved_x} Y{saved_y} F{km.travel_speed_xy}
    G0 Z{saved_z} F{km.travel_speed_z}
    G91
    # Unretract
    G1 E{'%.4f' % (params.E|default(saved_e))} F{km.load_speed}
    RESTORE_GCODE_STATE NAME=_KM_PAUSE_OVERRIDE_STATE MOVE=1
    _KM_RESUME_BASE
  {% else %}
    { action_respond_info("Printer is not paused.") }
  {% endif %}

[gcode_macro cancel_print]
description: Cancels the current print.
  Usage: CANCEL_PRINT
rename_existing: _KM_CANCEL_PRINT_BASE
gcode:
  {% set was_paused = printer.pause_resume.is_paused %}
  {% if was_paused or printer.idle_timeout.state|string == "Printing" %}
    PRINT_END
    SDCARD_RESET_FILE
  {% else %}
    { action_respond_info("No print from SD card in progress.") }
  {% endif %}
  _KM_CANCEL_PRINT_BASE
  {% if was_paused %}
    RESTORE_GCODE_STATE NAME=_KM_PAUSE_OVERRIDE_STATE MOVE=0
  {% endif %}
  CLEAR_PAUSE

[gcode_macro clear_pause]
description: Clears the current pause state.
  Usage: CLEAR_PAUSE
rename_existing: _KM_CLEAR_PAUSE
gcode:
  SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_e VALUE="{0.0}"
  SET_GCODE_VARIABLE MACRO=resume VARIABLE=saved_extruder_temp VALUE="{0}"
  _KM_CLEAR_PAUSE
