/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Pullenti.Unitext.Internal.Uni
{
    class UnitextCorrPdfPage
    {
        public int Num;
        public List<UnitextCorrPdfLine> Lines = new List<UnitextCorrPdfLine>();
        public Pullenti.Unitext.UnitextPagebreak PageBreak;
        public List<UnitextCorrPdfLine> Footnotes = new List<UnitextCorrPdfLine>();
        public override string ToString()
        {
            StringBuilder tmp = new StringBuilder();
            tmp.AppendFormat("№{0} ", Num);
            if (Footnotes.Count > 0) 
                tmp.AppendFormat("Foots:{0} ", Footnotes.Count);
            tmp.Append(Lines[0].ToString());
            return tmp.ToString();
        }
        static List<UnitextCorrPdfPage> _createPages(Pullenti.Unitext.UnitextContainer cnt)
        {
            List<UnitextCorrPdfPage> pages = new List<UnitextCorrPdfPage>();
            UnitextCorrPdfPage page = null;
            UnitextCorrPdfLine line = null;
            for (int i = 0; i < cnt.Children.Count; i++) 
            {
                Pullenti.Unitext.UnitextItem it = cnt.Children[i];
                it.Tag = i;
                if (it is Pullenti.Unitext.UnitextPlaintext) 
                {
                    string txt = (it as Pullenti.Unitext.UnitextPlaintext).Text;
                    if (string.IsNullOrEmpty(txt)) 
                        continue;
                    txt = txt.ToUpper();
                    if (txt.StartsWith("КОНСУЛЬТАНТПЛЮС") || txt.Contains("ПРЕДОСТАВЛЕН КОНСУЛЬТАНТПЛЮС")) 
                    {
                        int j;
                        for (j = i + 1; j < cnt.Children.Count; j++) 
                        {
                            Pullenti.Unitext.UnitextItem it1 = cnt.Children[j];
                            if (it1 is Pullenti.Unitext.UnitextPagebreak) 
                                break;
                            if (it1 is Pullenti.Unitext.UnitextNewline) 
                                continue;
                            if (!(it1 is Pullenti.Unitext.UnitextPlaintext)) 
                                break;
                            txt = (it1 as Pullenti.Unitext.UnitextPlaintext).Text;
                            if (string.IsNullOrEmpty(txt)) 
                                continue;
                            txt = txt.ToUpper();
                            if (txt.Contains("ПРАВОВАЯ ПОДДЕРЖКА") || txt.Contains("CONSULTANT.RU")) 
                                continue;
                            if (txt.Contains("КОНСУЛЬТАНТПЛЮС") || txt.Contains("ДАТА СОХРАНЕНИЯ")) 
                                continue;
                            break;
                        }
                        cnt.Children.RemoveRange(i, j - i);
                        i--;
                        continue;
                    }
                    if (page == null) 
                    {
                        page = new UnitextCorrPdfPage();
                        pages.Add(page);
                        page.Num = pages.Count;
                        line = null;
                        if (page.Num == 19) 
                        {
                        }
                    }
                    if (line == null) 
                    {
                        line = new UnitextCorrPdfLine();
                        page.Lines.Add(line);
                    }
                    line.Texts.Add(it as Pullenti.Unitext.UnitextPlaintext);
                    continue;
                }
                if (it is Pullenti.Unitext.UnitextNewline) 
                {
                    if (line != null) 
                        line.Newlines.Add(it as Pullenti.Unitext.UnitextNewline);
                    line = null;
                    continue;
                }
                if (it is Pullenti.Unitext.UnitextPagebreak) 
                {
                    if (page != null) 
                        page.PageBreak = it as Pullenti.Unitext.UnitextPagebreak;
                    page = null;
                    continue;
                }
                if (it is Pullenti.Unitext.UnitextFootnote) 
                    continue;
                line = null;
            }
            return pages;
        }
        public static void Correct(Pullenti.Unitext.UnitextContainer cnt)
        {
            List<UnitextCorrPdfPage> pages = _createPages(cnt);
            if (pages.Count == 0) 
                return;
            Dictionary<string, int> titles = new Dictionary<string, int>();
            foreach (UnitextCorrPdfPage p in pages) 
            {
                for (int k = 0; k < 2; k++) 
                {
                    UnitextCorrPdfLine line = p.Lines[(k == 0 ? 0 : (p.Lines.Count - 1))];
                    string tit = line.HeadTextWithoutNumbers;
                    if (tit != null) 
                    {
                        if (!titles.ContainsKey(tit)) 
                            titles.Add(tit, 1);
                        else 
                            titles[tit]++;
                    }
                    if (k == 0 && p.Lines.Count == 1) 
                        break;
                }
            }
            bool changes = false;
            int minCou = pages.Count / 4;
            if (minCou < 2) 
                minCou = 2;
            foreach (UnitextCorrPdfPage p in pages) 
            {
                for (int k = 0; k < 2; k++) 
                {
                    if (p.Lines.Count == 0) 
                        break;
                    UnitextCorrPdfLine line = p.Lines[(k == 0 ? 0 : (p.Lines.Count - 1))];
                    string tit = line.HeadTextWithoutNumbers;
                    if (tit != null) 
                    {
                        int cou = 0;
                        titles.TryGetValue(tit, out cou);
                        if (cou > minCou || ((cou == minCou && pages.Count == minCou))) 
                        {
                            line.RemoveAll();
                            p.Lines.Remove(line);
                            changes = true;
                            k--;
                            continue;
                        }
                    }
                    if (line.IsPureNumber) 
                    {
                        line.RemoveAll();
                        p.Lines.Remove(line);
                        changes = true;
                        k--;
                        continue;
                    }
                    if (k == 0 && p.Lines.Count == 1) 
                        break;
                }
            }
            if (changes) 
            {
                for (int i = cnt.Children.Count - 1; i >= 0; i--) 
                {
                    if (cnt.Children[i].Tag == null) 
                        cnt.Children.RemoveAt(i);
                }
                for (int i = cnt.Children.Count - 1; i >= 0; i--) 
                {
                    cnt.Children[i].Tag = i;
                }
            }
            foreach (UnitextCorrPdfPage p in pages) 
            {
                if (p.Num == 57) 
                {
                }
                p.ProcessFootnotes();
            }
            changes = false;
            for (int i = pages.Count - 1; i >= 0; i--) 
            {
                if (i == 17) 
                {
                }
                if (pages[i].CreateFootnotes(cnt)) 
                    changes = true;
            }
            for (int i = 0; i < cnt.Children.Count; i++) 
            {
                cnt.Children[i].Tag = i;
            }
            int total = 0;
            int hiphens = 0;
            foreach (UnitextCorrPdfPage p in pages) 
            {
                foreach (UnitextCorrPdfLine l in p.Lines) 
                {
                    if (l.TextLength < 40) 
                        continue;
                    total++;
                    if (CorrLine.IsHiphen(l.LastChar)) 
                        hiphens++;
                }
            }
            bool hasHiph = false;
            if (hiphens > 0 && (((hiphens * 100) / total)) > 10) 
                hasHiph = true;
            for (int i = pages.Count - 1; i >= 0; i--) 
            {
                UnitextCorrPdfPage page = pages[i];
                if (page.Lines.Count == 0) 
                    continue;
                if (i == 2) 
                {
                }
                if (((i + 1) < pages.Count) && pages[i + 1].Lines.Count > 0) 
                {
                    UnitextCorrPdfLine last = page.Lines[page.Lines.Count - 1];
                    if (last.CanUnion(pages[i + 1].Lines[0])) 
                    {
                        page.PageBreak.Typ = Pullenti.Unitext.WhitespaceType.Onespace;
                        if (hasHiph && last.IsLastCharHiphen) 
                        {
                            page.PageBreak.Typ = Pullenti.Unitext.WhitespaceType.Ignorable;
                            if (((i + 1) < page.Lines.Count) && char.IsLower(page.Lines[i + 1].FirstChar)) 
                                last.RemoveLastHiph();
                        }
                        for (int k = last.Newlines.Count - 1; k >= 0; k--) 
                        {
                            cnt.Children.RemoveAt((int)last.Newlines[k].Tag);
                        }
                    }
                }
                for (int j = page.Lines.Count - 2; j >= 0; j--) 
                {
                    UnitextCorrPdfLine line = page.Lines[j];
                    if (line.CanUnion(page.Lines[j + 1])) 
                    {
                        int i0 = -1;
                        if (line.Newlines.Count > 0) 
                            i0 = (int)line.Newlines[0].Tag;
                        for (int k = line.Newlines.Count - 1; k >= 0; k--) 
                        {
                            cnt.Children.RemoveAt((int)line.Newlines[k].Tag);
                        }
                        if (hasHiph && line.IsLastCharHiphen) 
                        {
                            if (char.IsLower(page.Lines[j + 1].FirstChar)) 
                                line.RemoveLastHiph();
                        }
                        else 
                        {
                            if (i0 < 0) 
                                i0 = ((int)line.Texts[line.Texts.Count - 1].Tag) + 1;
                            cnt.Children.Insert(i0, new Pullenti.Unitext.UnitextPlaintext() { Text = " " });
                        }
                    }
                }
            }
            for (int i = 0; i < (cnt.Children.Count - 1); i++) 
            {
                if ((cnt.Children[i] is Pullenti.Unitext.UnitextPagebreak) && (cnt.Children[i + 1] is Pullenti.Unitext.UnitextNewline)) 
                {
                    cnt.Children.RemoveAt(i + 1);
                    i--;
                    continue;
                }
                else if ((cnt.Children[i + 1] is Pullenti.Unitext.UnitextPagebreak) && (cnt.Children[i] is Pullenti.Unitext.UnitextNewline)) 
                {
                    cnt.Children.RemoveAt(i);
                    i--;
                    continue;
                }
            }
        }
        public void ProcessFootnotes()
        {
            List<UnitextCorrPdfLine> foots = new List<UnitextCorrPdfLine>();
            int max = 0;
            for (int i = Lines.Count - 1; i >= 0; i--) 
            {
                int num = Lines[i].FootnoteHeadNum;
                if (num > 0) 
                {
                    foots.Insert(0, Lines[i]);
                    max = 0;
                }
                else 
                    max++;
                if (max > 5) 
                    break;
            }
            if (foots.Count == 0) 
                return;
            for (int i = 0; i < (foots.Count - 1); i++) 
            {
                if ((foots[i].FootnoteHeadNum + 1) != foots[i + 1].FootnoteHeadNum) 
                {
                    if (foots[i].FootnoteHeadNum != (i + 1)) 
                        return;
                    if ((i + 2) == foots.Count) 
                    {
                    }
                    else if ((foots[i].FootnoteHeadNum + 1) == foots[i + 2].FootnoteHeadNum) 
                    {
                    }
                    else 
                        return;
                    foots.RemoveAt(i + 1);
                    i--;
                }
            }
            int fi = 0;
            int j = 0;
            max = Lines.IndexOf(foots[0]);
            for (; fi < foots.Count; fi++) 
            {
                UnitextCorrPdfLine foot = foots[fi];
                for (; j < max; j++) 
                {
                    UnitextCorrPdfLine li = Lines[j];
                    if (j == 18) 
                    {
                    }
                    if (li.AttachFoot(foot)) 
                        break;
                }
                if (j >= max) 
                    break;
            }
            if (fi < foots.Count) 
                return;
            Footnotes.AddRange(foots);
        }
        public bool CreateFootnotes(Pullenti.Unitext.UnitextContainer cnt)
        {
            if (Footnotes.Count == 0) 
                return false;
            int i0 = 0;
            int i1;
            for (int f = Footnotes.Count - 1; f >= 0; f--) 
            {
                UnitextCorrPdfLine foot = Footnotes[f];
                i0 = (int)foot.Texts[0].Tag;
                i1 = i0 + 100;
                if ((f + 1) < Footnotes.Count) 
                    i1 = (int)Footnotes[f + 1].Texts[0].Tag;
                Pullenti.Unitext.UnitextFootnote fn = new Pullenti.Unitext.UnitextFootnote();
                fn.CustomMark = string.Format("{0}", foot.FootnoteHeadNum);
                foot.ResFoot = fn;
                fn.Content = new Pullenti.Unitext.UnitextContainer();
                bool needSp = false;
                bool needTruct = true;
                for (int i = i0; (i < i1) && (i < cnt.Children.Count); i++) 
                {
                    Pullenti.Unitext.UnitextItem it = cnt.Children[i];
                    it.Parent = fn.Content;
                    if (it is Pullenti.Unitext.UnitextPlaintext) 
                    {
                        if (needTruct) 
                        {
                            needTruct = false;
                            Pullenti.Unitext.UnitextPlaintext pt0 = it as Pullenti.Unitext.UnitextPlaintext;
                            pt0.Text = pt0.Text.Substring(fn.CustomMark.Length).Trim();
                        }
                        if (needSp) 
                            (fn.Content as Pullenti.Unitext.UnitextContainer).Children.Add(new Pullenti.Unitext.UnitextPlaintext() { Text = " " });
                        needSp = false;
                        (fn.Content as Pullenti.Unitext.UnitextContainer).Children.Add(it);
                    }
                    else if (it is Pullenti.Unitext.UnitextNewline) 
                        needSp = true;
                    else 
                        break;
                }
            }
            for (i1 = i0; i1 < cnt.Children.Count; i1++) 
            {
                Pullenti.Unitext.UnitextItem it = cnt.Children[i1];
                if (it is Pullenti.Unitext.UnitextPagebreak) 
                    break;
            }
            cnt.Children.RemoveRange(i0, i1 - i0);
            for (int f = Footnotes.Count - 1; f >= 0; f--) 
            {
                UnitextCorrPdfLine foot = Footnotes[f];
                i0 = (int)foot.RefText.Tag;
                if (foot.RefPos == 0) 
                {
                    if (foot.RefText.Text.Length == foot.RefLen) 
                        cnt.Children[i0] = foot.ResFoot;
                    else 
                    {
                        foot.RefText.Text = foot.RefText.Text.Substring(foot.RefLen).TrimStart();
                        cnt.Children.Insert(i0, foot.ResFoot);
                    }
                }
                else if ((foot.RefPos + foot.RefLen) == foot.RefText.Text.Length) 
                {
                    foot.RefText.Text = foot.RefText.Text.Substring(0, foot.RefPos);
                    cnt.Children.Insert(i0 + 1, foot.ResFoot);
                }
                else 
                {
                    string txtTail = foot.RefText.Text.Substring(foot.RefPos + foot.RefLen, foot.RefText.Text.Length - foot.RefPos - foot.RefLen);
                    foot.RefText.Text = foot.RefText.Text.Substring(0, foot.RefPos);
                    cnt.Children.Insert(i0 + 1, foot.ResFoot);
                    cnt.Children.Insert(i0 + 2, new Pullenti.Unitext.UnitextPlaintext() { Text = txtTail });
                }
            }
            i0 = Lines.IndexOf(Footnotes[0]);
            if (i0 > 0) 
                Lines.RemoveRange(i0, Lines.Count - i0);
            return true;
        }
    }
}