using Microsoft.Office.Core;
using Microsoft.Office.Interop.Word;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Shape = Microsoft.Office.Interop.Word.Shape;

namespace OfficeAppHelp.Word
{
    /// <summary>
    /// 文档范围扩展
    /// </summary>
    public static class RangeEx
    {
        /// <summary>
        /// 统一设置颜色(文字，下划线，音调符号，表格边框)
        /// </summary>
        public static void SetColor(this Range range, WdColor wdColor)
        {
            range.Font.Color = wdColor;
            range.Font.DiacriticColor = wdColor;
            range.Font.UnderlineColor = wdColor;
            foreach (Table table in range.Tables)
            {
                table.Borders.InsideColor = wdColor;
                table.Borders.OutsideColor = wdColor;
            }
        }

        /// <summary>
        /// 是否无内容
        /// </summary>
        public static bool IsNull(this Range range)
        {
            //对公式等检测
            if (range.Text.Length == range.End - range.Start)
            {
                //对图片等检测
                string txt = range.Text.Replace("\r", "").Replace("\n", "").Replace("\v", "");
                if (string.IsNullOrEmpty(txt))
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 是否无内容或者空格组成
        /// </summary>
        public static bool IsNullOrSpace(this Range range)
        {
            //对公式等检测
            if (range.Text.Length == range.End - range.Start)
            {
                //对图片等检测
                string txt = range.Text.Trim();
                if (string.IsNullOrWhiteSpace(txt))
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 查找所有
        /// </summary>
        /// <param name="range"></param>
        /// <param name="findText">查找内容</param>
        /// <param name="isWildcard">是否使用通配符</param>
        public static List<Range> FindAll(this Range range, string findText, bool isWildcard = false)
        {
            int start = range.Start;
            int end = range.End;

            List<Range> ranges = new List<Range>();

            range.Find.Execute(FindText: findText, MatchCase: true, MatchWildcards: isWildcard);
            while (range.Find.Found)
            {
                //搜索会改变range，这里做了一个超出范围的判断
                if (range.Start > end)
                    break;

                ranges.Add(range.Document.Range(range.Start, range.End));
                range.Find.Execute(FindText: findText, MatchCase: true, MatchWildcards: isWildcard);
            }

            //对原来的range还原
            range.SetRange(start, end);
            return ranges;
        }

        /// <summary>
        /// 查找第一个
        /// </summary>
        /// <param name="range"></param>
        /// <param name="findText">查找内容</param>
        /// <param name="isWildcard">是否使用通配符</param>
        /// <returns>没有找到为空</returns>
        public static Range FindFirst(this Range range, string findText, bool isWildcard = false)
        {
            int start = range.Start;
            int end = range.End;

            bool isOk = range.Find.Execute(FindText: findText, MatchCase: true, MatchWildcards: isWildcard);
            if (isOk)
            {
                var newRange = range.Document.Range(range.Start, range.End);
                range.SetRange(start, end);
                return newRange;
            }
            else
                return null;
        }

        /// <summary>
        /// 替换
        /// </summary>
        /// <param name="range"></param>
        /// <param name="findText">查找内容</param>
        /// <param name="replacementText">替换内容</param>
        public static bool Replace(this Range range, string findText, string newValue)
        {
            return range.Find.Execute
                (
                FindText: findText,
                MatchCase: true,
                MatchWildcards: true,
                Wrap: WdFindWrap.wdFindStop,
                ReplaceWith: newValue,
                Replace: WdReplace.wdReplaceAll
                );
        }

        /// <summary>
        /// 得到非嵌入型的形状
        /// </summary>
        /// <param name="range"></param>
        public static List<Shape> GetNotWrapInlineShape(this Range range)
        {
            if (range == null)
                return null;

            List<Shape> shapes = new List<Shape>();
            foreach (Shape shape in range.ShapeRange)
            {
                if (shape.WrapFormat.Type != WdWrapType.wdWrapInline)
                {
                    shapes.Add(shape);
                }
            }
            return shapes;
        }

        /// <summary>
        /// 转为图片流（执行“Image.FromStream(Stream)”可为图片）
        /// </summary>
        /// <param name="range"></param>
        public static Stream ToImageStream(this Range range)
        {
            if (range == null)
                return null;

            var bits = (byte[])range.EnhMetaFileBits;
            return new MemoryStream(bits);
        }

        /// <summary>
        /// 是否在表格中
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool IsInTable(this Range range)
        {
            if (range == null)
                return false;

            foreach (Table table in range.Tables)
                if (range.InRange(table.Range))
                    return true;

            return false;
        }

        /// <summary>
        /// 得到页码
        /// </summary>
        /// <param name="range"></param>
        /// <param name="isAdjusted">是否返回调整后的页码（插入-页码-页码...-起始页码）</param>
        /// <returns></returns>
        public static List<int> GetPageNumber(this Range range, bool isAdjusted = true)
        {
            List<int> ints = new List<int>();
            if (range == null)
                return ints;

            int go = 0;
            int to = 0;
            Range startRange = range.Document.Range(range.Start, range.Start);
            if (isAdjusted)
            {
                go = (int)startRange.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
                to = (int)range.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
            }
            else
            {
                go = (int)startRange.get_Information(WdInformation.wdActiveEndPageNumber);
                to = (int)range.get_Information(WdInformation.wdActiveEndPageNumber);
            }

            for (; go <= to; go++)
                ints.Add(go);
            return ints;
        }

        /// <summary>
        /// 得到页码（最开始的一个）
        /// </summary>
        /// <param name="range"></param>
        /// <param name="isAdjusted">是否返回调整后的页码（插入-页码-页码...-起始页码）</param>
        /// <returns>range为空返回-1</returns>
        public static int GetPageNumberStart(this Range range, bool isAdjusted = true)
        {
            if (range == null)
                return -1;

            Range startRange = range.Document.Range(range.Start, range.Start);
            if (isAdjusted)
                return (int)startRange.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
            else
                return (int)startRange.get_Information(WdInformation.wdActiveEndPageNumber);

        }

        /// <summary>
        /// 得到页码（最后的一个）
        /// </summary>
        /// <param name="range"></param>
        /// <param name="isAdjusted">是否返回调整后的页码（插入-页码-页码...-起始页码）</param>
        /// <returns>range为空返回-1</returns>
        public static int GetPageNumberEnd(this Range range, bool isAdjusted = true)
        {
            if (range == null)
                return -1;

            if (isAdjusted)
                return (int)range.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
            else
                return (int)range.get_Information(WdInformation.wdActiveEndPageNumber);

        }

    }
}
