#pragma once
#include <Arduino.h>

// ── Wersja firmware ──────────────────────────────────────────────────────────
#define FIRMWARE_VERSION "1.0"
#define FIRMWARE_AUTHOR  "Leszek Klich"

// ── Pole robocze (A4 poziomo) ─────────────────────────────────────────────────
constexpr float WORKSPACE_WIDTH_MM   = 297.0f;
constexpr float WORKSPACE_HEIGHT_MM  = 210.0f;

// ── Ruch / silniki krokowe ───────────────────────────────────────────────────
// DRV8825 z 1/16 mikrostepowaniem (MS1=0, MS2=0, MS3=1): 200*16 / (20T*2mm) = 80 krok/mm
constexpr float STEPS_PER_MM_X      = 80.0f;
constexpr float STEPS_PER_MM_Y      = 80.0f;

constexpr float SPEED_DEFAULT_MM_S  = 60.0f;
constexpr float SPEED_MIN_MM_S      = 10.0f;
constexpr float SPEED_MAX_MM_S      = 150.0f;
constexpr float ACCEL_MM_S2         = 500.0f;

// ── Homing ───────────────────────────────────────────────────────────────────
// Krańcówki wyzwalają się gdy głowica jest w PRAWYM GÓRNYM rogu KARTKI.
// W układzie pola roboczego to jest pozycja (0,0) = lewy górny róg rysowania.
// Po homingu: (0,0) = pozycja domowa, X rośnie w prawo, Y rośnie w dół.
//
// HOMING_DIR: kierunek jazdy do krańcówek (+1 = dodatni krok AccelSteppera).
// Wartość domyślna +1 oznacza że dodatni kierunek silnika jedzie ku krańcówce.
// Jeśli silnik kręci się w złą stronę: zmień na -1 lub zamień kabel DIR.
constexpr int8_t HOMING_DIR_X       = +1;
constexpr int8_t HOMING_DIR_Y       = +1;
constexpr float  HOMING_SPEED_MM_S  = 20.0f;
constexpr float  HOMING_BACKOFF_MM  = 2.0f;  // cofnięcie po wyzwoleniu [mm]

// Mnożnik prędkości zmieniany przyciskami podczas drukowania
constexpr float SPEED_MULT_MIN      = 0.5f;
constexpr float SPEED_MULT_MAX      = 2.0f;
constexpr float SPEED_MULT_STEP     = 0.1f;
constexpr float SPEED_MULT_DEFAULT  = 1.0f;

// ── Servo / pisak ────────────────────────────────────────────────────────────
constexpr int   SERVO_ANGLE_UP      = 90;   // pisak uniesiony
constexpr int   SERVO_ANGLE_DOWN    = 50;   // pisak na papierze (nacisk)
constexpr int   SERVO_SETTLE_MS     = 150;  // czas opadnięcia serwa [ms]

// ── Piny GPIO ────────────────────────────────────────────────────────────────
constexpr uint8_t PIN_X_STEP        = 26;
constexpr uint8_t PIN_X_DIR         = 27;
constexpr uint8_t PIN_Y_STEP        = 14;
constexpr uint8_t PIN_Y_DIR         = 15;   // GPIO15 — bezpieczny zamiennik (GPIO16 niedostępny)
constexpr uint8_t PIN_STEPPER_EN    = 13;   // aktywny LOW

// Wyłączniki krańcowe (INPUT_PULLUP, aktywny LOW — wyzwolony = LOW)
// MIN = pozycja domowa (0,0), używany podczas homingu
// MAX = koniec pola roboczego, tylko zabezpieczenie przed najazdem
constexpr uint8_t PIN_LIMIT_X_MIN   = 36;   // tylko wejście — prawa strona = dom X (VP)
constexpr uint8_t PIN_LIMIT_X_MAX   = 34;   // tylko wejście — lewa strona = koniec X
constexpr uint8_t PIN_LIMIT_Y_MIN   = 39;   // tylko wejście — strona domowa osi Y (VN)
constexpr uint8_t PIN_LIMIT_Y_MAX   = 35;   // tylko wejście — koniec osi Y

constexpr uint8_t PIN_SERVO         = 25;

constexpr uint8_t PIN_SD_CS         = 5;    // SPI CS (MOSI=23, MISO=19, SCK=18)

// Przyciski podciągnięte do VCC (INPUT_PULLUP), aktywne LOW
constexpr uint8_t PIN_BTN_UP        = 32;
constexpr uint8_t PIN_BTN_DOWN      = 33;
constexpr uint8_t PIN_BTN_OK        = 4;

// ── OLED SH1106 1.3" 128x64 I2C ─────────────────────────────────────────────
// SDA=21, SCL=22 (domyślne Wire dla ESP32)
constexpr uint8_t OLED_I2C_ADDR      = 0x3C;  // alternatywnie 0x3D
constexpr uint8_t OLED_W             = 128;
constexpr uint8_t OLED_H             = 64;
constexpr uint8_t DISPLAY_LINE_CHARS = 21;    // max znaków w linii (font 6x10)

// ── Karta SD ─────────────────────────────────────────────────────────────────
constexpr uint8_t  SD_MAX_FILES     = 20;
constexpr uint8_t  FILENAME_MAX_LEN = 64;

// ── Timery UI ────────────────────────────────────────────────────────────────
constexpr uint32_t DISPLAY_UPDATE_MS  = 200;
constexpr uint32_t BUTTON_DEBOUNCE_MS = 50;
constexpr uint32_t BOOT_HOLD_MS            = 2000;
constexpr uint32_t STEPPER_IDLE_TIMEOUT_MS = 5000; // auto-wyłączenie silników po bezczynności [ms], 0=wyłącz

// ── Stany aplikacji ───────────────────────────────────────────────────────────
enum class AppState : uint8_t {
    MAIN_MENU,
    FILE_LIST,
    PRINTING,
    CONFIRM_STOP,
    UART_MODE,
    AXIS_TEST,
    ERROR
};

constexpr float TEST_STEP_MM   = 1.0f;   // krok na jedno naciśnięcie w trybie testowym [mm]
constexpr float TEST_SPEED_MM_S = 5.0f;  // prędkość w trybie testowym [mm/s]

// ── Komendy GCode ────────────────────────────────────────────────────────────
enum class GCodeCmd : uint8_t {
    NONE,
    G0,
    G1,
    G28,
    M3,
    M5,
    UNKNOWN
};

struct GCodeLine {
    GCodeCmd cmd;
    bool     hasX, hasY, hasF;
    float    x, y;
    float    f;  // feedrate w mm/min
};

// ── Status drukowania ─────────────────────────────────────────────────────────
struct PrintStatus {
    char     filename[FILENAME_MAX_LEN];
    uint32_t totalLines;
    uint32_t currentLine;
    float    speedMultiplier;
    bool     isPrinting;
};
