using PDF_Office.Model.PageEdit;
using PDF_Office.ViewModels.Dialog.BOTA;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace PDF_Office.Helper
{
    public class Compare<T, C> : IEqualityComparer<T>
    {
        private Func<T, C> _getField;

        public Compare(Func<T, C> getfield)
        {
            this._getField = getfield;
        }

        public bool Equals(T x, T y)
        {
            return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
        }

        public int GetHashCode(T obj)
        {
            return EqualityComparer<C>.Default.GetHashCode(this._getField(obj));
        }
    }

    /// <summary>
    /// 1 FindVisualParent 查找目标类型的父类控件
    /// 2 FindVisualChild  查找目标类型的子类控件
    /// 3 GetPageParmFromList  从页码集合获取页码字符串,如1,2,3 转换成1-3
    /// 4 GetPagesInRange 校验PageRange 输入是否合法,且可返回List<int> Pages  存放的索引值
    /// 5.ShowFileBrowser 显示系统文件浏览器,可以根据传入的路径参数,自动选中对应的文件
    /// 6.CreateFilePath 检查对应路径是否有重名,有重名的情况追加尾号
    /// 7.CreateFolder 检查对应文件夹是否有重名,有重名的情况追加尾号
    /// 8.GetUnitsFromPageSize 将PDF页面宽高转换成对应的单位
    /// 9.GetDpi() 返回当前设备DPI
    /// </summary>
    public static class CommonHelper
    {
        /// <summary>
        /// 自定义Distinct扩展方法
        /// </summary>
        /// <typeparam name="T">要去重的对象类</typeparam>
        /// <typeparam name="C">自定义去重的字段类型</typeparam>
        /// <param name="source">要去重的对象</param>
        /// <param name="getfield">获取自定义去重字段的委托</param>
        /// <returns></returns>
        public static IEnumerable<T> DistinctHelper<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
        {
            return source.Distinct(new Compare<T, C>(getfield));
        }

        /// <summary>
        /// 查找对象目标类型的父类控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T FindVisualParent<T>(DependencyObject obj) where T : class
        {
            try
            {
                while (obj != null)
                {
                    if (obj is T)
                        return obj as T;

                    obj = VisualTreeHelper.GetParent(obj);
                }
                return null;
            }
            catch { return null; }
        }

        /// <summary>
        /// 根据对象查找目标类型的子类
        /// </summary>
        /// <typeparam name="childItem"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static childItem FindVisualChild<childItem>(DependencyObject obj)
             where childItem : DependencyObject
        {
            try
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    if (child != null && child is childItem)
                        return (childItem)child;
                    else
                    {
                        childItem childOfChild = FindVisualChild<childItem>(child);
                        if (childOfChild != null)
                            return childOfChild;
                    }
                }
                return null;
            }
            catch { return null; }
        }

        /// <summary>
        /// 从页码集合获取页码字符串,如1,2,3 转换成1-3
        /// </summary>
        /// <param name="pagesList"></param>
        /// <returns></returns>
        public static string GetPageParmFromList(List<int> pagesList)
        {
            string pageParam = "";
            if (pagesList.Count != 0)
            {
                pagesList.Sort();//先对页码排序

                for (int i = 0; i < pagesList.Count; i++)
                {
                    if (i == 0)
                    {
                        pageParam += pagesList[0].ToString();
                    }
                    else
                    {
                        if (pagesList[i] == pagesList[i - 1] + 1)//页码连续
                        {
                            if (i >= 2)
                            {
                                if (pagesList[i - 1] != pagesList[i - 2] + 1)
                                    pageParam += "-";
                            }
                            else
                                pageParam += "-";

                            if (i == pagesList.Count - 1)
                            {
                                pageParam += pagesList[i].ToString();
                            }
                        }
                        else//页码不连续时
                        {
                            if (i >= 2)
                            {
                                if (pagesList[i - 1] == pagesList[i - 2] + 1)
                                    pageParam += pagesList[i - 1].ToString();
                            }
                            pageParam += "," + pagesList[i].ToString();
                        }
                    }
                }
            }
            return pageParam;
        }

        /// <summary>
        /// 校验PageRange 输入是否合法,且可返回List<int> Pages  存放的索引值
        /// </summary>
        /// <param name="pageIndexList">返回的页面索引集合</param>
        /// <param name="pageRange">需要判断的文本</param>
        /// <param name="count">页面总数</param>
        /// <param name="enumerationSeparator">例 new char[] { ',' }</param>
        /// <param name="rangeSeparator">例 new char[] { '-' }</param>
        /// <param name="inittag"></param>
        /// <returns></returns>
        public static bool GetPagesInRange(ref List<int> pageIndexList, string pageRange, int count, char[] enumerationSeparator, char[] rangeSeparator, bool inittag = false)
        {
            string[] rangeSplit = pageRange.Split(enumerationSeparator);//根据分隔符 拆分字符串

            pageIndexList.Clear();

            foreach (string range in rangeSplit)
            {
                int starttag = 1;
                if (inittag)
                {
                    starttag = 0;
                }
                if (range.Contains("-"))//连续页
                {
                    try
                    {
                        string[] limits = range.Split(rangeSeparator);//对子字符串再根据”-“ 拆分
                        if (limits.Length >= 2 && !string.IsNullOrWhiteSpace(limits[0]) && !string.IsNullOrWhiteSpace(limits[1]))
                        {
                            int start = int.Parse(limits[0]);
                            int end = int.Parse(limits[1]);

                            if ((start < starttag) || (end > count) || (start > end))
                            {
                                return false;
                            }

                            for (int i = start; i <= end; ++i)
                            {
                                if (pageIndexList.Contains(i))
                                {
                                    return false;
                                }

                                pageIndexList.Add(i - 1);
                            }
                            continue;
                        }
                    }
                    catch
                    {
                        return false;
                    }
                }
                int pageNr;
                try
                {
                    // Single page
                    pageNr = int.Parse(range);//单页
                }
                catch//格式不正确时
                {
                    return false;
                }
                if (pageNr < starttag || pageNr > count)
                {
                    return false;
                }
                if (pageIndexList.Contains(pageNr))
                {
                    return false;
                }
                pageIndexList.Add(pageNr - 1);
            }
            return true;
        }

        /// <summary>
        /// 显示系统文件浏览器
        /// </summary>
        /// <param name="selectedFile">要选中的文件路径</param>
        public static void ShowFileBrowser(string selectedFile = null)
        {
            if (string.IsNullOrEmpty(selectedFile))
            {
                Process.Start(@"explorer.exe");
            }
            else
            {
                Process.Start(@"explorer.exe", "/select,\"" + selectedFile + "\"");
            }

        }


        /// <summary>
        /// 检测文件是否重复  追加尾号
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string CreateFilePath(string path)
        {
            int i = 1;
            string oldDestName = path;
            do
            {
                if (File.Exists(path))
                {
                    int lastDot = oldDestName.LastIndexOf('.');

                    string fileExtension = string.Empty;

                    string fileName = oldDestName;

                    if (lastDot > 0)
                    {
                        fileExtension = fileName.Substring(lastDot);

                        fileName = fileName.Substring(0, lastDot);
                    }

                    path = fileName + string.Format(@"({0})", i) + fileExtension;
                }
                ++i;

            } while (File.Exists(path));
            return path;
        }

        /// <summary>
        /// 检查文件夹是否重复  追加尾号
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string CreateFolder(string folder)
        {
            int i = 1;
            string oldDestName = folder;
            DirectoryInfo info = new DirectoryInfo(folder);
            do
            {
                info = new DirectoryInfo(folder);
                if (info.Exists)
                {

                    string fileName = oldDestName;

                    folder = fileName + string.Format(@"({0})", i);
                }
                ++i;

            } while (info.Exists);
            info.Create();
            return folder;
        }

        /// <summary>
        /// 将Document 返回的PageSize 转换成对应单位
        /// </summary>
        /// <param name="size"></param>
        /// <param name="unit"></param>
        /// <returns></returns>
        public static double GetUnitsFromPageSize(double size, PageItemUnits unit = PageItemUnits.MM)
        {
            double sizeWithUnit = 0;
            switch (unit)
            {
                case PageItemUnits.MM:
                    sizeWithUnit = (size * 96 / 72.0) / GetDpi() * 25.4;
                    break;
                case PageItemUnits.CM:
                    sizeWithUnit = (size * 96 / 72.0) / GetDpi() * 25.4 / 10.0;
                    break;
                case PageItemUnits.IN:
                    sizeWithUnit = (size * 96 / 72.0) / GetDpi();
                    break;
                default:
                    break;
            }
            return sizeWithUnit;
        }

        /// <summary>
        /// 返回设备DPI
        /// </summary>
        /// <returns></returns>
        public static double GetDpi()
        {
            BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.NonPublic;
            PropertyInfo property = typeof(SystemParameters).GetProperty("Dpi", bindingAttr);
            return (int)property.GetValue(null, null);
        }
    }
}