using System;
using System.Collections.Generic;
using System.Text;
using ChaKi.Entity.Corpora;
using NHibernate;
using ChaKi.Entity.Corpora.Annotations;
using System.Diagnostics;

namespace ChaKi.Service.DependencyEdit
{
    internal class OperationCreateWordGroup : Operation
    {
        private CharRange m_Range;
        private Group m_Group;
        private Segment m_Segment;
        private string m_TagName;

        public OperationCreateWordGroup(CharRange range, string tagName)
        {
            m_Range = range;
            m_TagName = tagName;
        }

        public override void Execute(DepEditContext ctx)
        {
            Segment seg = new Segment();
            seg.Sentence = ctx.Sen;
            seg.Doc = ctx.Sen.ParentDoc;
            seg.Tag = ctx.Proj.FindTag(Tag.SEGMENT, m_TagName);
            seg.StartChar = m_Range.Start.Value + ctx.Sen.StartChar;
            seg.EndChar = m_Range.End.Value + ctx.Sen.StartChar;
            seg.Proj = ctx.Proj;
            seg.User = ctx.User;
            seg.Version = seg.Tag.Version;
            ctx.Save(seg);
            m_Segment = seg;
            if (m_Group == null)
            {
                Group grp = new Group();
                grp.Tag = ctx.Proj.FindTag(Tag.GROUP, m_TagName);
                grp.Proj = ctx.Proj;
                grp.User = ctx.User;
                grp.Version = grp.Tag.Version;
                m_Group = grp;
            }
            // Undo->Redoの場合は再生成せずにセーブされていたGroupを復活させる.
            // (Createしなおすと、AddItemのRedoで親Groupが異なってしまう）
            m_Group.Tags.Add(seg);
            ctx.Save(m_Group);
            ctx.Flush();
        }

        public override void UnExecute(DepEditContext ctx)
        {
            if (m_Group == null || m_Segment == null)
            {
                throw new NullReferenceException();
            }
            Debug.Assert(m_Group.Tags.Count == 1);
            m_Segment = m_Group.Tags[0] as Segment;
            ctx.Delete(m_Segment);
            m_Group.Tags.Clear();
            ctx.Delete(m_Group);
            m_Segment = null;
            ctx.Flush();
        }

        public override string ToIronRubyStatement(DepEditContext ctx)
        {
            return string.Format("#svc.CreateWordGroup(c+({0}), c+({1}), \"{2}\") : not supported",
                m_Range.Start + ctx.Sen.StartChar - ctx.CharOffset,
                m_Range.End + ctx.Sen.StartChar - ctx.CharOffset,
                m_TagName);
        }

        public override string ToString()
        {
            return string.Format("{{CreateWordGroup:{0}}}", m_Range);
        }
    }
}
