using System.Collections.Generic;
using System.Linq;
using OpenCvSharp;

namespace InterpreterLibrary.Processing
{
    internal static class HandwritingSegregator
    {
        public static IEnumerable<Rect> FindLines(Mat image)
        {
            var ret = new List<Rect>();
            var densities = FindLineDensities(image);
            const double threshold = 0.5;
            int? curY = null;
            foreach (var y in Enumerable.Range(0, densities.Count()))
            {
                var d = densities[y];
                if (d > threshold)
                {
                    if (!curY.HasValue)
                    {
                        curY = y;
                    }
                }
                else
                {
                    if (curY.HasValue)
                    {
                        var rc = Rect.FromLTRB(0, curY.Value, image.Width - 1, y - 1);
                        ret.Add(rc);
                        curY = null;
                    }
                }

                if (!curY.HasValue) continue;
                {
                    var rc = Rect.FromLTRB(0, curY.Value, image.Width - 1, image.Height - 1);
                    ret.Add(rc);
                }
            }
            return ret;
        }

        private static IReadOnlyList<double> FindLineDensities(Mat image)
        {
            int w = image.Width, h = image.Height;
            var densities = new double[h];
            using (var bytes = new MatOfByte(image))
            {
                var indexer = bytes.GetIndexer();
                for (var y = 0; y < h; y++)
                {
                    var cum = 0.0;
                    for (var x = 0; x < w; ++x)
                    {
                        var pixel = (double)indexer[y, x];
                        var value = 100 * (byte.MaxValue - pixel) / byte.MaxValue / w;
                        cum += value;
                    }
                    densities[y] = cum;
                }
            }
            return densities;
        }

        public static IReadOnlyList<double> FindVerticalDensities(Mat image)
        {
            int w = image.Width, h = image.Height;
            var densities = new double[w];
            using (var bytes = new MatOfByte(image))
            {
                var indexer = bytes.GetIndexer();
                for (var x = 0; x < w; ++x)
                {
                    var cum = 0.0;
                    for (var y = 0; y < h; y++)
                    {
                        var pixel = (double)indexer[y, x];
                        var value = 100 * (byte.MaxValue - pixel) / byte.MaxValue / h;
                        cum += value;
                    }
                    densities[x] = cum;
                }
            }
            return densities;
        }


    }
}

