using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using ComPDFKitViewer.PdfViewer;
using PDF_Office.Model;
using System.Collections.ObjectModel;
using PDF_Office.Model.PageEdit;
using Prism.Commands;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Controls.Primitives;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Threading;
using Prism.Events;
using PDF_Office.EventAggregators;
using System.Windows.Input;
using PDF_Office.Helper;
using Microsoft.Win32;
using ComPDFKit.PDFDocument;
using PDF_Office.CustomControl;
using PDF_Office.Model.HomePageToolsDialogs;
using System.IO;

namespace PDF_Office.ViewModels.PageEdit
{
    public class PageEditContentViewModel : BindableBase, INavigationAware
    {

        private CPDFViewer PDFViewer;

        private ViewContentViewModel viewContentViewModel;

        private IDialogService dialogs;

        private IEventAggregator eventor;

        /// <summary>
        /// 用于筛选多窗体时间的唯一识别码
        /// </summary>
        private string unicode = null;

        /// <summary>
        /// Undo操作记录栈
        /// 只有插入、移位、旋转，倒序需要记录
        /// </summary>
        private Stack<PageEditHistory> UndoStack = new Stack<PageEditHistory>();

        /// <summary>
        /// Redo操作记录栈
        /// </summary>

        private Stack<PageEditHistory> RedoStack = new Stack<PageEditHistory>();

        /// <summary>
        /// 项数据集合
        /// </summary>
        public ObservableCollection<PageEditItem> PageEditItems { get; set; }

        /// <summary>
        /// 页面范围的项集合
        /// </summary>
        public ObservableCollection<string> PageRangeItems { get; set; }

        #region 属性
        /// <summary>
        /// 是否是第一次加载
        /// </summary>
        private bool isFirstLoad = true;

        /// <summary>
        /// 记录多选项中最后一项的索引
        /// </summary>
        private int maxSelectedIndex = 0;

        private Visibility showTip = Visibility.Collapsed;
        /// <summary>
        /// 是否显示渐隐提示
        /// </summary>
        public Visibility ShowTip
        {
            get { return showTip; }
            set
            {
                SetProperty(ref showTip, value);
            }
        }

        private Visibility isLoading = Visibility.Collapsed;
        /// <summary>
        /// 是否正在处理中
        /// </summary>
        public Visibility IsLoading
        {
            get { return isLoading; }
            set
            {
                SetProperty(ref isLoading, value);
            }
        }


        private int listSelecedIndex;
        /// <summary>
        /// 缩略图选中项的索引
        /// </summary>
        public int ListSelectedIndex
        {
            get { return listSelecedIndex; }
            set
            {
                SetProperty(ref listSelecedIndex, value);
                //显示页面范围选择控件
                TbPageRangeVisibility = Visibility.Visible;
                TbPageRange = (ListSelectedIndex + 1).ToString();
                TxtPageInputVisibility = Visibility.Collapsed;
                if(IsBOTAThumb==Visibility.Visible&&PDFViewer!=null)
                {
                    PDFViewer.GoToPage(listSelecedIndex);
                }
            }
        }

        private bool isMultiSelected;
        /// <summary>
        /// 是否有多选 用于判断倒序和替换功能
        /// </summary>
        public bool IsMultiSelected
        {
            get { return isMultiSelected; }
            set
            {
                SetProperty(ref isMultiSelected, value);
            }
        }


        private int comboxSelectIndex;
        /// <summary>
        /// 下拉框选项集合
        /// </summary>
        public int ComboxSelectIndex
        {
            get { return comboxSelectIndex; }
            set
            {
                SetProperty(ref comboxSelectIndex, value);
                //选中指定的页面范围
                SuitPageRange(comboxSelectIndex);
                //隐藏tb页面范围显示控件
                TbPageRangeVisibility = Visibility.Collapsed;

            }
        }

        private Visibility tbPageRangeVisibility = Visibility.Visible;
        /// <summary>
        /// 页面范围的文本显示
        /// </summary>
        public Visibility TbPageRangeVisibility
        {
            get { return tbPageRangeVisibility; }
            set
            {
                SetProperty(ref tbPageRangeVisibility, value);
                if (value == Visibility.Visible)
                {
                    comboxSelectIndex = -1;
                }
            }
        }

        private string tbPageRange;
        /// <summary>
        /// 页面范围显示的内容
        /// </summary>
        public string TbPageRange
        {
            get { return tbPageRange; }
            set
            {
                SetProperty(ref tbPageRange, value);
            }
        }


        private Visibility txtPageInputVisibility = Visibility.Collapsed;
        /// <summary>
        /// 页面自定义输入框的显示
        /// </summary>
        public Visibility TxtPageInputVisibility
        {
            get { return txtPageInputVisibility; }
            set
            {
                SetProperty(ref txtPageInputVisibility, value);
            }
        }

        /// <summary>
        /// 页面缩放状态，-1 为最小值，1为最大值
        /// </summary>
        private int zoomIndex = 0;

        public int ZoomIndex
        {
            get { return zoomIndex; }
            set
            {
                SetProperty(ref zoomIndex, value);
            }
        }


        private string toastText = "操作失败";
        /// <summary>
        /// Toast提示
        /// </summary>
        public string ToastText
        {
            get { return toastText; }
            set
            {
                SetProperty(ref toastText, value);
            }
        }


        private Visibility isBOTAThumb = Visibility.Collapsed;
        /// <summary>
        /// 是否是BOTA侧边栏的缩略图
        /// </summary>
        public Visibility IsBOTAThumb
        {
            get { return isBOTAThumb; }
            set
            {
                SetProperty(ref isBOTAThumb, value);
            }
        }

        private Visibility hasShowPageSize = Visibility.Collapsed;
        /// <summary>
        /// 是否显示页面尺寸
        /// </summary>
        public Visibility HasShowPageSize
        {
            get { return hasShowPageSize; }
            set
            {
                SetProperty(ref hasShowPageSize, value);
            }
        }

        private bool canUndo;

        /// <summary>
        /// 是否可以进行Undo操作
        /// </summary>
        public bool CanUndo
        {
            get { return canUndo; }
            set
            {
                SetProperty(ref canUndo, value);
                if (viewContentViewModel != null)
                {
                    viewContentViewModel.CanUndo = this.CanUndo;
                }
            }
        }

        private bool canRedo;
        /// <summary>
        /// 是否可以进行Redo操作
        /// </summary>
        public bool CanRedo
        {
            get { return canRedo; }
            set
            {
                SetProperty(ref canRedo, value);
                if(viewContentViewModel!=null)
                {
                    viewContentViewModel.CanRedo = this.CanRedo;
                }
 
            }
        }

        #endregion

        #region 命令
        public DelegateCommand<object> SelectionChangedCommand { get; set; }

        /// <summary>
        /// 拦截键盘输入的事件
        /// </summary>
        public DelegateCommand<object> PreviewKeyDown { get; set; }

        /// <summary>
        /// 响应键盘回车事件
        /// </summary>
        public DelegateCommand<object> KeyDown { get; set; }

        /// <summary>
        /// 替换文件
        /// </summary>
        public DelegateCommand ReplaceCommand { get; set; }

        /// <summary>
        /// 插入文件命令
        /// </summary>
        public DelegateCommand<object> InsertCommand { get; set; }

        /// <summary>
        /// 拆分文件
        /// </summary>
        public DelegateCommand SplitCommand { get; set; }

        /// <summary>
        /// 提取文件
        /// </summary>
        public DelegateCommand ExtractCommand { get; set; }

        /// <summary>
        /// 逆时针旋转
        /// </summary>
        public DelegateCommand LeftRotateCommand { get; set; }

        /// <summary>
        /// 顺时针旋转
        /// </summary>
        public DelegateCommand RightRotateCommand { get; set; }

        /// <summary>
        /// 删除
        /// </summary>
        public DelegateCommand DeleteCommand { get; set; }

        /// <summary>
        /// 倒序
        /// </summary>
        public DelegateCommand ReverseCommand { get; set; }

        /// <summary>
        /// 放大
        /// </summary>
        public DelegateCommand ZoomInCommand { get; set; }

        /// <summary>
        /// 缩小
        /// </summary>
        public DelegateCommand ZoomOutCommand { get; set; }

        /// <summary>
        /// 显示页面大小
        /// </summary>
        public DelegateCommand ShowPageSizeCommand { get; set; }
        #endregion

        public PageEditContentViewModel(IDialogService dialogService, IEventAggregator eventAggregator)
        {
            //变量初始化
            dialogs = dialogService;
            eventor = eventAggregator;
            unicode = App.mainWindowViewModel.SelectedItem.Unicode;
            PageEditItems = new ObservableCollection<PageEditItem>();
            PageRangeItems = new ObservableCollection<string>();

            //绑定命令
            SelectionChangedCommand = new DelegateCommand<object>(SelectionChangedEvent);
            PreviewKeyDown = new DelegateCommand<object>(PreviewKeyDownEvent);
            KeyDown = new DelegateCommand<object>(KeyDownEvent);

            SplitCommand = new DelegateCommand(SplitCommandEvent);
            InsertCommand = new DelegateCommand<object>(InsertCommandEvent);
            ReplaceCommand = new DelegateCommand(ReplaceCommandEvent, CanReplaceCommandExcute).ObservesProperty(() => IsMultiSelected);
            ExtractCommand = new DelegateCommand(ExtractCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex);
            DeleteCommand = new DelegateCommand(DeleteCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex);
            LeftRotateCommand = new DelegateCommand(LeftRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex);
            RightRotateCommand = new DelegateCommand(RightRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex);
            ReverseCommand = new DelegateCommand(ReverseCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex);
            ZoomInCommand = new DelegateCommand(ZoomInCommandEvent, CanZoomIn).ObservesProperty(() => ZoomIndex);
            ZoomOutCommand = new DelegateCommand(ZoomOutCommandEvent, CanZoomOut).ObservesProperty(() => ZoomIndex);
            ShowPageSizeCommand = new DelegateCommand(ShowPageSize);

            //订阅页面刷新事件
            eventAggregator.GetEvent<PageEditRefreshEvent>().Subscribe(OnPageEditRefreshEvent, e => e.Unicode == unicode);


            RefreshPageRangeItem();
        }


        #region 事件
        /// <summary>
        /// 替换功能的逻辑
        /// </summary>
        private async void ReplaceCommandEvent()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Multiselect = false;
            dialog.Filter = PDF_Office.Properties.Resources.OpenDialogFilter;
            if ((bool)dialog.ShowDialog())
            {
                IsLoading = Visibility.Visible;
                await Task.Delay(200);
                int pageCount = PDFViewer.Document.PageCount;
                int insertIndex = listSelecedIndex;

                //从文件插入到指定位置
                var result = await InsertFromFile(listSelecedIndex+1,dialog.FileName);
                if(result)
                {
                    //插入成功后再删除原有页面
                    DoRemoveSelectedPages(new List<int>() { listSelecedIndex });
                }

                ReloadAfterOption(true, true, Tuple.Create(insertIndex-1, insertIndex + pageCount));
                IsLoading = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// 拆分功能的逻辑
        /// </summary>
        private void SplitCommandEvent()
        {
            DialogParameters valuePairs = new DialogParameters();
            valuePairs.Add(ParameterNames.PDFViewer, PDFViewer);
            dialogs.ShowDialog(DialogNames.SplitDialog, valuePairs,e=> { 
                if(e.Result==ButtonResult.OK&&e.Parameters!=null)
                {
                    var model = e.Parameters.GetValue<HomePageSplitDialogModel>(ParameterNames.DataModel);
                    DoSplitPages(model);
                }
            });
        }

        /// <summary>
        /// 提取功能的逻辑
        /// </summary>
        private void ExtractCommandEvent()
        {
            dialogs.ShowDialog(DialogNames.ExtractDialog,null,e=> { 
                if(e.Result==ButtonResult.OK&&e.Parameters!=null)
                {
                    var model = e.Parameters.GetValue<ExtractModel>(ParameterNames.DataModel);
                    DoExtractPages(model.IsEveryPageToFile,model.IsDeleteAfterExtract);
                }
            });
        }

        /// <summary>
        /// 插入功能的逻辑
        /// </summary>
        private async void InsertCommandEvent(object type)
        {
            if((string)type==null)
            {
                return;
            }
            //获取插入位置
            int insertIndex = 0;
            if(listSelecedIndex<0)
            {
                insertIndex = 0;
            }
            else
            {
                insertIndex = listSelecedIndex+1;
                if(isMultiSelected)
                {
                    insertIndex = maxSelectedIndex+1;
                }
            }
            IsLoading = Visibility.Visible;
            await Task.Delay(3);

            PageEditHistory history = new PageEditHistory();
            history.InsertIndex = insertIndex;
            if((string)type==ParameterNames.InsertType_Blank)
            {
                history.Type = ActionType.InsertCustomPages;
                history.InsertFilePath = "";
                //插入空白页面
                bool result;
                if (insertIndex == 0)
                {
                    result = PDFViewer.Document.InsertPage(insertIndex, PageEditItems[insertIndex].Size.Width, PageEditItems[insertIndex].Size.Height, null);
                    history.PageSize = PageEditItems[insertIndex].Size;
                }
                else
                {
                    result = PDFViewer.Document.InsertPage(insertIndex, PageEditItems[insertIndex-1].Size.Width, PageEditItems[insertIndex-1].Size.Height, null);
                    history.PageSize = PageEditItems[insertIndex - 1].Size;
                }
                if(!result)
                {
                    IsLoading = Visibility.Collapsed;
                    ShowToast();
                    return;
                }

                //UI层插入Item
                var item = GetNewPageEditItem(insertIndex);
                PageEditItems.Insert(insertIndex,item);
         

                ReloadAfterOption(true,true,Tuple.Create(insertIndex,insertIndex+1));
                await Task.Delay(10);
                //选中插入的页面
                ListSelectedIndex = insertIndex;
            }
            else if((string)type == ParameterNames.InsertType_File)
            {
                OpenFileDialog dialog = new OpenFileDialog();
                dialog.Multiselect = false;
                dialog.Filter = PDF_Office.Properties.Resources.OpenDialogFilter;
                if ((bool)dialog.ShowDialog())
                {
                    //插入文件
                    var result = await InsertFromFile(insertIndex,dialog.FileName);
                    if(!result)
                    {
                        IsLoading = Visibility.Collapsed;
                        ShowToast();
                        return;
                    }

                    ReloadAfterOption(true,true,Tuple.Create(0,PDFViewer.Document.PageCount));
                }
                IsLoading = Visibility.Collapsed;
                //里面附带了Undo栈记录，需要提前返回，避免重复记录
                return;
            }
            else
            {
                DialogParameters keyValuePairs = new DialogParameters();
                keyValuePairs.Add("CurrentPageSize", PDFViewer.Document.GetPageSize(ListSelectedIndex));
                //插入自定义页面
                dialogs.ShowDialog(DialogNames.InsertDialog, keyValuePairs,e=> { 
                    if(e.Result == ButtonResult.OK&&e.Parameters!=null)
                    {
                        var model = e.Parameters.GetValue<CustomInsertModel>(ParameterNames.DataModel);

                        var result = InsertFromCustomPage(insertIndex, model.width, model.height, model.filepath);
                        if(!result)
                        {
                            return;
                        }

                        history.Type = ActionType.InsertCustomPages;
                        history.InsertFilePath = model.filepath;
                        history.PageSize = new Size(model.width,model.height);

                    }
                });
            }
            IsLoading = Visibility.Collapsed;

            //添加记录到Undo栈，清除Redo栈
            AddToUndoStack(history);
        }

        /// <summary>
        /// 删除选中页面
        /// </summary>
        private async void DeleteCommandEvent()
        {
            IsLoading = Visibility.Visible;
            await Task.Delay(3);
            DoRemoveSelectedPages();
            ReloadAfterOption(true, true, Tuple.Create(0,PDFViewer.Document.PageCount));
            IsLoading = Visibility.Collapsed;
        }

        /// <summary>
        /// 左旋转页面的逻辑
        /// </summary>
        private void LeftRotateCommandEvent()
        {
            RotateSelectedPages(false);
        }

        /// <summary>
        /// 右旋转页面的逻辑
        /// </summary>
        private void RightRotateCommandEvent()
        {
            RotateSelectedPages();
        }

        /// <summary>
        /// 页面倒序的逻辑
        /// </summary>
        private async void ReverseCommandEvent()
        {
            IsLoading = Visibility.Visible;
            await Task.Delay(3);
            List<int> pages = new List<int>();
            for (int i = 0; i <PageEditItems.Count; i++)
            {
                if (PageEditItems[i].Selected)
                {
                    pages.Add(i);
                }
            }
            DoReverse(pages);
           
            IsLoading = Visibility.Collapsed;
        }

        /// <summary>
        /// 将指定页面结合进行倒序
        /// </summary>
        private async void DoReverse(List<int> pages, bool isFromUndoRedo = false)
        {
            if (pages.Count <= 1)
            {
                ShowToast("请至少选择两个图片进行倒序操作。");
                return;
            }
            pages.Sort();

            //记录原位置和目标位置 用于undo，redo
            Dictionary<int, int> sourceTarget = new Dictionary<int, int>();
            for (int i = 0; i < pages.Count; i++)
            {
                int preindex = pages[i];
                int laterIndex = pages[pages.Count - i - 1];//尾部的索引
                if (laterIndex <= preindex)//交换完成
                {
                    //用于记录选中集合为奇数时，最中间Item的还原
                    sourceTarget.Add(preindex, preindex);
                    break;
                }

                var result = ExchangeItem(preindex,laterIndex);
                if(!result)
                {
                    ShowToast();
                    IsLoading = Visibility.Collapsed;
                    return;
                }
                sourceTarget.Add(preindex, laterIndex);
            }

            await Task.Delay(20);
            //转换成页码数据集合，传递给UI，选中目标页面
            //因虚拟化加载的问题，通过Selected来控制Item选中效果会有问题
            List<int> pageRange = new List<int>();
            for (int i = 0; i < pages.Count; i++)
            {
                pageRange.Add(pages[i] + 1);
            }

            NotifyUIToRefresh(pageRange);

            ReloadAfterOption(true, true, null);

            if(!isFromUndoRedo)
            {
                PageEditHistory history = new PageEditHistory();
                history.Type = ActionType.Reverse;
                history.SourceTargetValue = sourceTarget;
                AddToUndoStack(history);
            }
        }

        /// <summary>
        /// 交换两个Item顺序
        /// </summary>
        /// <param name="preiIndex"></param>
        /// <param name="laterIndex"></param>
        /// <returns></returns>
        private bool ExchangeItem(int preiIndex,int laterIndex)
        {
            if (preiIndex == laterIndex)
            {
                return true;
            }
            var sourceitem = PageEditItems[preiIndex];
            var targetitem = PageEditItems[laterIndex];

            var result = PDFViewer.Document.ExchangePage(preiIndex, laterIndex);
            if (!result)
            {
                return false;
            }

            PageEditItems.Remove(sourceitem);
            PageEditItems.Remove(targetitem);
            PageEditItems.Insert(preiIndex, targetitem);
            PageEditItems.Insert(laterIndex, sourceitem);

            //PageEditItems.Remove(targetitem);
            //PageEditItems.Insert(laterIndex, sourceitem);
            //PageEditItems.Remove(sourceitem);
            //PageEditItems.Insert(preiIndex, targetitem);
            return true;
        }

        /// <summary>
        /// 是否可以执行文件操作命令  除插入、拆分外
        /// </summary>
        /// <returns></returns>
        private bool CanFileCommandExcute()
        {
            if (ListSelectedIndex < 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 校验是否可以替换
        /// </summary>
        /// <returns></returns>
        private bool CanReplaceCommandExcute()
        {
            return !IsMultiSelected;
        }

        /// <summary>
        /// 放大页面
        /// </summary>
        private void ZoomInCommandEvent()
        {
            ChangeItemSize(new Size(PageEditItems[0].ItemSize.Width *2, PageEditItems[0].ItemSize.Height *2));
            ZoomIndex++;

            NotifyUIToRefresh();
        }

        /// <summary>
        /// 缩小页面
        /// </summary>
        private void ZoomOutCommandEvent()
        {
            ChangeItemSize(new Size(PageEditItems[0].ItemSize.Width / 2, PageEditItems[0].ItemSize.Height / 2));
            ZoomIndex--;
            NotifyUIToRefresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="newsize"></param>
        public void ChangeItemSize(Size newsize)
        {
            for (int i = 0; i < PageEditItems.Count; i++)
            {
                PageEditItems[i].ItemSize = newsize;
            }
            //缩略图模式 调整item大小的时候，更新选中项
            NotifyUIToRefresh(new List<int>() { PDFViewer.CurrentIndex + 1 });
        }

        private bool CanZoomIn()
        {
            if (ZoomIndex >= 1)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        private bool CanZoomOut()
        {
            if (ZoomIndex <= -1)
            {
                return false;
            }
            else
            {
                return true;
            }
        }


        /// <summary>
        /// 响应UI发送刷新图片的事件
        /// </summary>
        /// <param name="e"></param>
        private void OnPageEditRefreshEvent(PageEditRefreshEventArgs e)
        {
            //UI发送事件过来通知刷新图片时
            //调整逻辑,前后预加载5页
            RefreshItemImage(e.PageRange.Item1 - 2, e.PageRange.Item2 + 2);
        }

        /// <summary>
        /// 选项改变事件  
        /// 虚拟化的时候不会触发选中事件
        /// </summary>
        /// <param name="e"></param>
        private void SelectionChangedEvent(object e)
        {
            var args = e as SelectionChangedEventArgs;
            //下下策 从UI控件获取所有选项的集合
            var listbox = args.OriginalSource as ListBox;
            if (TbPageRangeVisibility == Visibility.Visible && args != null)
            {
                List<int> pagelist = new List<int>();
                for (int i = 0; i < listbox.SelectedItems.Count; i++)
                {
                    if (!pagelist.Contains((listbox.SelectedItems[i] as PageEditItem).PageNumber))
                    {
                        pagelist.Add((listbox.SelectedItems[i] as PageEditItem).PageNumber);
                    }
                }

                ////根据选中的范围 适配全部页面范围、奇数页面范围等
                //if (pagelist.Count == PageEditItems.Count)
                //{
                //    ComboxSelectIndex = 0;
                //    return;
                //}

                string pageparm = CommonHelper.GetPageParmFromList(pagelist);
                TbPageRange = pageparm;
            }

            //判断是否有选中多项
            if (listbox.SelectedItems.Count > 1)
            {
                IsMultiSelected = true;
                maxSelectedIndex = listbox.Items.IndexOf(listbox.SelectedItems[listbox.SelectedItems.Count - 1]);
            }
            else
            {
                IsMultiSelected = false;
            }
        }

        /// <summary>
        /// 限制文本框输入内容
        /// </summary>
        /// <param name="e"></param>
        private void PreviewKeyDownEvent(object e)
        {
            var args = e as KeyEventArgs;
            if (args == null)
            {
                return;
            }

            if (args.Key != Key.Enter && args.Key != Key.Back && args.Key != Key.OemComma && args.Key != Key.Subtract && !((args.Key >= Key.D0 && args.Key <= Key.D9) || (args.Key >= Key.NumPad0 && args.Key <= Key.NumPad9)))
            {
                args.Handled = true;
            }
        }

        /// <summary>
        /// 响应回车确认事件
        /// </summary>
        /// <param name="e"></param>
        private void KeyDownEvent(object e)
        {
            var args = e as KeyEventArgs;
            if (args == null)
            {
                return;
            }
            if (args.Key == Key.Enter)
            {
                List<int> TargetPageIndexs = new List<int>();
                var result = CommonHelper.GetPagesInRange(ref TargetPageIndexs, (args.OriginalSource as TextBox).Text, PDFViewer.Document.PageCount, new char[] { ',', '，' }, new char[] { '-' });
                if (!result)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("","请输入有效范围","OK");
                    return;
                }

                //选中输入的页面范围
                List<int> pageRange = new List<int>();
                for (int i = 0; i < PageEditItems.Count; i++)
                {
                    if (TargetPageIndexs.Contains(PageEditItems[i].PageNumber - 1))
                    {
                        pageRange.Add(i+1);
                    }
                }

                NotifyUIToRefresh(pageRange);
            }
        }

        #endregion

        #region 方法

        /// <summary>
        /// 页面编辑执行Undo操作的方法
        /// </summary>
        private async void Undo()
        {
            var history = UndoStack.Pop();
            PageEditHistory redoHistory = new PageEditHistory();
            switch (history.Type)
            {
                case ActionType.RightRotate:
                    var rightlist = history.SourceTargetValue.Keys.ToList<int>();
                    RotateSelectedPages(false, rightlist,true);

                    redoHistory.SourceTargetValue = history.SourceTargetValue;
                    redoHistory.Type = ActionType.LeftRotate;
                    break;
                case ActionType.LeftRotate:
                    var leftlist = history.SourceTargetValue.Keys.ToList<int>();
                    RotateSelectedPages(true, leftlist,true);

                    redoHistory.SourceTargetValue = history.SourceTargetValue;
                    redoHistory.Type = ActionType.RightRotate;
                    break;
                case ActionType.InsertFromFile:
                    List<int> pageList = new List<int>();
                    for(int i=0;i<history.InsertPageCount;i++)
                    {
                        pageList.Add(history.InsertIndex+i);
                    }
                    DoRemoveSelectedPages(pageList, true);
                    redoHistory = history;
                    break;
                case ActionType.InsertCustomPages:
                    DoRemoveSelectedPages(new List<int> {history.InsertIndex},true);
                    redoHistory = history;
                    break;
                case ActionType.DragSort:
                    //将字典倒序后，将每个Source的值恢复到Key的位置
                    var SourceTargets = history.SourceTargetValue;
                    var keys = SourceTargets.Keys.ToArray();
                    Array.Reverse(keys);
                    foreach(var key in keys)
                    {
                        MoveItemToIndex(SourceTargets[key], key);
                    }
                    //刷新页码等
                    ReloadAfterOption(true,true,new Tuple<int, int>(0,PDFViewer.Document.PageCount));

                    List<int> selectedPages = new List<int>();
                    //将索引集合转换成页码集合
                    foreach(var key in SourceTargets.Keys)
                    {
                        selectedPages.Add(key+1);
                    }
                    //通知UI选中Item
                    NotifyUIToRefresh(selectedPages);
                    redoHistory = history;
                    break;
                case ActionType.Reverse:
                    //将字典倒序后，将每个Source的值恢复到Key的位置
                    var SourceTarget = history.SourceTargetValue;
                    var pres = SourceTarget.Keys.ToArray();
                    foreach (var key in pres)
                    {
                        if (key != SourceTarget[key])
                        {
                            ExchangeItem(key, SourceTarget[key]);
                        }
                    }

                    await Task.Delay(20);
                    //刷新页码等
                    ReloadAfterOption(true, true, null);

                    List<int> Pages = new List<int>();
                    //将索引集合转换成页码集合
                    foreach (var key in SourceTarget.Keys)
                    {
                        Pages.Add(key + 1);
                    }
                    foreach(var key in SourceTarget.Values)
                    {
                        Pages.Add(key + 1);
                    }
                    //通知UI选中Item
                    NotifyUIToRefresh(Pages);
                    redoHistory = history;
                    break;
                default:
                    break;
            }
            RedoStack.Push(redoHistory);
            CanRedo = true;
            //检查是否可以再进行Undo
            if(UndoStack.Count<=0)
            {
                this.CanUndo = false;
            }
        }

        /// <summary>
        /// 页面编辑执行Redo操作的方法
        /// </summary>
        private async void Redo()
        {
            var history = RedoStack.Pop();
            PageEditHistory undoHistory = new PageEditHistory();
            switch (history.Type)
            {
                case ActionType.RightRotate:
                    var rightlist = history.SourceTargetValue.Keys.ToList<int>();
                    RotateSelectedPages(false, rightlist,true);

                    undoHistory.SourceTargetValue = history.SourceTargetValue;
                    undoHistory.Type = ActionType.LeftRotate;
                    break;
                case ActionType.LeftRotate:
                    var leftlist = history.SourceTargetValue.Keys.ToList<int>();
                    RotateSelectedPages(true, leftlist,true);
                    undoHistory.SourceTargetValue = history.SourceTargetValue;
                    undoHistory.Type = ActionType.RightRotate;
                    break;
                case ActionType.InsertFromFile:
                    await InsertFromFile(history.InsertIndex,history.InsertFilePath,history.InsertFilePassWord,true);
                    ReloadAfterOption(true, true, Tuple.Create(history.InsertIndex-1, history.InsertIndex+history.InsertPageCount));
                    undoHistory = history;
                    break;
                case ActionType.InsertCustomPages:
                    InsertFromCustomPage(history.InsertIndex, history.PageSize.Width, history.PageSize.Height, history.InsertFilePath);
                    ListSelectedIndex = history.InsertIndex;
                    undoHistory = history;
                    break;
                case ActionType.DragSort:
                    DragToSort(history.InsertIndex,history.SourceTargetValue.Keys.ToList<int>(),true);
                    undoHistory = history;
                    break;
                case ActionType.Reverse:
                    var list = history.SourceTargetValue.Keys.ToList<int>().Union(history.SourceTargetValue.Values.ToList<int>()).ToList<int>();
                    DoReverse(list, true);
                    undoHistory = history;
                    break;
                default:
                    break;
            }
            UndoStack.Push(undoHistory);
            CanUndo = true;
            if (RedoStack.Count <= 0)
            {
                this.CanRedo = false;
            }
        }

        /// <summary>
        /// 退出页面编辑面试，回到阅读页
        /// </summary>
        public void BackToPDFViewer(int PageIndex)
        {
            PDFViewer.GoToPage(PageIndex);
            viewContentViewModel.ExitToolMode();
        }

        /// <summary>
        /// 显示Toast提示
        /// </summary>
        private void ShowToast(string content="")
        {
            if (!string.IsNullOrEmpty(content))
            {
                ToastText = content;
            }
            else
            {
                ToastText = "操作失败";
            }
            ShowTip = Visibility.Visible;
        }

        /// <summary>
        /// 通知UI刷新页面范围
        /// 或通过xaml来设置选中项
        /// </summary>vb nmjvcx
        private void NotifyUIToRefresh(List<int> pageRange=null)
        {
            if (pageRange == null || pageRange.Count <= 0)
            {
                //通知UI刷新页面范围
                eventor.GetEvent<PageEditNotifyEvent>().Publish(new PageEditNotifyEventArgs(unicode));
            }
            else
            {
                //通知UI刷新页面范围
                eventor.GetEvent<PageEditNotifyEvent>().Publish(new PageEditNotifyEventArgs(unicode,NotifyType.SelectItems,pageRange));
            }
        }

        /// <summary>
        /// 删除选中项的方法 不带Reload操作
        /// 方便其他逻辑中调用
        /// </summary>
        private void DoRemoveSelectedPages(List<int> pageList = null, bool isFromUndoRedo = false)
        {
            List<int> indexList = new List<int>();
            if (pageList == null || pageList.Count < 0)
            {
                for (int i = 0; i < PageEditItems.Count; i++)
                {
                    if (PageEditItems[i].Selected)
                    {
                        indexList.Add(i);
                    }
                }
            }
            else
            {
                indexList = pageList;
            }
            
            if(indexList.Count>0&& indexList.Count==PDFViewer.Document.PageCount)
            {
                AlertsMessage alertsMessage = new AlertsMessage();
                alertsMessage.ShowDialog("","不能删除所有页面","OK");
                return;
            }

            var result = PDFViewer.Document.RemovePages(indexList.ToArray());
            if (!result)
            {
                 ShowToast();
                return;
            }

            //文档层操作成功后再删除UI层
            for (int i = indexList.Count - 1; i >= 0; i--)
            {
                PageEditItems.RemoveAt(indexList[i]);
            }

            if (!isFromUndoRedo)
            {
                //清除页面编辑Undo，Redo栈
                UndoStack.Clear();
                RedoStack.Clear();
                this.CanUndo = false;
                this.CanRedo = false;
            }
        }

        /// <summary>
        /// 提取选中页面的方法
        /// </summary>
        /// <param name="isEveryPageToFile">是否每页生成一个文件</param>
        /// <param name="isDeleteAfterExtract">是否提取后删除页面</param>
        private async void DoExtractPages(bool isEveryPageToFile,bool isDeleteAfterExtract)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (string.IsNullOrEmpty(dialog.SelectedPath))
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("","","OK");//补充提示文案
                    return;
                }
            }
            else
                return;

            string selectedfile = "";
            IsLoading = Visibility.Visible;
            await Task.Delay(3);
            List<int> pagenums = new List<int>();
            for(int i=0;i<PageEditItems.Count;i++)
            {
                if(PageEditItems[i].Selected)
                {
                    pagenums.Add(PageEditItems[i].PageNumber);
                }
            }

            if (isEveryPageToFile)
            {
                //每页生成的单独的文件
                for (int i = 0; i < pagenums.Count; i++)
                {
                    string filename = PDFViewer.Document.FileName + " " + pagenums[i] + ".pdf";
                    string path = System.IO.Path.Combine(dialog.SelectedPath, filename);
                    path = CommonHelper.CreateFilePath(path);
                    selectedfile = path;
                    CPDFDocument savedoc = CPDFDocument.CreateDocument();
                    bool result = savedoc.ImportPages(PDFViewer.Document, pagenums[i].ToString());
                    if (!result)
                    {
                        savedoc.Release();
                        continue;
                    }
                    result = savedoc.WriteToFilePath(path);
                    if (!result)
                    {
                        savedoc.Release();
                        continue;
                    }
                    savedoc.Release();//释放内存
                }
            }
            else//全部生成一个文件
            {
                string filename = PDFViewer.Document.FileName + " " + CommonHelper.GetPageParmFromList(pagenums) + ".pdf";
                string path = System.IO.Path.Combine(dialog.SelectedPath, filename);
                path = CommonHelper.CreateFilePath(path);
                selectedfile = path;
                CPDFDocument savedoc = CPDFDocument.CreateDocument();
                string range = String.Join(",", pagenums);
                bool result = savedoc.ImportPages(PDFViewer.Document, range);
                if (!result)
                {
                     ShowToast();
                    IsLoading = Visibility.Collapsed;
                    return;
                }
                result = savedoc.WriteToFilePath(path);
                if (!result)
                {
                     ShowToast();
                }
                savedoc.Release();//释放内存
            }

            if(isDeleteAfterExtract)
            {
                DoRemoveSelectedPages();
                ReloadAfterOption(true,true,Tuple.Create(0,PDFViewer.Document.PageCount));
            }

            CommonHelper.ShowFileBrowser(selectedfile);
            IsLoading = Visibility.Collapsed;
        }

        private void DoSplitPages(HomePageSplitDialogModel model)
        {
            try
            {

                var pdfViewer = PDFViewer;

                System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
                //dialog.Description = App.MainPageLoader.GetString("Main_OpenFolderNoteWarning"); ;
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    if (string.IsNullOrEmpty(dialog.SelectedPath))
                    {
                        return;
                    }
                }
                else
                    return;

                var data = model;
                int PageCount = pdfViewer.Document.PageCount;
                string selectedfile = "";
                if (data.Mode == HomePageSplitDialogModel.SplitMode.AveragePages)
                {
                    int perPages = Convert.ToInt32(data.GetModeCount);
                    int SplitCount = (int)Math.Ceiling((double)PageCount / (double)perPages);
                    //TODO:命名规则是否要调整
                    selectedfile = data.FileName + " " + "1.pdf";
                    for (int i = 0; i < SplitCount; i++)
                    {
                        int startNum = i * perPages + 1;
                        int endNum = Math.Min(PageCount, (i + 1) * perPages);
                        string range = startNum.ToString() + "-" + endNum.ToString();
                        CPDFDocument savedoc = CPDFDocument.CreateDocument();
                        bool result = savedoc.ImportPages(pdfViewer.Document, range);
                        if (!result)
                        {
                            savedoc.Release();
                            continue;
                        }
                        string filename = data.FileName + " " + (i + 1) + ".pdf";
                        string path = System.IO.Path.Combine(dialog.SelectedPath, filename);
                        path = CommonHelper.CreateFilePath(path);
                        result = savedoc.WriteToFilePath(path);
                        if (!result)
                        {
                            savedoc.Release();
                            continue;
                        }
                        savedoc.Release();
                        selectedfile = path;
                    }
                }
                else if (data.Mode == HomePageSplitDialogModel.SplitMode.AverageFiles)
                {
                    int docCount = Convert.ToInt32(data.GetModeCount);
                    int avePages = (int)Math.Floor((double)PageCount / (double)docCount);
                    int remain = PageCount % docCount;
                    int startNum = 1;
                    //TODO:命名规则是否要调整
                    selectedfile = data.FileName + " " + "1.pdf";
                    for (int i = 0; i < docCount; i++)
                    {
                        int endNum = startNum + (avePages - 1);
                        if (i < remain) endNum++;
                        endNum = Math.Min(endNum, PageCount);
                        string range = startNum + "-" + endNum;
                        startNum = endNum + 1;
                        string fileName = data.FileName + " " + (i + 1) + ".pdf";
                        string path = System.IO.Path.Combine(dialog.SelectedPath, fileName);
                        path = CommonHelper.CreateFilePath(path);
                        CPDFDocument savedoc = CPDFDocument.CreateDocument();
                        bool result = savedoc.ImportPages(pdfViewer.Document, range);
                        if (!result)
                        {
                            savedoc.Release();
                            continue;
                        }
                        result = savedoc.WriteToFilePath(path);
                        if (!result)
                        {
                            savedoc.Release();
                            continue;
                        }
                        savedoc.Release();
                        selectedfile = path;

                    }
                }
                else//自定义页码范围
                {
                    string pageRange="";
                    if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.OddPage)
                    {
                        int[] page = new int[(PageCount + 1) / 2];
                        for (int i = 0; i < page.Length; i++)
                        {
                            page[i] = i * 2 + 1;
                        }
                        pageRange = string.Join(",", page);
                    }
                    else if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.EvenPage)
                    {
                        int[] page = new int[PageCount / 2];
                        for (int i = 0; i < page.Length; i++)
                        {
                            page[i] = i * 2 + 2;
                        }
                        pageRange = string.Join(",", page);
                    }
                    List<int> pageList1 = new List<int>();
                    //如果是自定义输入页面范围的话，直接解析
                    CommonHelper.GetPagesInRange(ref pageList1, pageRange, PageCount, new char[] { ',' }, new char[] { '-' });
                    //part1
                    selectedfile = "";
                    CPDFDocument saveDoc1 = CPDFDocument.CreateDocument();
                    string filepath = data.FileName + " " + "1.pdf";
                    string path1 = Path.Combine(dialog.SelectedPath, filepath);
                    path1 = CommonHelper.CreateFilePath(path1);
                    bool result = saveDoc1.ImportPages(pdfViewer.Document, pageRange);
                    if (!result)
                    {
                        saveDoc1.Release();
                         ShowToast();
                        return;
                    }
                    result = saveDoc1.WriteToFilePath(path1);
                    if (!result)
                    {
                        saveDoc1.Release();
                         ShowToast();
                        return;
                    }
                    saveDoc1.Release();
                    //Part2
                    List<int> pageList2 = new List<int>();
                    for (int i = 1; i <= pdfViewer.Document.PageCount; i++)
                    {
                        if (!pageList1.Contains(i - 1))//pagelist1 存放的是index
                            pageList2.Add(i);
                    }
                    string pageRange2 = string.Join(",", pageList2);
                    CPDFDocument saveDoc2 = CPDFDocument.CreateDocument();
                    string filepath2 = data.FileName + " " + "2.pdf";
                    string path2 = Path.Combine(dialog.SelectedPath, filepath2);
                    path2 = CommonHelper.CreateFilePath(path2);
                    result = saveDoc2.ImportPages(pdfViewer.Document, pageRange2);
                    if (!result)
                    {
                        saveDoc2.Release();
                         ShowToast();
                        return;
                    }
                    result = saveDoc2.WriteToFilePath(path2);
                    if (!result)
                    {
                        saveDoc2.Release();
                         ShowToast();
                        return;
                    }
                    selectedfile = path1;
                    saveDoc2.Release();
                }
                //显示文件夹，并选中一个文件
                Process.Start("explorer", "/select,\"" + selectedfile + "\"");
            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// 将文件插入到指定位置
        /// </summary>
        /// <param name="insertIndex"></param>
        public async Task<bool> InsertFromFile(int insertIndex, string filePath, string oldPassWord = null, bool isFromUndoRedo = false)
        {
            CPDFDocument doc = CPDFDocument.InitWithFilePath(filePath);
            if (doc == null)
            {
                 ShowToast();
                return false;
            }
            string password = "";
            if (doc.IsLocked)
            {
                if(!string.IsNullOrEmpty(oldPassWord))
                {
                    var result =  doc.UnlockWithPassword(oldPassWord);
                    if(result)
                    {
                        password = oldPassWord;
                    }
                }

                //没有传入密码，或者用传入密码解密失败是，需要弹出界面弹窗
                if (doc.IsLocked)
                {
                    DialogParameters value = new DialogParameters();
                    value.Add(ParameterNames.PDFDocument, doc);
                    bool result = true;
                    dialogs.ShowDialog(DialogNames.VerifyPassWordDialog, value, e =>
                     {
                         if (e.Result != ButtonResult.OK)
                         {
                             result = false;
                         }
                         password = e.Parameters.GetValue<string>(ParameterNames.PassWord);
                     });
                    if (!result)
                    {
                        return false;
                    }
                }
            }

           int pageCount = doc.PageCount;

            //插入整个新文档
            //文档层插入

            var insertresult = PDFViewer.Document.ImportPagesAtIndex(doc, "1-" + pageCount, insertIndex);
            if (!insertresult)
            {
                ShowToast();
                return false;
            }
            //插入成功后释放临时Document对象
            doc.Release();


            //UI层插入
            for (int i = 0; i < pageCount; i++)
            {
                var item = GetNewPageEditItem(i);
                PageEditItems.Insert(insertIndex + i, item);
            }

            //加一点延时才能显示选中效果
            await Task.Delay(200);
            List<int> pageRange = new List<int>();
            for (int i = 0; i < pageCount; i++)
            {
                pageRange.Add(insertIndex+i+1);
            }
            NotifyUIToRefresh(pageRange);

            //如果是undo redo里调用本方法，则不需要添加到Undo栈
            if (!isFromUndoRedo)
            {
                //添加记录到Undo栈，清空Redo栈
                PageEditHistory history = new PageEditHistory();
                history.Type = ActionType.InsertFromFile;
                history.InsertIndex = insertIndex;
                history.InsertFilePath = filePath;
                history.InsertFilePassWord = password;
                history.InsertPageCount = pageCount;

                AddToUndoStack(history);
            }
            return true;
        }

        /// <summary>
        /// 添加记录到Undo栈
        /// </summary>
        /// <param name="history"></param>
        private void AddToUndoStack(PageEditHistory history)
        {
            UndoStack.Push(history);
            CanUndo = true;
            RedoStack.Clear();
            CanRedo = false;
        }

        /// <summary>
        /// 插入自定义页面
        /// </summary>
        /// <param name="insertIndex"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private bool InsertFromCustomPage(int insertIndex,double width,double height,string filePath)
        {
            //文档层插入
            var result = PDFViewer.Document.InsertPage(insertIndex, width, height, string.IsNullOrEmpty(filePath)?null:filePath);
            if (!result)
            {
                ShowToast();
                return false;
            }
            PageEditItem item = new PageEditItem();
            PageEditItems.Insert(insertIndex, item);
            ReloadAfterOption(true, true, Tuple.Create(insertIndex - 1, insertIndex + 1));
            return true;
        }

        /// <summary>
        /// 根据索引创建新的Item
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private PageEditItem GetNewPageEditItem(int index)
        {
            PageEditItem item = new PageEditItem();
            if (PDFViewer.Document.PageAtIndex(index).Rotation % 2 != 0)
            {
                ///标记为横向页面
                item.isVertical = false;
            }
            item.PageNumber = index + 1;
            var pagesize = PDFViewer.Document.GetPageSize(index);
            item.Size = pagesize;
            double width = CommonHelper.GetUnitsFromPageSize(pagesize.Width);
            double height = CommonHelper.GetUnitsFromPageSize(pagesize.Height);
            item.PageSize = $"{width.ToString("F2")}mm*{height.ToString("F2")} mm";
            return item;
        }

        /// <summary>
        /// 进行文件操作后刷新PDFView
        /// 清除undo 栈
        /// 重加载Document
        /// 设置保存状态
        /// </summary>
        /// <param name="needRefreshPageNum">是否需要刷新页码</param>
        /// <param name="needClearUndoHistory">是否需要清空注释Undo栈</param>
        /// <param name="pageRange">需要刷新的页面范围图片</param>
        public void ReloadAfterOption(bool needRefreshPageNum = false, bool needClearUndoHistory = true, Tuple<int, int> pageRange = null)
        {
            if (needRefreshPageNum)
            {
                RefreshPageNum();
            }
            if (needClearUndoHistory)
            {
                PDFViewer.UndoManager.ClearHistory();
            }
            if (pageRange != null)
            {
                if (pageRange.Item2 - pageRange.Item1 > 30)
                {
                    //范围较大时，通知UI获取更准确的刷新范围
                    NotifyUIToRefresh();
                }
                else
                {
                    RefreshItemImage(pageRange.Item1, pageRange.Item2);
                }
            }
            PDFViewer.UndoManager.CanSave = true;
            PDFViewer.ReloadDocument();
        }

        /// <summary>
        /// 旋转所有选中页面
        /// </summary>
        /// <param name="rightRotate"></param>
        private async void RotateSelectedPages(bool rightRotate = true,List<int> pageitems=null,bool isFromUndoRedo = false)
        {
            IsLoading = Visibility.Visible;
            await Task.Delay(2);
            Dictionary<int, int> items = new Dictionary<int, int>();
            if (pageitems == null)
            {
                //旋转选中页面
                for (int i = 0; i < PageEditItems.Count; i++)
                {
                    if (PageEditItems[i].Selected)
                    {
                        //逆时针旋转传 - 1  顺时针旋转传1
                        PDFViewer.Document.RotatePage(i, rightRotate ? 1 : -1);
                        PDFViewer.Document.ReleasePages(i);
                        items.Add(i, i);

                        //重新拿图
                        PageEditItems[i].isVertical = !PageEditItems[i].isVertical;
                        PageEditItems[i].IsGetImage = false;
                    }
                }
            }
            else
            {
                //旋转对应Items集合
                for (int i = 0; i < pageitems.Count; i++)
                {
                    PDFViewer.Document.RotatePage(pageitems[i], rightRotate ? 1 : -1);
                    PDFViewer.Document.ReleasePages(pageitems[i]);
                    items.Add(pageitems[i], pageitems[i]);

                    //重新拿图
                    PageEditItems[pageitems[i]].isVertical = !PageEditItems[pageitems[i]].isVertical;
                    PageEditItems[pageitems[i]].IsGetImage = false;
                }
            }

            //如果是undo,Redo里调用的方法，则不记录到栈里
            if (!isFromUndoRedo)
            {
                //记录进Undo栈
                PageEditHistory history = new PageEditHistory();
                history.Type = rightRotate ? ActionType.RightRotate : ActionType.LeftRotate;
                history.SourceTargetValue = items;
                AddToUndoStack(history);
            }

            ReloadAfterOption(false, true, Tuple.Create(0, PageEditItems.Count));
            IsLoading = Visibility.Collapsed;
        }

        /// <summary>
        /// 刷新页码
        /// </summary>
        private void RefreshPageNum()
        {
            for (int i = 0; i < PageEditItems.Count; i++)
            {
                PageEditItems[i].PageNumber = i + 1;
                PageEditItems[i].ShowPageSize = HasShowPageSize == Visibility.Visible ? true : false;
            }
            
        }

        /// <summary>
        /// 刷新页面范围下拉框
        /// </summary>
        private void RefreshPageRangeItem()
        {
            PageRangeItems.Clear();
            PageRangeItems.Add("所有页面");
            PageRangeItems.Add("奇数页");
            PageRangeItems.Add("偶数页");
            PageRangeItems.Add("横向页面");
            PageRangeItems.Add("纵向页面");
            PageRangeItems.Add("自定义");
        }


        /// <summary>
        /// 选中目标页面范围的页面
        /// </summary>
        /// <param name="index">页面范围选中项索引</param>
        private void SuitPageRange(int index)
        {
            List<int> pageRange = new List<int>();
            switch (index)
            {
                case 0:
                    for (int i = 0; i < PageEditItems.Count; i++)
                    {
                        pageRange.Add(i+1);
                    }
                    break;

                case 1:
                    //奇数页
                    for (int i = 0; i < PageEditItems.Count; i++)
                    {
                        if (i % 2 == 0)
                        {
                            pageRange.Add(i + 1);
                        }
                    }
                    break;
                case 2:
                    //偶数页
                    for (int i = 0; i < PageEditItems.Count; i++)
                    {
                        if (i % 2 != 0)
                        {
                            pageRange.Add(i + 1);
                        }
                    }
                    break;
                case 3://横向页面
                    for (int i = 0; i < PageEditItems.Count; i++)
                    {
                        if (PDFViewer.Document.PageAtIndex(i).Rotation % 2 != 0)
                        {
                            pageRange.Add(i + 1);
                        }
                    }
                    break;
                case 4://纵向页面
                    for (int i = 0; i < PageEditItems.Count; i++)
                    {
                        if (PDFViewer.Document.PageAtIndex(i).Rotation % 2 == 0)
                        {
                            pageRange.Add(i + 1);
                        }
                    }
                    break;
                case 5://自定义
                    //取消所有选中
                    ListSelectedIndex = -1;
                    TxtPageInputVisibility = Visibility.Visible;
                    break;
                default:
                    break;
            }
            if(pageRange.Count>0)
            {
                NotifyUIToRefresh(pageRange);
            }
        }


        /// <summary>
        /// 是否显示页面尺寸
        /// </summary>
        /// <param name="show">是或否</param>
        private void ShowPageSize()
        {
            bool show = true;
            if(HasShowPageSize== Visibility.Visible)
            {
                show = false;
                HasShowPageSize = Visibility.Collapsed;
            }
            else
            {
                show = true;
                HasShowPageSize = Visibility.Visible;
            }
            for (int i = 0; i < PageEditItems.Count; i++)
            {
                PageEditItems[i].ShowPageSize = show;
            }
        }


        /// <summary>
        /// 从PDFView获取所有Items集合
        /// </summary>
        private void GetSourceItems(bool isFirstLoad)
        {
            if (isFirstLoad||IsBOTAThumb==Visibility.Visible)
            {
                PageEditItems.Clear();
                for (int i = 0; i < PDFViewer.Document.PageCount; i++)
                {
                    var item = GetNewPageEditItem(i);
                    PageEditItems.Add(item);
                }
            }
            else
            {
                //后续进来仅刷新图片即可
                for (int i = 0; i < PageEditItems.Count; i++)
                {
                    PageEditItems[i].IsGetImage = false;
                }
            }
        }

        /// <summary>
        /// 刷新书签列表
        /// </summary>
        public void RefreshBookMarkList()
        {
            if (PDFViewer != null)
            {
                var booklist = PDFViewer.Document.GetBookmarkList();
                if (booklist == null)
                {
                    return;
                }
                //获取所有书签的Index集合
                List<int> marks = new List<int>();
                for (int i = 0; i < booklist.Count; i++)
                {
                    marks.Add(booklist[i].PageIndex);
                }

                //不能只遍历marks集合，考虑书签集合元素删除的情况
                for (int k = 0; k < PageEditItems.Count; k++)
                {
                    if (marks.Contains(k))
                        PageEditItems[k].HaveBookMark = true;
                    else
                        PageEditItems[k].HaveBookMark = false;
                }
            }
        }

        /// <summary>
        /// 刷新指定范围的图片
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        private async void RefreshItemImage(int startIndex, int endIndex)
        {
            for (int i = startIndex; i <= endIndex; i++)
            {
                if (i <= PDFViewer.Document.PageCount - 1 && i >= 0 && PageEditItems.Count > 0)
                {
                    //宽高为样式中图片控件宽高
                    if (PageEditItems[i].isVertical)
                    {
                        await PDFViewer.GetThumbnail(i, 208, 294);
                    }
                    else
                    {
                        //获取横图
                        await PDFViewer.GetThumbnail(i, 294, 208);
                    }
                }
            }
        }

        /// <summary>
        /// 拖拽排序功能
        /// </summary>
        /// <param name="targetIndex"></param>
        /// <param name="pageIndexs"></param>
        public void DragToSort(int targetIndex,List<int> pageIndexs,bool IsFromUndoRedo =false)
        {
            //拖拽排序后需要重新选中项的集合
            List<int> selectedPages = new List<int>();

            //记录原位置和目标位置的字典，用于Undo，Redo恢复
            Dictionary<int, int> SourceTargetValue = new Dictionary<int, int>();

            bool result = false;

            //排序前，先对所有页码排序
            pageIndexs.Sort();
            //要考虑每一次交换都会导致局部页码发生改变
            //每次整体往后移动时，先移动大页码；整体往前移动时，先移动小页码；往中间移动时，再按上述两种情况分别移动
            if (targetIndex <= pageIndexs[0])
            {
                for (int i = 0; i < pageIndexs.Count; i++)
                {
                    // list.Add(PageEditListBox.Items[pageIndexs[i]] as ListBoxItem);
                    //sourceindex.Add(pageIndexs[i]);
                    result = MoveItemToIndex(pageIndexs[i], targetIndex + i);
                    if(!result)
                    {
                        return;
                    }
                    SourceTargetValue.Add(pageIndexs[i], targetIndex + i);
                    selectedPages.Add(targetIndex + i+1);
                }
            }
            else if (targetIndex > pageIndexs[pageIndexs.Count - 1])
            {
                //目标位置在所有选中内容右边 整体后移
                for (int i = 0; i < pageIndexs.Count; i++)
                {
                    result = MoveItemToIndex(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i);
                    if (!result)
                    {
                        return;
                    }
                    SourceTargetValue.Add(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i);
                    selectedPages.Add(targetIndex - i);
                }
            }
            else//目标位置在所有选中项中间
            {
                int i, j, k;
                //找出PageEditListBox.Items中页码等于destpage的下标
                for (k = 0; k < pageIndexs.Count - 1; k++)
                {
                    //这里要算入K---即前面部分的页面个数
                    if (pageIndexs[k] < targetIndex && pageIndexs[k + 1] >= targetIndex)
                    {
                        break;
                    }
                }

                //局部往后移动
                for (i = 0; i <= k; i++)
                {
                    result = MoveItemToIndex(pageIndexs[k - i], targetIndex - 1 - i);
                    if (!result)
                    {
                        return;
                    }
                    SourceTargetValue.Add(pageIndexs[k - i], targetIndex - 1 - i);
                    selectedPages.Add(targetIndex - i);
                }
                int newIndex = targetIndex;
                //局部往前移动
                for (j = i; j < pageIndexs.Count; j++)
                {
                    result = MoveItemToIndex(pageIndexs[j], newIndex);
                    if (!result)
                    {
                        return;
                    }
                    SourceTargetValue.Add(pageIndexs[j], newIndex);
                    selectedPages.Add(newIndex + 1);
                    newIndex++;
                }
            }
            //通知UI选中Items
            NotifyUIToRefresh(selectedPages);
            //刷新页码和图片
            ReloadAfterOption(true,true,new Tuple<int, int>(0,PDFViewer.Document.PageCount));

            if (!IsFromUndoRedo)
            {
                //存入Undo栈
                PageEditHistory history = new PageEditHistory();
                history.Type = ActionType.DragSort;
                history.SourceTargetValue = SourceTargetValue;
                //用于Redo恢复
                history.InsertIndex = targetIndex;
                AddToUndoStack(history);
            }
        }

        /// <summary>
        /// 移动某个Item到指定位置
        /// </summary>
        private bool MoveItemToIndex(int sourceindex, int targetindex)
        {
            if (targetindex == sourceindex || targetindex < 0)
            {
                return false;
            }
            //文档层移动
            var result = PDFViewer.Document.MovePage(sourceindex, targetindex);
            if (!result)
            {
                return false;
            }

            //UI层移动
            var source = PageEditItems[sourceindex];
            PageEditItems.RemoveAt(sourceindex);
            PageEditItems.Insert(targetindex, source);
            return true;
        }

        /// <summary>
        /// 从底层库获取对应页面的图片
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="thumb"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        private void PDFViewer_OnThumbnailGenerated(int pageIndex, byte[] thumb, int w, int h)
        {
            try
            {
                if (PageEditItems.Count >= pageIndex + 1)
                {
                    PixelFormat fmt = PixelFormats.Bgra32;
                    BitmapSource bps = BitmapSource.Create(w, h, 96.0, 96.0, fmt, null, thumb, (w * fmt.BitsPerPixel + 7) / 8);
                    PageEditItems[pageIndex].Image = bps;
                    PageEditItems[pageIndex].IsGetImage = true;
                }
            }
            catch
            {

            }
        }
        #endregion

        #region Navigate
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {


        }

        /// <summary>
        /// 从其他页面导航过来的时候会触发
        /// 考虑只有在页面编辑的时候会进行页面的删减,可以尝试逻辑优化:仅第一次进入页面编辑时重新刷新页面
        /// </summary>
        /// <param name="navigationContext"></param>
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            navigationContext.Parameters.TryGetValue<ViewContentViewModel>(ParameterNames.ViewContentViewModel, out viewContentViewModel);
            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
            bool isBOTA = false;
            navigationContext.Parameters.TryGetValue<bool>(ParameterNames.BOTAThumb, out isBOTA);
            if (PDFViewer != null)
            {
                if (isFirstLoad)
                {
                    PDFViewer.OnThumbnailGenerated -= PDFViewer_OnThumbnailGenerated;
                    PDFViewer.OnThumbnailGenerated += PDFViewer_OnThumbnailGenerated;
                    PDFViewer.InfoChanged += PDFViewer_InfoChanged;
                    ZoomIndex = 0;
                    if(viewContentViewModel!=null)
                    {
                        viewContentViewModel.PageEditUndo = Undo;
                        viewContentViewModel.PageEditRedo = Redo;
                    }
                }
                //BOTA缩略图时，显示不同的菜单栏
                if(isBOTA)
                {
                    IsBOTAThumb = Visibility.Visible;
                }

                GetSourceItems(isFirstLoad);

                ListSelectedIndex = PDFViewer.CurrentIndex;
                viewContentViewModel.CanUndo = this.CanUndo;
                viewContentViewModel.CanRedo = this.CanRedo;
                RefreshBookMarkList();
                isFirstLoad = false;
            }
        }

        private void PDFViewer_InfoChanged(object sender, KeyValuePair<string, object> e)
        {
            if(e.Key== "PageNum")
            {
                NotifyUIToRefresh(new List<int> { (int)e.Value});
            }
        }
        #endregion
    }
}
