using System;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu]
public sealed class PixelFontConfig : ScriptableObject {
    [System.Serializable]
    public sealed class Glypt {
        public string symbols;
        public Rect rect;
        public Glypt(Rect rect, string symbols = "") {
            this.symbols = symbols;
            this.rect = rect;
        }
    }
    [SerializeField] private Material fontMaterial = null; // Set from editor
    [SerializeField] private List<Glypt> glyptsInfo = new List<Glypt>(); // Set from editor or generate

    private readonly Rect EmptyRect = new Rect(0, 0, 0, 0);
    private Dictionary<char, Rect> cache = null;

    public Rect GetRect(char symbol) {
        if (cache == null) {
            cache = GenerateCache(glyptsInfo);
        }
        if (cache.ContainsKey(symbol)) {
            return cache[symbol];
        }
        return EmptyRect;
    }

    public bool ContainsSymbol(char symbol) {
        if (cache == null) {
            cache = GenerateCache(glyptsInfo);
        }
        return cache.ContainsKey(symbol);
    }

    public Material GetMaterial() {
        return fontMaterial;
    }

    private Dictionary<char, Rect> GenerateCache(List<Glypt> glyptsInfo) {
        var cache = new Dictionary<char, Rect>();
        foreach (var glypt in glyptsInfo) {
            if (!string.IsNullOrEmpty(glypt.symbols)) {
                foreach (char symbol in glypt.symbols) {
                    cache.Add(symbol, glypt.rect);
                }
            }
        }
        return cache;
    }

    #if UNITY_EDITOR
    [SerializeField] private List<string> symbolsForId = new List<string>(); // Set from editor or generate
    [ContextMenu("Generate Font Data")]
    private void GenerateFontData() {
        glyptsInfo = new List<Glypt>();
        const int rowCount = 8;
        const int columnCount = 16;
        Vector2 size = new Vector2(1f / (float)rowCount, 1f / (float)columnCount);
        for (int i = 0; i < rowCount; i++) {
            for (int j = 0; j < columnCount; j++) {
                int id = i + j * rowCount;
                string symbols = string.Empty;
                if (symbolsForId.Count > id) {
                    symbols = symbolsForId[id];
                }
                glyptsInfo.Add(new Glypt(new Rect(i * size.x, 1f - (j + 1) * size.y, size.x, size.y), symbols));
            }
        }
    }
    #endif
}