using System;
using System.IO;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using System.Xml.Linq;
using Windows.Graphics.Imaging;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace PCUT.Extensions
{
    public static class ImageSourceExtensions
    {
        public static async Task LoadStreamAsync(this ImageSource source, IRandomAccessStream data)
        {
            switch (source)
            {
                case SvgImageSource svgSource:
                    {
                        await svgSource.SetSourceAsync(data);
                        break;
                    }
                case BitmapSource bitmapSource:
                    {
                        await bitmapSource.SetSourceAsync(data);
                        break;
                    }
                default:
                    return;
            }
        }

        public static async Task LoadSvgAsync(this ImageSource source, XDocument svg)
        {
            if (source is SvgImageSource svgSource)
            {
                using (var stream = new MemoryStream())
                {
                    await svg.SaveAsync(stream, SaveOptions.None, default);
                    stream.Seek(0, SeekOrigin.Begin);
                    await svgSource.SetSourceAsync(stream.AsRandomAccessStream());
                }
            }
        }

        public static async Task<IRandomAccessStream> CreateThumbnailAsync(this Image image)
        {
            var stream = new InMemoryRandomAccessStream();
            var bitmap = new RenderTargetBitmap();
            await bitmap.RenderAsync(image);
            var pixelBuffer = await bitmap.GetPixelsAsync();
            var sb = SoftwareBitmap.CreateCopyFromBuffer(pixelBuffer, BitmapPixelFormat.Bgra8, bitmap.PixelWidth, bitmap.PixelHeight);
            try
            {
                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
                encoder.SetSoftwareBitmap(sb);
                var scale = bitmap.PixelHeight > bitmap.PixelWidth
                            ? bitmap.PixelHeight > 480 ? 480m / bitmap.PixelHeight : 1
                            : bitmap.PixelWidth > 640 ? 640m / bitmap.PixelWidth : 1;
                encoder.BitmapTransform.ScaledWidth = (uint)(scale * bitmap.PixelWidth);
                encoder.BitmapTransform.ScaledHeight = (uint)(scale * bitmap.PixelHeight);
                await encoder.FlushAsync();
                stream.Seek(0);
                return stream;
            }
            catch
            {
                stream.Dispose();
                return null;
            }
        }
    }
}
