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

namespace FooEditor
{
    public sealed class OutlineItem : FoldingItem
    {
        /// <summary>
        /// コンストラクター
        /// </summary>
        public OutlineItem(int start, int end, int level)
            : base(start, end)
        {
            this.Level = level;
        }

        /// <summary>
        /// アウトラインレベル
        /// </summary>
        public int Level
        {
            get;
            set;
        }
    }

    sealed class RegexFoldingGenerator : IFoldingStrategy
    {
        Regex BeginBracket, EndBracket;
        public RegexFoldingGenerator(string begin, string end)
        {
            if (string.IsNullOrEmpty(begin) || string.IsNullOrEmpty(end))
                throw new ArgumentNullException();
            this.BeginBracket = new Regex(begin,RegexOptions.IgnoreCase);
            this.EndBracket = new Regex(end, RegexOptions.IgnoreCase);
        }

        public IEnumerable<FoldingItem> AnalyzeDocument(Document doc, int start, int end)
        {
            Stack<int> beginIndexs = new Stack<int>();
            int level = 0;
            int lineHeadIndex = start;
            foreach (string lineStr in doc.GetLines(start, end))
            {
                Match m = this.BeginBracket.Match(lineStr);
                if (m.Success)
                {
                    beginIndexs.Push(lineHeadIndex + m.Index);
                    level++;
                }
                m = this.EndBracket.Match(lineStr);
                if (m.Success)
                {
                    if (beginIndexs.Count == 0)
                        continue;
                    int beginIndex = beginIndexs.Pop();
                    int endIndex = lineHeadIndex + m.Index + m.Length - 1;
                    if (beginIndex < endIndex)
                        yield return new OutlineItem(beginIndex, endIndex,level);
                    level--;
                }
                lineHeadIndex += lineStr.Length;
            }
        }
    }
}
