/**
 * @file led_font.h
 * @brief Complete 8x8 font database for LED matrix display
 * @author TuyaOpen
 * @date 2024
 */

#ifndef LED_FONT_H
#define LED_FONT_H

#include <stdint.h>

// Font character structure
typedef struct {
    char ch;         // Character
    uint8_t data[8]; // 8x8 bitmap data (8 rows)
    uint8_t width;   // Character width (8 pixels)
} LED_FONT_CHAR_T;

// Complete 8x8 font database for LED matrix display
static const LED_FONT_CHAR_T LED_FONT[] = {
    // Space and punctuation
    {' ', {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8},
    {'!', {0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x18, 0x00}, 8},
    {'"', {0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00}, 8},
    {'#', {0x00, 0x36, 0x7F, 0x36, 0x36, 0x7F, 0x36, 0x00}, 8},
    {'$', {0x00, 0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18}, 8},
    {'%', {0x00, 0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06}, 8},
    {'&', {0x00, 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76}, 8},
    {'\'', {0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00}, 8},
    {'(', {0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00}, 8},
    {')', {0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00}, 8},
    {'*', {0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00}, 8},
    {'+', {0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00}, 8},
    {',', {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30}, 8},
    {'-', {0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}, 8},
    {'.', {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00}, 8},
    {'/', {0x00, 0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60}, 8},

    // Numbers 0-9
    {'0', {0x00, 0x3C, 0x66, 0x6E, 0x76, 0x66, 0x3C, 0x00}, 8},
    {'1', {0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7E, 0x00}, 8},
    {'2', {0x00, 0x3C, 0x66, 0x0C, 0x18, 0x30, 0x7E, 0x00}, 8},
    {'3', {0x00, 0x3C, 0x66, 0x0C, 0x06, 0x66, 0x3C, 0x00}, 8},
    {'4', {0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x00}, 8},
    {'5', {0x00, 0x7E, 0x60, 0x7C, 0x06, 0x66, 0x3C, 0x00}, 8},
    {'6', {0x00, 0x3C, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00}, 8},
    {'7', {0x00, 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x00}, 8},
    {'8', {0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00}, 8},
    {'9', {0x00, 0x3C, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00}, 8},

    // Uppercase letters A-Z
    {'A', {0x00, 0x18, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x00}, 8},
    {'B', {0x00, 0x7C, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00}, 8},
    {'C', {0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x00}, 8},
    {'D', {0x00, 0x78, 0x6C, 0x66, 0x66, 0x6C, 0x78, 0x00}, 8},
    {'E', {0x00, 0x7E, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00}, 8},
    {'F', {0x00, 0x7E, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00}, 8},
    {'G', {0x00, 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x3C, 0x00}, 8},
    {'H', {0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00}, 8},
    {'I', {0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, 8},
    {'J', {0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00}, 8},
    {'K', {0x00, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x00}, 8},
    {'L', {0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00}, 8},
    {'M', {0x00, 0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x00}, 8},
    {'N', {0x00, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63, 0x00}, 8},
    {'O', {0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, 8},
    {'P', {0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x00}, 8},
    {'Q', {0x00, 0x3C, 0x66, 0x66, 0x66, 0x6C, 0x36, 0x00}, 8},
    {'R', {0x00, 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x00}, 8},
    {'S', {0x00, 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x3C, 0x00}, 8},
    {'T', {0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, 8},
    {'U', {0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, 8},
    {'V', {0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00}, 8},
    {'W', {0x00, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, 8},
    {'X', {0x00, 0x66, 0x66, 0x3C, 0x3C, 0x66, 0x66, 0x00}, 8},
    {'Y', {0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00}, 8},
    {'Z', {0x00, 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00}, 8},

    // Lowercase letters a-z
    {'a', {0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00}, 8},
    {'b', {0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00}, 8},
    {'c', {0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00}, 8},
    {'d', {0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00}, 8},
    {'e', {0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00}, 8},
    {'f', {0x00, 0x0E, 0x18, 0x3E, 0x18, 0x18, 0x18, 0x00}, 8},
    {'g', {0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C}, 8},
    {'h', {0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00}, 8},
    {'i', {0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00}, 8},
    {'j', {0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x66, 0x3C}, 8},
    {'k', {0x00, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x66, 0x00}, 8},
    {'l', {0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, 8},
    {'m', {0x00, 0x00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, 8},
    {'n', {0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00}, 8},
    {'o', {0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00}, 8},
    {'p', {0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60}, 8},
    {'q', {0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06}, 8},
    {'r', {0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00}, 8},
    {'s', {0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00}, 8},
    {'t', {0x00, 0x18, 0x7E, 0x18, 0x18, 0x1A, 0x0C, 0x00}, 8},
    {'u', {0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00}, 8},
    {'v', {0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00}, 8},
    {'w', {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, 8},
    {'x', {0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00}, 8},
    {'y', {0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C}, 8},
    {'z', {0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00}, 8},

    // Additional symbols
    {':', {0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00}, 8},
    {';', {0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30}, 8},
    {'<', {0x00, 0x00, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x00}, 8},
    {'=', {0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00}, 8},
    {'>', {0x00, 0x00, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x00}, 8},
    {'?', {0x00, 0x3C, 0x66, 0x0C, 0x18, 0x00, 0x18, 0x00}, 8},
    {'@', {0x00, 0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C}, 8},
    {'[', {0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00}, 8},
    {'\\', {0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00}, 8},
    {']', {0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00}, 8},
    {'^', {0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00}, 8},
    {'_', {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00}, 8},
    {'`', {0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00}, 8},
    {'{', {0x00, 0x0E, 0x18, 0x7C, 0x18, 0x18, 0x0E, 0x00}, 8},
    {'|', {0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, 8},
    {'}', {0x00, 0x70, 0x18, 0x1E, 0x18, 0x18, 0x70, 0x00}, 8},
    {'~', {0x00, 0x00, 0x00, 0x3B, 0x6E, 0x00, 0x00, 0x00}, 8},
};

// Font utility functions
static inline const LED_FONT_CHAR_T *get_font_char(char ch)
{
    for (int i = 0; i < sizeof(LED_FONT) / sizeof(LED_FONT[0]); i++) {
        if (LED_FONT[i].ch == ch) {
            return &LED_FONT[i];
        }
    }
    return &LED_FONT[0]; // Return space if not found
}

static inline uint32_t calculate_text_width(const char *text)
{
    uint32_t width = 0;
    for (const char *p = text; *p; p++) {
        char ch = (*p >= 'a' && *p <= 'z') ? (*p - 'a' + 'A') : *p;
        const LED_FONT_CHAR_T *font_char = get_font_char(ch);
        width += font_char->width; // character width (no spacing)
    }
    return width;
}

#endif // LED_FONT_H
