using Minint.Core.Models;

namespace Minint.Core.Services.Impl;

public sealed class PaletteService : IPaletteService
{
    public int FindColor(MinintDocument document, RgbaColor color)
        => document.FindColorCached(color);

    public int EnsureColor(MinintDocument document, RgbaColor color)
        => document.EnsureColorCached(color);

    public void CompactPalette(MinintDocument document)
    {
        var palette = document.Palette;
        if (palette.Count <= 1)
            return;

        var usedIndices = new HashSet<int> { 0 };
        foreach (var layer in document.Layers)
        {
            foreach (int idx in layer.Pixels)
                usedIndices.Add(idx);
        }

        var oldToNew = new int[palette.Count];
        var newPalette = new List<RgbaColor>(usedIndices.Count);

        newPalette.Add(palette[0]);
        oldToNew[0] = 0;

        for (int i = 1; i < palette.Count; i++)
        {
            if (usedIndices.Contains(i))
            {
                oldToNew[i] = newPalette.Count;
                newPalette.Add(palette[i]);
            }
        }

        if (newPalette.Count == palette.Count)
            return;

        palette.Clear();
        palette.AddRange(newPalette);

        foreach (var layer in document.Layers)
        {
            var px = layer.Pixels;
            for (int i = 0; i < px.Length; i++)
                px[i] = oldToNew[px[i]];
        }

        document.InvalidatePaletteCache();
    }
}
