#ifndef TDECK_DISPLAY_H
#define TDECK_DISPLAY_H

// ============================================================================
// tdeck_display.h — U8g2-shaped adapter over the T-Deck's ST7789 panel.
//
// WHY AN ADAPTER RATHER THAN A SECOND UI
// --------------------------------------
// main.cpp draws two screens (boot + periodic status) across ~24 U8g2 calls.
// The obvious plan was to keep U8g2 and just swap the constructor, since U8g2
// drives dozens of controllers — but the pinned U8g2 (2.35.30) contains NO
// ST7789 support whatsoever (verified: zero matches for "ST7789" in
// U8g2lib.h; the compiler's nearest suggestion was IST3088). So the T-Deck
// panel needs Adafruit_ST7789.
//
// Forking the 24 call sites would mean two copies of the same layout drifting
// apart. Instead this class exposes the handful of U8g2 methods main.cpp
// actually uses, implemented over Adafruit_GFX. Every existing drawStr /
// drawHLine / sendBuffer line compiles unchanged on both boards, and there is
// still exactly one screen layout to maintain.
//
// COORDINATE SCALING
// ------------------
// The layout was authored for a 128x64 OLED. This panel is 320x240. Rather
// than re-lay-out (and diverge), coordinates are scaled 2x and text is drawn
// at size 2, giving a 256x128 used area on a 320x240 screen — legible and
// faithful to the original arrangement. Refining the layout to use the full
// panel is a deliberate follow-up, not an oversight.
//
// U8g2 uses a BASELINE y for drawStr; Adafruit_GFX uses a TOP-LEFT cursor.
// drawStr() compensates so the existing y values land where they visually did
// before, instead of one text-height too low.
// ============================================================================

#ifdef PDL_BOARD_TDECK

#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <U8g2lib.h>   // only for the two font symbols main.cpp passes in
#include "config.h"

class TDeckDisplay {
public:
    TDeckDisplay() : m_tft(nullptr), m_scale(2), m_char_h(8) {}

    // Bind to the SHARED SPI bus (the same instance the SX1262 uses — the two
    // are arbitrated by their separate CS lines, LoRa on GPIO9 and the panel
    // on GPIO12). Must be called after that bus has been begun.
    void attach(SPIClass* spi) {
        if (m_tft) return;
        m_tft = new Adafruit_ST7789(spi, TDECK_TFT_CS, TDECK_TFT_DC, -1);
    }

    void begin() {
        if (!m_tft) return;
        m_tft->init(240, 320);       // panel native portrait
        // Rotation 3, not 1. Both are landscape 320x240, but they differ by
        // 180 degrees — and on the T-Deck chassis rotation 1 renders the image
        // upside down relative to the keyboard (confirmed on both physical
        // units 2026-08-02). 3 puts the top of the screen away from the user.
        m_tft->setRotation(3);
        m_tft->fillScreen(ST77XX_BLACK);
        m_tft->setTextColor(ST77XX_WHITE, ST77XX_BLACK);
        m_tft->setTextSize(m_scale);
        m_tft->setTextWrap(false);
    }

    // U8g2 parity: buffered API. Adafruit_GFX draws immediately, so
    // clearBuffer() clears the panel and sendBuffer() is a no-op. Kept so the
    // call sites stay identical.
    void clearBuffer() { if (m_tft) m_tft->fillScreen(ST77XX_BLACK); }
    void sendBuffer()  { /* immediate-mode: nothing to flush */ }

    // Only two fonts are used by the layout. Rather than port U8g2 font data,
    // map them onto GFX text sizes: the bold 7x13 heading font becomes size 3,
    // the 6x10 body font size 2.
    void setFont(const uint8_t* font) {
        if (!m_tft) return;
        // Distinguish by pointer identity against the two fonts main.cpp uses.
        // Any unrecognised font falls back to body size.
        m_scale  = (font == u8g2_font_7x13B_tr) ? 3 : 2;
        m_char_h = 8 * m_scale;
        m_tft->setTextSize(m_scale);
    }

    void drawStr(int16_t x, int16_t y, const char* s) {
        if (!m_tft || !s) return;
        // U8g2 y = text baseline; GFX y = top of glyph cell.
        int16_t top = (int16_t)(y * 2) - m_char_h;
        if (top < 0) top = 0;
        m_tft->setCursor((int16_t)(x * 2), top);
        m_tft->print(s);
    }

    void drawHLine(int16_t x, int16_t y, int16_t w) {
        if (!m_tft) return;
        m_tft->drawFastHLine((int16_t)(x * 2), (int16_t)(y * 2),
                             (int16_t)(w * 2), ST77XX_WHITE);
    }

    // Present for API parity with the SSD1306 path; the ST7789 has no
    // equivalent software contrast register. Backlight is a GPIO (see main.cpp).
    void setContrast(uint8_t) {}

private:
    Adafruit_ST7789* m_tft;
    uint8_t          m_scale;
    int16_t          m_char_h;
};

#endif // PDL_BOARD_TDECK
#endif // TDECK_DISPLAY_H
