using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using FooEditEngine;

namespace Outline
{
    class OutlineAnalyzer
    {
        const int MaxLevel = 6;
        Dictionary<string, string[]> OutlineAnalyzePattern;

        public OutlineAnalyzer(Dictionary<string, string[]> analyzePattern)
        {
            this.OutlineAnalyzePattern = analyzePattern;
        }

        public void Analyze(TreeView treeView1,string key,LineToIndexTable LayoutLines)
        {
            if (key == null)
                return;

            treeView1.SuspendLayout();

            treeView1.Nodes.Clear();
            Stack<TreeNode> ParentList = new Stack<TreeNode>();

            for (int i = 0; i < LayoutLines.Count; i++)
            {
                string line = LayoutLines[i].ToString();
                int level = GetOutlineLevel(key, line);
                if (level == -1)
                {
                    if (i == LayoutLines.Count - 1)
                        this.SetLineCount(ParentList, i);
                    continue;
                }
                if (level >= MaxLevel)
                    continue;

                TreeNode newNode = new TreeNode(line.Trim(new char[]{' ','\t','.',Document.NewLine}));
                newNode.Tag = new OutlineInfo(i, 1);

                TreeNode ParentNode;
                while (level <= ParentList.Count - 1)
                {
                    ParentNode = ParentList.Pop();
                    SetLineCount(ParentNode, i);
                }

                if (ParentList.Count == 0)
                {
                    treeView1.Nodes.Add(newNode);
                }else{
                    ParentNode = ParentList.Peek();
                    ParentNode.Nodes.Add(newNode);
                }

                ParentList.Push(newNode);
            }

            treeView1.PerformLayout();
        }

        private void SetLineCount(Stack<TreeNode> prevNodes, int row)
        {
            foreach (TreeNode node in prevNodes)
                if (node != null)
                    this.SetLineCount(node, row);
        }

        private void SetLineCount(TreeNode node, int row)
        {
            if (node == null)
                return;
            OutlineInfo info = (OutlineInfo)node.Tag;
            info.Count = row - info.StartRow;   //rowは発見した見出し項目があるので含まない
            node.Tag = info;
        }

        public bool IsOutlineTextFormat(string patternName)
        {
            return patternName == "WZ Text";
        }

        public int GetOutlineLevel(string patternName, string str)
        {
            int level = -1;
            string[] patterns = this.OutlineAnalyzePattern[patternName];
            if (!IsOutlineTextFormat(patternName))
            {
                for (int i = patterns.Length - 1; i >= 0; i--)
                {
                    Regex regex = new Regex(patterns[i], RegexOptions.IgnoreCase);
                    Match match = regex.Match(str);
                    if (match.Success)
                    {
                        level = i;
                        break;
                    }
                }
            }
            else
            {
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] == '.')
                        level++;
                    else
                        break;
                }
            }
            return level;
        }

    }
}
