using System.Linq;
using DotNetTextStore.UnmanagedAPI.WinDef;
using DotNetTextStore.UnmanagedAPI.TSF;
using DotNetTextStore;

namespace FooEditEngine
{
    static class TextStoreHelper
    {
        public static bool StartCompstion(Document document)
        {
            if (document.State == AsyncState.Loading)
            {
                return false;
            }
            document.UndoManager.BeginUndoGroup();
            return true;
        }

        public static void EndCompostion(Document document)
        {
            document.UndoManager.EndUndoGroup();
        }

        public static bool ScrollToCompstionUpdated(TextStoreBase textStore,EditView view,int start, int end)
        {
            if (textStore.IsLocked() == false)
                return false;
            using (Unlocker locker = textStore.LockDocument(false))
            {
                foreach (TextDisplayAttribute attr in textStore.EnumAttributes(start, end))
                {
                    if (attr.attribute.bAttr == TF_DA_ATTR_INFO.TF_ATTR_TARGET_CONVERTED)
                    {
                        if (view.AdjustSrc(attr.startIndex))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;   
        }

        public static void GetStringExtent(Document document,EditView view,int i_startIndex,int i_endIndex,out Point startPos,out Point endPos)
        {
            if (document.State == AsyncState.Loading)
            {
                startPos = new Point();
                endPos = startPos;
                return;
            }
            var endIndex = i_endIndex < 0 ? document.Length - 1 : i_endIndex;
            TextPoint endTextPoint;

            startPos = view.GetPostionFromTextPoint(view.LayoutLines.GetTextPointFromIndex(i_startIndex));
            endTextPoint = view.GetLayoutLineFromIndex(endIndex);
            endPos = view.GetPostionFromTextPoint(endTextPoint);
            endPos.Y += view.LayoutLines.GetData(endTextPoint.row).Layout.Height;
        }

        public static void GetSelection(Controller controller, Document document, out int o_startIndex, out int o_endIndex)
        {
            if (controller.RectSelection && document.Selections.Count > 0)
            {
                o_startIndex = document.Selections[0].start;
                o_endIndex = o_startIndex + document.Selections[0].length;
            }
            else
            {
                o_startIndex = controller.SelectionStart;
                o_endIndex = o_startIndex + controller.SelectionLength;
            }
        }

        public static void SetSelectionIndex(Controller controller,EditView view,int i_startIndex, int i_endIndex)
        {
            if (controller.RectSelection && view.InsertPoint != null)
            {
                TextPoint start = view.LayoutLines.GetTextPointFromIndex(i_startIndex);
                TextPoint end = view.LayoutLines.GetTextPointFromIndex(view.InsertPoint.Last().start);
                controller.Select(start, i_endIndex - i_startIndex, end.row - start.row);
            }
            else if (i_startIndex == i_endIndex)
            {
                controller.JumpCaret(i_startIndex);
            }
            else
            {
                controller.Select(i_startIndex, i_endIndex - i_startIndex);
            }
        }

        public static void InsertTextAtSelection(Controller controller,string i_value)
        {
            controller.DoInputString(i_value, true);
        }
    }
}
