using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace ZionExtractor.Controllers.LegworkMethods
{
    class RegularExpression
    {
        public static List<ZionExtractor.Models.Hypothesis> Search(string pattern,
                                                                   ZionVault.Binder.OCR.Page page,
                                                                   ZionVault.Basic.Location Limit,
                                                                   ZionSchematics.Models.SearchOptions options)
        {
            List<ZionExtractor.Models.Hypothesis> hypotesis = new List<ZionExtractor.Models.Hypothesis>();
            RegexOptions regexOptions;

            if (options.IgnoreCase && options.IgnorePatternWhitespace)
                regexOptions = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture;
            else if (options.IgnoreCase)
                regexOptions = RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
            else if (options.IgnorePatternWhitespace)
                regexOptions = RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture;
            else
                regexOptions = RegexOptions.None;

            List<ZionVault.Binder.OCR.Word> words = get(pattern, page, Limit, options, regexOptions, false);

            if (words.Count == 0)
                words = get(pattern, page, Limit, options, regexOptions, true);
            if (words.Count == 0)
                return hypotesis;

            foreach (ZionVault.Binder.OCR.Word word in words)
                hypotesis.Add(new Models.Hypothesis(word.Text, word.Location, word.Quality));

            return hypotesis;
        }

        private static List<ZionVault.Binder.OCR.Word> get(string pattern,
                                                           ZionVault.Binder.OCR.Page page,
                                                           ZionVault.Basic.Location limit,
                                                           ZionSchematics.Models.SearchOptions options,
                                                           RegexOptions regexOptions,
                                                           bool strict = false)
        {

            //if (limit.Top == 1)
            //{
                //(from areas in page.Areas
                // from paragraphes in areas.Paragraphes
                // from lines in paragraphes.Lines
                // select lines.All(strict)).ToList().ForEach(ws =>
                // {
                //     ws.ForEach(w =>
                //     {
                //         System.IO.File.AppendAllText(@"C:\Robot\SearchResults\ADVISE\20200722\hipoteses.txt", w.Text + "\n");
                //     });
                // });
            //}

            var words = (from areas in page.Areas
                     from paragraphes in areas.Paragraphes
                     from lines in paragraphes.Lines
                     from word in lines.All(strict)
                     where
                        word != null
                        && (word.Location.Top >= limit.Top || limit.Top == -1)
                        && (word.Location.Bottom <= limit.Bottom || limit.Bottom == -1)
                        && (word.Location.Right <= limit.Right || limit.Right == -1)
                        && (word.Location.Left >= limit.Left || limit.Left == -1)
                        && (word.Text.Trim() != String.Empty)
                        && (
                            Regex.IsMatch(word.Text.Trim(), pattern, regexOptions)
                            ||
                            (Regex.IsMatch(word.Text.Replace(" ", string.Empty).Trim(), pattern, regexOptions))
                        )
                        && (options.MinLength == 0 || word.Text.Length >= options.MinLength)
                        && (options.MaxLength == 0 || word.Text.Length <= options.MaxLength)
                     orderby
                         word.Text.Length descending
                     select word).ToList();

            if (words.Count > 0)
            {
                words.ForEach(x =>
                {
                    var c = Regex.IsMatch(x.Text.Replace(" ", string.Empty).Trim(), pattern, regexOptions);
                    var f = Regex.IsMatch(x.Text.Trim(), pattern, regexOptions);
                    var b = Regex.Match(x.Text.Trim(), pattern, regexOptions).Groups;
                    var e = Regex.Match(x.Text.Replace(" ", string.Empty).Trim(), pattern, regexOptions).Groups;
                    var d = Regex.Match(x.Text.Trim(), pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture).Groups;

                });
            }

            List<ZionVault.Binder.OCR.Word> result = new List<ZionVault.Binder.OCR.Word>();

            words.ForEach(word =>
            {
                if (Regex.IsMatch(word.Text.Trim(), pattern, regexOptions))
                    result.Add(new ZionVault.Binder.OCR.Word(word.Index, word.Quality, word.Location,
                            Regex.Match(word.Text.Trim(), pattern, regexOptions).Groups[0].Value));
                else if(Regex.IsMatch(word.Text.Replace(" ", string.Empty).Trim(), pattern, regexOptions))
                    result.Add(new ZionVault.Binder.OCR.Word(word.Index, word.Quality, word.Location,
                            Regex.Match(word.Text.Replace(" ", string.Empty).Trim(), pattern, regexOptions).Groups[0].Value));
            });
            
            return result;
        }
    }
}