using System;
using System.ComponentModel;
using System.Drawing;
using System.Net;
using System.Runtime.Caching;

namespace Azyobuzi.Twirunrun
{
    public static class Icons
    {
        public static MemoryCache Cache = MemoryCache.Default;

        public static void Add(string iconUri, Image img)//URIで管理する
        {
            Cache.Add(
                new CacheItem(iconUri, img),
                new CacheItemPolicy()
                {
                    SlidingExpiration = TimeSpan.FromMinutes(20d),
                    RemovedCallback = args => ((IDisposable)args.CacheItem.Value).Dispose()
                }
            );
        }

        public static Image GetItem(string key)
        {
            return Cache[key] as Image;
        }

        public readonly static object LockObj = new object();



        public static void AddAsync(string uri)
        {
            RunnningCount++;
            var bw = new BackgroundWorker();
            bw.DoWork += (sender, e) =>
            {
                try
                {
                    var result = CreateIcon(uri);
                    lock (LockObj)
                    {
                        Icons.Add(uri, result);
                    }
                }
                catch { }
            };
            bw.RunWorkerCompleted += (sender, e) =>
            {
                RunnningCount--;
                if (RunnningCount <= 0)
                {
                    AddCompleted();
                }
            };
            bw.RunWorkerAsync();
        }

        private static int RunnningCount = 0;

        /// <summary>
        /// AddAsyncですべての処理が終わったときに呼び出されます。
        /// </summary>
        public static Action AddCompleted { set; get; }



        /// <summary>
        /// 指定したURIからアイコンを作成する
        /// </summary>
        public static Bitmap CreateIcon(string uri)
        {
            const int RESULT_SIZE = 48;

            Image img;

            using (var wc = new WebClient())
            {
                img = wc.DownloadImage(uri);
            }

            if (img.Width == img.Height)
                return new Bitmap(img, RESULT_SIZE, RESULT_SIZE);

            int size = Math.Min(img.Width, img.Height);
            using (Bitmap temp = new Bitmap(size, size))
            {
                if (img.Width > img.Height)
                {
                    int left = img.Width / 2 - ((/*img.Width - */img.Height) / 2);
                    using (var g = Graphics.FromImage(temp))
                    {
                        g.DrawImage(img, 0, 0, new Rectangle(left, 0, size, size), GraphicsUnit.Pixel);
                    }
                }
                else if (img.Width < img.Height)
                {
                    int top = img.Height / 2 - ((/*img.Height - */img.Width) / 2);
                    using (var g = Graphics.FromImage(temp))
                    {
                        g.DrawImage(img, 0, 0, new Rectangle(0, top, size, size), GraphicsUnit.Pixel);
                    }
                }

                return new Bitmap(temp, RESULT_SIZE, RESULT_SIZE);
            }
        }
    }
}
