using HMUI;
using IllusionPlugin;
using SimpleJSON;
using System;
using System.Text.RegularExpressions;
using UnityEngine;


namespace SongBrowserPlugin.UI
{
    class Base64Sprites
    {
        // https://www.iconfinder.com/icons/17236/folder_icon
        public static string FolderIcon = "data:image/png;base64,[encoded data, 21280 characters]";

        // https://www.iconfinder.com/icons/103857/find_glass_magnifying_search_icon
        public static string SearchIcon = "data:image/png;base64,[encoded data, 4856 characters]";

        // https://icons8.com/icon/24520/playlist
        public static string PlaylistIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAPtSURBVHhe7dzLa9RQFAbwLgQXihvdaC2CCG5c6STjYzE28dGF+le40oKu3AndunYhPnDhWqzFRylMC8W2/4KKG10qBe0kU5Ha1nviN3EqZx7J5GZC+H7wYe3J3Nx70slkMtURIiIiIiIiIiIiIiIiIhIvF5a3yxwsMxZ6br15vlrFX4dPm3SZgmXGQt/dDnx3K/Ccl8HFygl8e3i0SZcpWGZMDkArgeduBr7z7KdfOYpy/rRJlylYZqz9ALQdiF/mWfEgvHzyIDYjW7QD0Ip5Nqyb3Fvznf3YnLKmNV7J99B37n6t1fbiYZQVpdmd47nfzOnp9tbEsd14OA1KbXSPmIPwJfSc69u12i4MQ2lpDU6QDxiG0lKamigYhtLSmpokGIbS0pqaJBiG0tKamiQYhtLSmhrFc++YrKq1tmCY7Ghv38sULDOmNVUitdUJd595JzxlLjnXtG0k0SBZ0iZdpmCZMa2pEpQjjdqpA3JLQm5NdNsuE9qkyxQsM/Z/Q1tBeQe5ORf6zn25Wddtu4Foky5TsMxYe9Pbg7JqffzMEfNseGqygW9RWlrzJSh3tTZeOY4vKS2t+RKUyTat+RKUyTat+RKUyTat+RKUyTat+RKUyTat+RKUyTat+RKUyTat+RKUyTat+RKU86e9fS9TsMyY1nwJyvnTJl2mYJkxrfkSlPOnTbpMwTJjWvMlKOdPm3SZgmXGtOZLUCbbtOZLUCbbtOZLUCbbtOZLUCbbtOZLUKY0mjX3cOC5kyazoee+N3+GEnw9a3JTtpFtteZLooEomeaFs4cC33kin9VqTW2PbBP47mOtJsGQ1K/mePVa6DuB1sw0wbDUj8Cr3jKnlU2tkWmDoakX+cnPuvkSDE/dNL3To+a009AaOGiwi/xpb9+LkOmFpebc3NweTDMiL7ha87IIdpE/bfGFyPzyc0wxsn6pMhZ4zm+teVkEu8mfuvgCZKb+bhJTjJjz/qTWuKyC3eRPW3wRMrOwcg5TjJjTzxutcVkFu6FOzLvaj1rjsgp2Q53YuvppBbuhTuweAKeB3VAnVk9BZmzshjqx+SJsLm9fYzfUic3L0IZfuYHdUCfRG7E+bjsnjYzZ+qyAeuh2Pz9tzDPrEYanXuQDmG7/hjdxPPcH/5uyhP7ejh78npCM0fQqVzHs8Gi3AYqU6fnlKUw1NugHMvJYGQPDDZe26CLFHICNF/UVF9ONRR9JpjkdRY9xrmCY4dMWXbwsfZ5eXBzDlGNy/pYX5n6ujmQbc9p5WLhzvr7g4mV6funTq/rKKKa9g1xGyrW8ORhv8aso/34txXxParzUJCIiIiIiIiIiIiIiIsrOyMgfUAEg+sZSgwsAAAAASUVORK5CYII=";

        // https://github.com/andruzzzhka/BeatSaverDownloader/blob/master/BeatSaverDownloader/Misc/Base64Sprites.cs
        public static string AddToFavoritesIcon = "data:image/png;base64,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";
        public static string RemoveFromFavoritesIcon = "data:image/png;base64,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";

        public static Sprite Base64ToSprite(string base64)
        {
            // prune base64 encoded image header
            Regex r = new Regex(@"data:image.*base64,");
            base64 = r.Replace(base64, "");            

            Sprite s = null;
            try
            {
                Texture2D tex = Base64ToTexture2D(base64);
                s = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), (Vector2.one / 2f));
            }
            catch (Exception)
            {
                Console.WriteLine("Exception loading texture from base64 data.");
                s = null;
            }

            return s;
        }

        public static Texture2D Base64ToTexture2D(string encodedData)
        {
            byte[] imageData = Convert.FromBase64String(encodedData);

            int width, height;
            GetImageSize(imageData, out width, out height);

            Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false, true);
            texture.hideFlags = HideFlags.HideAndDontSave;
            texture.filterMode = FilterMode.Trilinear;
            texture.LoadImage(imageData);
            return texture;
        }

        private static void GetImageSize(byte[] imageData, out int width, out int height)
        {
            width = ReadInt(imageData, 3 + 15);
            height = ReadInt(imageData, 3 + 15 + 2 + 2);
        }

        private static int ReadInt(byte[] imageData, int offset)
        {
            return (imageData[offset] << 8) | imageData[offset + 1];
        }
    }
}
