#pragma once

// Freenove Media Kit reference profile (Sketch_19):
// - FNK0102H ST7796 320x480 by default, rotation 1
// - Buttons via analog ladder on GPIO19
// - I2S output BCLK=42, WS=41, DOUT=1

#ifndef FREENOVE_LCD_VARIANT_FNK0102A
#define FREENOVE_LCD_VARIANT_FNK0102A 0
#endif

#ifndef FREENOVE_LCD_VARIANT_FNK0102B
#define FREENOVE_LCD_VARIANT_FNK0102B 0
#endif

#ifndef FREENOVE_LCD_VARIANT_FNK0102H
#define FREENOVE_LCD_VARIANT_FNK0102H 1
#endif

#if (FREENOVE_LCD_VARIANT_FNK0102A + FREENOVE_LCD_VARIANT_FNK0102B + FREENOVE_LCD_VARIANT_FNK0102H) > 1
#error "Select one LCD variant only (FNK0102A/FNK0102B/FNK0102H)."
#endif

#if !FREENOVE_LCD_VARIANT_FNK0102A && !FREENOVE_LCD_VARIANT_FNK0102B && !FREENOVE_LCD_VARIANT_FNK0102H
#error "At least one LCD variant must be enabled."
#endif

// Master switch for LVGL draw buffers in PSRAM.
// Keep legacy macro for backward compatibility with existing build flags.
#if defined(FREENOVE_PSRAM_UI_DRAW_BUFFER) && !defined(UI_DRAW_BUF_IN_PSRAM)
#define UI_DRAW_BUF_IN_PSRAM FREENOVE_PSRAM_UI_DRAW_BUFFER
#endif

#ifndef UI_DRAW_BUF_IN_PSRAM
#define UI_DRAW_BUF_IN_PSRAM 1
#endif

#ifndef FREENOVE_PSRAM_UI_DRAW_BUFFER
#define FREENOVE_PSRAM_UI_DRAW_BUFFER UI_DRAW_BUF_IN_PSRAM
#endif

// Optional policy toggles for other large buffers.
#ifndef UI_AUDIO_RINGBUF_IN_PSRAM
#define UI_AUDIO_RINGBUF_IN_PSRAM 1
#endif

#if defined(FREENOVE_PSRAM_CAMERA_FRAMEBUFFER) && !defined(UI_CAMERA_FB_IN_PSRAM)
#define UI_CAMERA_FB_IN_PSRAM FREENOVE_PSRAM_CAMERA_FRAMEBUFFER
#endif

#ifndef UI_CAMERA_FB_IN_PSRAM
#define UI_CAMERA_FB_IN_PSRAM 1
#endif

#ifndef FREENOVE_PSRAM_CAMERA_FRAMEBUFFER
#define FREENOVE_PSRAM_CAMERA_FRAMEBUFFER UI_CAMERA_FB_IN_PSRAM
#endif

// SPI TX DMA staging buffers should stay in internal DRAM.
#ifndef UI_DMA_TX_IN_DRAM
#define UI_DMA_TX_IN_DRAM 1
#endif

#define UI_LCD_SPI_HOST 1
#define UI_SERIAL_BAUD 57600
#define UI_ROTATION 1

#if FREENOVE_LCD_VARIANT_FNK0102A
#define FREENOVE_LCD_LABEL "FNK0102A_ST7789_135x240"
#define FREENOVE_LCD_WIDTH 135
#define FREENOVE_LCD_HEIGHT 240
#define ST7789_DRIVER
#define TFT_WIDTH 135
#define TFT_HEIGHT 240
#define TFT_SDA_READ
#define TFT_INVERSION_ON
#elif FREENOVE_LCD_VARIANT_FNK0102H
#define FREENOVE_LCD_LABEL "FNK0102H_ST7796_320x480"
#define FREENOVE_LCD_WIDTH 320
#define FREENOVE_LCD_HEIGHT 480
#define ST7796_DRIVER
#define TFT_INVERSION_ON
#else
#define FREENOVE_LCD_LABEL "FNK0102B_ST7796_320x480"
#define FREENOVE_LCD_WIDTH 320
#define FREENOVE_LCD_HEIGHT 480
#define ST7796_DRIVER
#define TFT_INVERSION_ON
#endif

#define FREENOVE_LCD_ROTATION 1

// TFT SPI pins (official Freenove setup).
#define FREENOVE_TFT_SCK 47
#define FREENOVE_TFT_MOSI 21
#define FREENOVE_TFT_MISO -1
#define FREENOVE_TFT_CS -1
#define FREENOVE_TFT_DC 45
#define FREENOVE_TFT_RST 20
#define FREENOVE_TFT_BL 2

// TFT_eSPI bridge defines.
#define USER_SETUP_LOADED 1
#define TFT_MOSI FREENOVE_TFT_MOSI
#define TFT_SCLK FREENOVE_TFT_SCK
#define TFT_MISO FREENOVE_TFT_MISO
#define TFT_CS FREENOVE_TFT_CS
#define TFT_DC FREENOVE_TFT_DC
#define TFT_RST FREENOVE_TFT_RST
#define TFT_BL FREENOVE_TFT_BL
#define TFT_BACKLIGHT_ON HIGH
#define SPI_FREQUENCY 80000000
#define SPI_READ_FREQUENCY 20000000
#ifndef SUPPORT_TRANSACTIONS
#define SUPPORT_TRANSACTIONS
#endif
#ifndef FREENOVE_LCD_USE_HSPI
#define FREENOVE_LCD_USE_HSPI 0
#endif
#if FREENOVE_LCD_USE_HSPI
#define USE_HSPI_PORT
#else
#define USE_FSPI_PORT
#endif

// Buttons: analog ladder by default (5 keys).
#define FREENOVE_BTN_ANALOG_PIN 19
#define FREENOVE_BTN_1 -1
#define FREENOVE_BTN_2 -1
#define FREENOVE_BTN_3 -1
#define FREENOVE_BTN_4 -1
#define FREENOVE_BTN_LONG_PRESS_MS 700

#ifndef FREENOVE_HAS_TOUCH
#define FREENOVE_HAS_TOUCH 0
#endif

#if FREENOVE_HAS_TOUCH
#define FREENOVE_TOUCH_CS 9
#define FREENOVE_TOUCH_IRQ 15
#define SPI_TOUCH_FREQUENCY 2500000
#define TOUCH_CS FREENOVE_TOUCH_CS
#else
#define TOUCH_CS -1
#endif

// Storage and audio buses from Freenove reference.
#define FREENOVE_SDMMC_CMD 38
#define FREENOVE_SDMMC_CLK 39
#define FREENOVE_SDMMC_D0 40
#define FREENOVE_I2S_WS 41
#define FREENOVE_I2S_BCK 42
#define FREENOVE_I2S_DOUT 1
#define FREENOVE_I2S_IN_SCK 3
#define FREENOVE_I2S_IN_WS 14
#define FREENOVE_I2S_IN_DIN 46

// Audio output behavior tuning (embedded audio manager knobs).
#ifndef FREENOVE_AUDIO_MAX_VOLUME
#define FREENOVE_AUDIO_MAX_VOLUME 21U
#endif

#ifndef FREENOVE_AUDIO_VOLUME_RAMP_MS
#define FREENOVE_AUDIO_VOLUME_RAMP_MS 140U
#endif

#ifndef FREENOVE_AUDIO_START_TIMEOUT_MS
#define FREENOVE_AUDIO_START_TIMEOUT_MS 2200U
#endif

#ifndef FREENOVE_AUDIO_STALL_TIMEOUT_MS
#define FREENOVE_AUDIO_STALL_TIMEOUT_MS 8000U
#endif

#ifndef FREENOVE_AUDIO_RETRY_MAX
#define FREENOVE_AUDIO_RETRY_MAX 1U
#endif

#ifndef FREENOVE_AUDIO_RETRY_DELAY_MS
#define FREENOVE_AUDIO_RETRY_DELAY_MS 800U
#endif

// WS2812 + battery defaults for Freenove ESP32-S3.
#ifndef FREENOVE_WS2812_PIN
#define FREENOVE_WS2812_PIN 48
#endif

#ifndef FREENOVE_WS2812_COUNT
#if FREENOVE_LCD_VARIANT_FNK0102H
#define FREENOVE_WS2812_COUNT 4
#else
#define FREENOVE_WS2812_COUNT 4
#endif
#endif

#ifndef FREENOVE_WS2812_BRIGHTNESS
#define FREENOVE_WS2812_BRIGHTNESS 36
#endif

#ifndef FREENOVE_BAT_ADC_PIN
#define FREENOVE_BAT_ADC_PIN 20
#endif

#ifndef FREENOVE_BAT_VOLT_MULTIPLIER
#define FREENOVE_BAT_VOLT_MULTIPLIER 2.5f
#endif

#ifndef FREENOVE_BAT_VOLT_OFFSET_MV
#define FREENOVE_BAT_VOLT_OFFSET_MV -3300.0f
#endif

#ifndef FREENOVE_BAT_VOLTAGE_MIN
#define FREENOVE_BAT_VOLTAGE_MIN 3.20f
#endif

#ifndef FREENOVE_BAT_VOLTAGE_MAX
#define FREENOVE_BAT_VOLTAGE_MAX 4.20f
#endif

#ifndef FREENOVE_BAT_CHARGE_PIN
#define FREENOVE_BAT_CHARGE_PIN -1
#endif

// Camera wiring from Freenove FNK0102 (ESP32S3_EYE profile).
#ifndef FREENOVE_CAM_ENABLE
#define FREENOVE_CAM_ENABLE 1
#endif

#ifndef FREENOVE_CAM_XCLK
#define FREENOVE_CAM_XCLK 15
#endif

#ifndef FREENOVE_CAM_SIOD
#define FREENOVE_CAM_SIOD 4
#endif

#ifndef FREENOVE_CAM_SIOC
#define FREENOVE_CAM_SIOC 5
#endif

#ifndef FREENOVE_CAM_Y2
#define FREENOVE_CAM_Y2 11
#endif

#ifndef FREENOVE_CAM_Y3
#define FREENOVE_CAM_Y3 9
#endif

#ifndef FREENOVE_CAM_Y4
#define FREENOVE_CAM_Y4 8
#endif

#ifndef FREENOVE_CAM_Y5
#define FREENOVE_CAM_Y5 10
#endif

#ifndef FREENOVE_CAM_Y6
#define FREENOVE_CAM_Y6 12
#endif

#ifndef FREENOVE_CAM_Y7
#define FREENOVE_CAM_Y7 18
#endif

#ifndef FREENOVE_CAM_Y8
#define FREENOVE_CAM_Y8 17
#endif

#ifndef FREENOVE_CAM_Y9
#define FREENOVE_CAM_Y9 16
#endif

#ifndef FREENOVE_CAM_VSYNC
#define FREENOVE_CAM_VSYNC 6
#endif

#ifndef FREENOVE_CAM_HREF
#define FREENOVE_CAM_HREF 7
#endif

#ifndef FREENOVE_CAM_PCLK
#define FREENOVE_CAM_PCLK 13
#endif

#ifndef FREENOVE_CAM_PWDN
#define FREENOVE_CAM_PWDN -1
#endif

#ifndef FREENOVE_CAM_RESET
#define FREENOVE_CAM_RESET -1
#endif
