using System.Globalization;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Soletude.Stags.Images.Helpers;

namespace Soletude.Stagsi.Plugins
{
    public class Txt
    {
        private const string TxtFormatName = "txt";
        private const string EndLineChars = "\r\n";
        private const string RenderFontName = "Arial";
        private const double RenderFontSize = 144.0;
        private static readonly string[] InvalidStrings = {"\0"};

        public static void StagsiPlugin(IPluginService service)
        {
            service.RegisterImageLoaderV1(RenderTxt,
                new ImageLoaderV1 { FileExtensions = new[] {TxtFormatName}});
        }

        private static BitmapSource RenderTxt(Stream input, IImageLoadingV1 parameters)
        {
            if (parameters.Width == 0 || parameters.Height == 0)
            {
                return null;
            }

            string allText;
            // Don't do this, it'll close the stream and interfere with other plugins:
            //using (var reader = new StreamReader(input))
            var len = input.Length;
            if (input.Length > 100000)
            {
                len = 100000;
            }
            byte[] buf = new byte[len];
            input.Read(buf, 0, buf.Length);
            allText = Encoding.UTF8.GetString(buf);

            foreach (var v in InvalidStrings)
            {
                if (allText.Contains(v))
                {
                    return null;
                }
            }

            // Remove BOM signature if exists.
            if (allText.Length > 3)
            {
                if (allText[0] == 0xEF && allText[1] == 0xBB && allText[2] == 0xBF)
                {
                    allText = allText.Substring(3, allText.Length - 3);
                }
            }

            allText = allText.Replace(EndLineChars, " ");
            // Draw wrapped text and save.
            var txt = new FormattedText(allText, CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight, new Typeface(RenderFontName),
                RenderFontSize, Brushes.Black);
            return WriteTextToImage(txt, new Point(0, 0),  parameters);
        }

        public static BitmapSource WriteTextToImage(FormattedText text,
            Point position, IImageLoadingV1 parameters)
        {
            var visual = new DrawingVisual();
            var prop = parameters.Height / parameters.Width;
            var wid = parameters.Width;
            var hei = (int)(wid * prop);

            text.MaxTextWidth = wid;
            using (var dc = visual.RenderOpen())
            {
                dc.DrawRectangle(Brushes.White, null, new Rect(new Size(wid, hei)));
                dc.DrawText(text, position);
            }

            var target = new RenderTargetBitmap((int)wid, hei, 96.0, 96.0,
                PixelFormats.Default);
            target.Render(visual);

            FileMagic.FillOutValues(parameters, wid, hei, TxtFormatName);

            return target;
        }
    }
}
