using AForge.Imaging;
using AForge.Imaging.Filters;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using Tesseract;

namespace ZionGraphics.Filtering
{
    class CarneJequiti : IFilter
    {
        public override Bitmap Apply(Bitmap original)
        {
            double num = 0.22;
            double num2 = 0.5;
            AutoRotate.FixImageOrientation(original);
            Rectangle rect = new Rectangle((int)((double)original.Width * num2), 0, (int)((double)original.Width * num2), (int)((double)original.Height * num));
            return original.Clone(rect, original.PixelFormat);
        }
    }
    class MultiFiltro_DoisFiltros : IFilter
    {
        public override Bitmap Apply(Bitmap bitmap)
        {
            List<Func<Bitmap, Bitmap>> filters = new List<Func<Bitmap, Bitmap>>
            {
                MultiFiltro.Deskewing2_Grayscale,
                MultiFiltro.RotateBicubic_0
            };
            MultiFiltro.ApplyFilterList(bitmap, filters);
            return bitmap;
        }
    }
    class MultiFiltro_TresFiltros : IFilter
    {
        public override Bitmap Apply(Bitmap bitmap)
        {
            List<Func<Bitmap, Bitmap>> filters = new List<Func<Bitmap, Bitmap>>
            {
                MultiFiltro.Deskewing,
                MultiFiltro.RotateBicubic_N1,
                MultiFiltro.RotateBicubic_1
            };
            MultiFiltro.ApplyFilterList(bitmap, filters);
            return bitmap;
        }
    }
    class MultiFiltro_SeisFiltros : IFilter
    {
        public override Bitmap Apply(Bitmap bitmap)
        {
            List<Func<Bitmap, Bitmap>> filters = new List<Func<Bitmap, Bitmap>>
            {
                MultiFiltro.Deskewing2_Grayscale,
                MultiFiltro.Deskewing,
                MultiFiltro.Sharpen,
                MultiFiltro.Contrast,
                MultiFiltro.RotateBicubic_N1,
                MultiFiltro.RotateBicubic_1
            };
            MultiFiltro.ApplyFilterList(bitmap, filters);
            return bitmap;
        }
    }

    class MultiFiltro : IFilter
    {
        public static Bitmap Deskewing2_Grayscale(Bitmap bitmap)
        {
            return IFilter.build("Deskewing2_Grayscale").Apply(bitmap);
        }
        public static Bitmap Deskewing(Bitmap bitmap)
        {
            return IFilter.build("Deskewing").Apply(bitmap);
        }
        public static Bitmap Sharpen(Bitmap bitmap)
        {
            return IFilter.build("Sharpen").Apply(bitmap);
        }
        public static Bitmap Contrast(Bitmap bitmap)
        {
            return IFilter.build("Contrast").Apply(bitmap);
        }
        public static Bitmap Brightness(Bitmap bitmap)
        {
            return IFilter.build("Brightness").Apply(bitmap);
        }
        public static Bitmap RotateBicubic(Bitmap bitmap, int intensity)
        {
            return IFilter.build("RotateBicubic", intensity).Apply(bitmap); 
        }
        public static Bitmap RotateBicubic_0(Bitmap bitmap)
        {
            return RotateBicubic(bitmap, 0);
        }
        public static Bitmap RotateBicubic_1(Bitmap bitmap)
        {
            return RotateBicubic(bitmap, 1);
        }
        public static Bitmap RotateBicubic_N1(Bitmap bitmap)
        {
            return RotateBicubic(bitmap, -1);
        }

        public override Bitmap Apply(Bitmap bitmap)
        {
            AutoRotate.FixImageOrientation(bitmap);

            List<Func<Bitmap, Bitmap>> filters = new List<Func<Bitmap, Bitmap>>
            {
                Deskewing2_Grayscale,
                Deskewing,
                Sharpen,
                Contrast,
                Brightness,
                RotateBicubic_0,
                RotateBicubic_1,
                RotateBicubic_N1
            };
            Bitmap[] filterResults = new Bitmap[filters.Count];
            for (int i = 0; i < filters.Count; i++)
            {
                filterResults[i] = filters[i](bitmap);
            }
            Bitmap result = new Bitmap(bitmap, bitmap.Width, bitmap.Height * (filters.Count + 1));
            using (Graphics graphics = Graphics.FromImage(result))
            {
                graphics.Clear(Color.White);
                int width = result.Width;
                int Height = result.Height / (filters.Count + 1);
                Rectangle rect2 = new Rectangle(0, 0, width, Height);
                graphics.DrawImage(bitmap, rect2);
                for (int i = 0; i < filters.Count; i++)
                {
                    rect2.Y += Height;
                    graphics.DrawImage(filterResults[i], rect2);
                }
            }
            return result;
        }

        public static Bitmap ApplyFilterList(Bitmap bitmap, List<Func<Bitmap, Bitmap>> filters)
        {
            AutoRotate.FixImageOrientation(bitmap);

            if (filters.Count == 0)
            {
                return bitmap;
            }

            Bitmap[] filterResults = new Bitmap[filters.Count];
            for (int i = 0; i < filters.Count; i++)
            {
                filterResults[i] = filters[i](bitmap);
            }
            Bitmap result = new Bitmap(bitmap, bitmap.Width, bitmap.Height * (filters.Count + 1));
            using (Graphics graphics = Graphics.FromImage(result))
            {
                graphics.Clear(Color.White);
                int width = result.Width;
                int Height = result.Height / (filters.Count + 1);
                Rectangle rect2 = new Rectangle(0, 0, width, Height);
                graphics.DrawImage(bitmap, rect2);
                for (int i = 0; i < filters.Count; i++)
                {
                    rect2.Y += Height;
                    graphics.DrawImage(filterResults[i], rect2);
                }
            }
            return result;
        }
    }
}
