using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using ZionGraphics.Handlers;
using ZionGraphics.Pdf.Text;

namespace ZionGraphics.Pdf
{
    class Importer : IDisposable
    {
        private PdfReader reader;

        private string path;

        public Importer(string path)
        {
            this.path = path;
            this.reader = new PdfReader(this.path);
        }

        public int Pages { get => this.reader.NumberOfPages; }

        public System.Drawing.Bitmap ExtractBitmapFromPage(int index)
        {
            try
            {
                ImageRenderListener listener = null;
                PdfReaderContentParser parser = new PdfReaderContentParser(reader);
                parser.ProcessContent(index, (listener = new ImageRenderListener()));

                if (listener.Images.Count == 0)
                    throw new NullReferenceException();

                List<Rectangle> list = new List<Rectangle>();

                for(int i = 0; i < listener.Images.Count(); i++)
                {
                    list.Add(listener.Images[i].Rect);
                }

                float left = list.Select(x => x.X).Min();
                float right = list.Select(x => x.X + x.Width).Max();

                float top = list.Select(x => x.Y).Min();
                float bottom = list.Select(x => x.Y + x.Height).Max();

                System.Drawing.Bitmap bitmap = new Bitmap((int)((right - left)), (int)((bottom - top)));

                using(Graphics g = Graphics.FromImage(bitmap))
                {
                    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                    
                    for (int i = 0; i < listener.Images.Count(); i++)
                    {
                        int y = bitmap.Height - ((int)Math.Floor((double)(list[i].Y + list[i].Height)));
                        g.DrawImage((System.Drawing.Bitmap)listener.Images[i].Img, new Rectangle((int)(list[i].X), y, (int)(list[i].Width), (int)(list[i].Height)));
                    }
                }

                //System.Drawing.Bitmap result = (System.Drawing.Bitmap)listener.Images.First().Value;

                listener = null;
                parser = null;

                return bitmap;
            }
            catch
            {
                return null;
            }
        }

        public System.Drawing.Bitmap GenerateBitmapFromPage(int index)
        {
            using (var document = PdfiumViewer.PdfDocument.Load(path))
            {
                //return (Bitmap)document.Render(index, 72, 72, false);
                return (Bitmap)document.Render(index, 300, 300, PdfiumViewer.PdfRenderFlags.CorrectFromDpi);
            }
        }

        public ZionVault.Binder.OCR.Page ExtractTextFromPage(int index)
        {
            iTextSharp.text.Rectangle pagesize = reader.GetPageSize(index);

            ZionVault.Binder.OCR.Page content = new ZionVault.Binder.OCR.Page(index);
            
            ZionExtractionStrategy strategy = new ZionExtractionStrategy(pagesize.Height);                
            content.Text = PdfTextExtractor.GetTextFromPage(reader, index, strategy);

            content.Areas.AddRange(strategy.Content.Areas);
            
            return content;
        }

        public void Dispose()
        {
            reader.Close();
            reader.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.WaitForFullGCComplete();
        }

        
    }
}
