using PDF_Office.EventAggregators;
using PDF_Office.Helper;
using PDF_Office.Model.PageEdit;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using WpfToolkit.Controls;

namespace PDF_Office.Views.PageEdit
{
    /// <summary>
    /// PageEditContent.xaml 的交互逻辑
    /// </summary>
    public partial class PageEditContent : UserControl
    {
        /// <summary>
        /// 用于通知刷新图片的事件
        /// 因为目前的图片刷新策略依赖很多UI事件判断，因为将主要判断逻辑放在UI层，VM负责图片刷新，非必要情况尽量不要采用这种形式
        /// </summary>
        private IEventAggregator eventor;

        /// <summary>
        /// 暂存的唯一索引值,用于区分多页签
        /// </summary>
        private string unicode;

        /// <summary>
        /// 是否是加载时第一次触发滚动
        /// </summary>
        private bool isFirstScrollChange = true;

        /// <summary>
        /// 用于判断滚轮停止的计时器
        /// </summary>
        private DispatcherTimer timer = new DispatcherTimer();

        /// <summary>
        /// 判断是否开始框选
        /// </summary>
        private bool startChoose = false;

        /// <summary>
        /// 框选的起始位置
        /// </summary>
        private Point starPosition = new Point();

        /// <summary>
        /// 记录当前滑块的状态
        /// </summary>
        private ScrollEventType scrolltype = ScrollEventType.EndScroll;

        //鼠标点击时在item中的位置  实现类似点哪拖哪的细节
        private double item_x;

        private double item_y;

        //插入标记代表的插入位置
        private int InsertIndex = -1;

        //拖动的Item
        private ListBoxItem tempItem;

        ///鼠标是否停留在item前半部
        ///显示在前半部时，获取的index为实际索引值
        ///显示在后半部时，获取的index需要+1
        private bool isFrontHalf = false;

        /// <summary>
        /// 是否正在拖拽排序中，通过该变量避免单击触发拖动
        /// </summary>
        private bool isDraging = false;

        //是否正在从外部拖入文件
        private bool isDragingEnter = false;

        /// <summary>
        /// 是否需要自动滚动
        /// </summary>

        private bool needScroll = false;

        //自动滚动速度
        private int speed = 0;

        public PageEditContent()
        {
            InitializeComponent();
        }


        public PageEditContent(IEventAggregator eventAggregator) :this()
        {
            eventor = eventAggregator;
            unicode = App.mainWindowViewModel.SelectedItem.Unicode;

            timer.Interval = TimeSpan.FromSeconds(0.3);
            timer.Tick += Timer_Tick;

            //订阅页面刷新事件
            eventor.GetEvent<PageEditNotifyEvent>().Subscribe(OneNotifyEvent, e => e.Unicode == unicode);
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            PulishEvent();
            timer.Stop();
        }

        private void OneNotifyEvent(PageEditNotifyEventArgs  e)
        {
            PulishEvent();
        }


        #region UI事件
        /// <summary>
        /// 每次显示的时候就触发事件，刷新所有图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PageEdit_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if((bool)e.NewValue)
            {
                //当前页面没有发生变化时，刷新图片 这种情况下会拿两次图，需要留意
                PulishEvent();
                //当前页面发生变化时通过ScrollChanged事件来刷新图片
                isFirstScrollChange = true;
            }
        }

        /// <summary>
        /// 鼠标滚轮滚动时触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListPageEdit_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (isFirstScrollChange)
            {
                PulishEvent();//第一次加载时触发的Scollchange 直接刷新界面，减少白板显示时间
                isFirstScrollChange = false;
                return;
            }
            else
            {
                if (e.VerticalChange != 0)
                    timer.Start();//暂时找不到比较好的 判断Scroller停止的方法，先用计时器粗略判断
            }
        }

        /// <summary>
        /// 拖动右侧滑块时触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListPageEdit_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e)
        {
            scrolltype = e.ScrollEventType;
            if (scrolltype != System.Windows.Controls.Primitives.ScrollEventType.EndScroll)
            {
                timer.Stop();
                return;
            }
            PulishEvent();
        }

        #endregion

        #region 方法
        /// <summary>
        /// 发布事件
        /// </summary>
        private void PulishEvent()
        {
            var itemSize = (ListPageEdit.Items[0] as PageEditItem).ItemSize;
            var range = GetRoughFromView(ListPageEdit, itemSize, new Thickness(5, 10, 5, 10));
            eventor.GetEvent<PageEditRefreshEvent>().Publish(new PageEditRefreshEventArgs() { Unicode = unicode, PageRange = range });
        }

        /// <summary>
        /// 获取滑轨的垂直偏移量，结合item总数和Item尺寸以及间隔，来估算实际展示的item范围
        /// 返回值为页面范围  从1开始
        /// </summary>
        /// <param name="view"></param>
        /// <param name="itemSize"></param>
        /// <param name="itemMargin"></param>
        /// <returns></returns>
        private Tuple<int, int, int> GetRoughFromView(ListBox view, Size itemSize, Thickness itemMargin)
        {
            //var scrollViewer = GetScrollHost(view);
            var scrollViewer = CommonHelper.FindVisualChild<ScrollViewer>(view);
            if (scrollViewer == null || scrollViewer.ActualHeight == 0 || scrollViewer.ActualWidth == 0)//视图展开
                return new Tuple<int, int, int>(0, 0, 0);
            try
            {
                var currentHeight = scrollViewer.ActualHeight - view.Padding.Top;
                var currentWidth = scrollViewer.ActualWidth;
                //计算当前窗口大小能显示的行数和列数
                var columnCount = (int)(currentWidth / (itemSize.Width + itemMargin.Left));
                var rowCount = (int)Math.Ceiling(currentHeight / (itemSize.Height + itemMargin.Bottom));

                var preItemCount = (int)((scrollViewer.VerticalOffset / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount));//滑动百分比*行数 = 大概的垂直位置
                preItemCount = preItemCount * columnCount;
                var preEnd = (int)(((scrollViewer.VerticalOffset + scrollViewer.ActualHeight) / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount));
                preEnd = preEnd * columnCount + columnCount - 1;

                var middle = (int)Math.Ceiling(preItemCount + preEnd / 2d);

                return new Tuple<int, int, int>(
                    Math.Max(preItemCount, 0),
                    Math.Min(view.Items.Count, preEnd),
                    middle);
            }
            catch { }
            return new Tuple<int, int, int>(0, 0, 0);
        }

        /// <summary>
        /// 获取listbox里的ScrollViewer对象
        /// 留意如果有重写ListBox对象,该方法可能无效
        /// </summary>
        /// <param name="listBox"></param>
        /// <returns></returns>
        private ScrollViewer GetScrollHost(ListBox listBox)
        {
            if (VisualTreeHelper.GetChildrenCount(listBox) > 0)
            {
                int s = VisualTreeHelper.GetChildrenCount(listBox);

                Border border = VisualTreeHelper.GetChild(listBox, 0) as Border;
                if (border != null)
                {
                    return VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
                }
            }
            return null;
        }

        #endregion

        /// <summary>
        /// 输入框显示时，自动获取焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if((bool)e.NewValue)
            {
                (sender as Control).Focus();
            }
        }

        private void ListPageEdit_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    //鼠标框选逻辑
                    if (startChoose)
                    {
                        var position = e.GetPosition(ListPageEdit);
                        if (position.X < 5 || position.X > ListPageEdit.ActualWidth - 5 || position.Y < 5 || position.Y > ListPageEdit.ActualHeight - 5)
                        {
                            startChoose = false;
                            RectChoose.Visibility = Visibility.Collapsed;
                            //暂时未想到靠近顶部和底部自动翻滚的好方法，只能先屏蔽这部分功能
                            Mouse.Capture(null);
                            return;
                        }
                        //矩形框内的item设为选中
                        DoSelectItems();
                        return;
                    }
                    //拖拽排序的逻辑
                    var pos = e.GetPosition(ListPageEdit);
                    if (pos.Y < 0 || pos.Y > ListPageEdit.ActualHeight)
                    {
                        LineInset.Visibility = Visibility.Collapsed;
                        return;
                    }
                    HitTestResult result = VisualTreeHelper.HitTest(ListPageEdit, pos);
                    if (result == null)
                    {
                        return;
                    }
                    var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
                    if (listBoxItem == null)
                    {
                        return;
                    }
                    isDragingEnter = false;
                    tempItem = listBoxItem;

                    var item_pos = e.GetPosition(tempItem);
                    if (item_pos != null)
                    {
                        item_x = item_pos.X;
                        item_y = item_pos.Y;
                    }
                    var scroll = GetScrollHost(ListPageEdit);

                    //string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Temp.pdf");
                    //System.IO.File.Create(tempPath);
                    //string[] files = new string[1];
                    //files[0] = tempPath;
                    DataObject dataObj = new DataObject(DataFormats.FileDrop);
                    DragDrop.DoDragDrop(ListPageEdit, dataObj, DragDropEffects.Move);
                    Mouse.Capture(ListPageEdit);
                    return;
                }
                RectChoose.Visibility = Visibility.Collapsed;
                startChoose = false;
                Mouse.Capture(null);
            }
            catch
            {
               LineInset.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// 判断是否开始框选、记录框选起始位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListPageEdit_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var pos = e.GetPosition(ListPageEdit);
            HitTestResult result = VisualTreeHelper.HitTest(ListPageEdit, pos);
            if (result == null)
            {
                return;
            }
            //未选中item  并且不是点击滑轨时 开始框选
            var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
            var scroller = CommonHelper.FindVisualParent<ScrollBar>(result.VisualHit);
            if (listBoxItem == null)
            {
                if (scroller != null)
                {
                    startChoose = false;
                    return;
                }
                //点击空白处时开始框选
                startChoose = true;
                if (ListPageEdit.SelectedItems.Count > 0)
                {
                    ListPageEdit.SelectedItems.Clear();
                }
                starPosition = e.GetPosition(ListPageEdit);
                starPosition = new Point(starPosition.X, starPosition.Y + GetWrapPanel(ListPageEdit).VerticalOffset);
                Mouse.Capture(ListPageEdit);
                return;
            }
            //选中了item 时，不能框选
            startChoose = false;
        }

        private void ListPageEdit_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            startChoose = false;
            Mouse.Capture(null);
            RectChoose.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// 获取Listobox的Wrappanel容器
        /// </summary>
        /// <param name="listBox"></param>
        /// <returns></returns>
        public VirtualizingWrapPanel GetWrapPanel(ListBox listBox)
        {
            Border border = VisualTreeHelper.GetChild(listBox, 0) as Border;
            var panel = CommonHelper.FindVisualChild<VirtualizingWrapPanel>(border);
            return panel;
        }

        /// <summary>
        ///根据鼠标拖选的框 选中里面的Item
        /// </summary>
        private void DoSelectItems()
        {
            var s = GetScrollHost(ListPageEdit);
            Point start = new Point();
            //通过 实时的垂直偏移量和第一次的偏移量抵消，来获取准确的垂直偏移值。
            start = new Point(starPosition.X, starPosition.Y - s.VerticalOffset);
            var rec = new Rect(start, Mouse.GetPosition(ListPageEdit));
            RectChoose.Margin = new Thickness(rec.Left, rec.Top, 0, 0);
            RectChoose.Width = rec.Width;
            RectChoose.Height = rec.Height;
            RectChoose.Visibility = Visibility.Visible;

            //检测遍历所有项,筛选在矩形框中的Item
            for (int i = 0; i < ListPageEdit.Items.Count; i++)
            {
                var _item = ListPageEdit.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                //通过这一步来避免重复误选中
                var parent = CommonHelper.FindVisualParent<VirtualizingWrapPanel>(_item);
                if (parent == null)
                    continue;

                var v = VisualTreeHelper.GetOffset(_item);
                if (rec.IntersectsWith(new Rect(v.X, v.Y, _item.ActualWidth, _item.ActualHeight)))
                {
                    ListPageEdit.SelectedItems.Add(ListPageEdit.Items[i]);
                }
                else
                {
                    ListPageEdit.SelectedItems.Remove(ListPageEdit.Items[i]);
                }
            }
            return;
        }

        /// <summary>
        /// 计算插入标记线和虚影显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListPageEdit_DragOver(object sender, DragEventArgs e)
        {
            try
            {
                //ctrl建按下 不显示插入标记和虚影  因为释放不会响应drop事件
                if (e.KeyStates == (DragDropKeyStates.ControlKey | DragDropKeyStates.LeftMouseButton) || e.KeyStates == (DragDropKeyStates.ShiftKey | DragDropKeyStates.LeftMouseButton | DragDropKeyStates.ControlKey))
                    return;

                //滚动后有 位置不准确 要减去滚动偏移量
                //控制线的位置
                var pos = e.GetPosition(ListPageEdit);
                var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
                if (result == null)
                {
                    //MidLane.Visibility = Visibility.Collapsed;
                    //return;
                }

                //获取当前鼠标指针下的容器
                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
                if (listBoxItem == null)
                {
                    //MidLane.Visibility = Visibility.Collapsed;
                    //return;
                }

                #region  计算虚影位置
                //xaml层 要设置 虚影控件为左上
                double xPos = 0;
                double yPos = 0;
                //内部拖动
                if (!isDragingEnter)
                {
                    //Viewbox viewBox = (tempItem.Content as StackPanel).Children[0] as Viewbox;//获取item宽度

                    ImgPicture.Width = tempItem.ActualWidth;
                    ImgPicture.Height = tempItem.ActualHeight;
                    ImgPicture.Source = (tempItem.DataContext as PageEditItem).Image;
                    xPos = e.GetPosition(ListPageEdit).X - item_x;
                    yPos = e.GetPosition(ListPageEdit).Y - item_y;
                }
                //else
                //{
                //    //从外部拖入的逻辑
                //    //var pic = ToBitmapSource(dragingEnterPath);
                //    //ShadowPicture.Width = pic.Width;
                //    //ShadowPicture.Height = pic.Height;
                //    //ShadowPicture.Source = pic;
                //    //xPos = e.GetPosition(ListPageEdit).X - pic.Width / 2;
                //    //yPos = e.GetPosition(ListPageEdit).Y - pic.Height / 2;
                //}

                ImgPicture.Margin = new Thickness(xPos, yPos, 0, 0);
                #endregion

                #region 计算插入标记位置
                var scroll = GetScrollHost(ListPageEdit);
                if (listBoxItem != null)
                {
                    //虚拟化影响到该值计算
                    var p = VisualTreeHelper.GetOffset(listBoxItem);//计算控件在容器中的偏移(位置)
                    LineInset.Visibility = Visibility.Visible;

                    var panel = GetWrapPanel(ListPageEdit);
                    var item = (ListPageEdit.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem).DesiredSize.Width;

                    int count = (int)(panel.ViewportWidth / item);
                    var gap = (panel.ViewportWidth - count * item) / (count + 1) * 1.0;

                    LineInset.X2 = LineInset.X1 = p.X + gap / 2 + listBoxItem.DesiredSize.Width;

                    if (pos.X < p.X + gap / 2 + listBoxItem.ActualWidth / 2)
                    {
                        isFrontHalf = true;//前半部 线条出现在位置前 
                        LineInset.X2 = LineInset.X1 = p.X - gap / 2;
                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem);
                    }
                    else
                    {
                        isFrontHalf = false;
                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem) + 1;
                    }
                    //MidLane.Y1 = p.Y - scroll.VerticalOffset;//向下滑动后要减去滑动值
                    LineInset.Y1 = p.Y;
                    if (LineInset.Y1 < 0)//避免超出上边界
                    {
                        LineInset.Y1 = 0;
                    }
                    //MidLane.Y2 = p.Y + listBoxItem.ActualHeight - scroll.VerticalOffset;//仿智能滚动后可能会导致 垂直滚动偏量不准确
                    LineInset.Y2 = p.Y + listBoxItem.ActualHeight;
                    if (LineInset.Y2 < 0)
                    {
                        LineInset.Y2 = 0;
                    }
                }
                #endregion

                //暂时处理  鼠标移出边框时，虚影的显示问题
                if (pos.Y <= 30 || pos.Y >= ListPageEdit.ActualHeight - 10)
                {
                    LineInset.Visibility = Visibility.Collapsed;
                    needScroll = false;
                }

                if (pos.X <= 40 || pos.X >= scroll.ViewportWidth - 50)
                {
                    LineInset.Visibility = Visibility.Collapsed;
                    needScroll = false;
                }

                #region 靠近上下边界时，自动滚动，离边界越近，滚动速度越快
                //speed = 0;
                //if (pos.Y >= PageEditListBox.ActualHeight - 30)
                //{
                //    speed = 30 - (int)(PageEditListBox.ActualHeight - pos.Y);
                //    needScroll = true;
                //}
                //else if (pos.Y <= 30)
                //{
                //    speed = (int)(pos.Y - 30);
                //    needScroll = true;
                //}
                //else
                //    needScroll = false;

                //var v = scroll.VerticalOffset;
                //scroll.ScrollToVerticalOffset(v + speed);//触发连续滚动
                #endregion
            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// 退出拖拽模式
        /// </summary>
        private void ExitDraging()
        {
            LineInset.Visibility = Visibility.Collapsed;
            isDraging = false;
        }

        /// <summary>
        /// 拖拽释放后的处理逻辑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListPageEdit_Drop(object sender, DragEventArgs e)
        {
            needScroll = false;
            if (!isDraging)
            {
                //未拖拽时隐藏插入标记和虚影
                LineInset.Visibility = Visibility.Collapsed;
                return;
            }
            #region 功能付费锁
            //    //if (!App.IsActive())
            //    //{
            //    //    MidLane.Visibility = Visibility.Collapsed;
            //    //    IAPFunctionDialog dialog = new IAPFunctionDialog("PageEdit");
            //    //    dialog.ShowDialog();
            //    //    return;
            //    //}
            #endregion

            #region  从外部拖拽插入文件
            //if (isDragingEnter)
            //{


            //    //在当前位置插入整个pdf
            //    CPDFDocument dragDoc = CPDFDocument.InitWithFilePath(dragingEnterPath);
            //    if (dragDoc.IsLocked)
            //    {
            //        VerifyPasswordDialog dialog = new VerifyPasswordDialog(dragDoc);
            //        dialog.ShowDialog();
            //        if (dragDoc.IsLocked)
            //            return;
            //    }
            //    if (dragingEnterPath.Substring(dragingEnterPath.LastIndexOf(".")).ToLower() == ".pdf")
            //    {
            //        if (dragDoc != null)
            //        {
            //            int index = InsertIndex == -1 ? 0 : InsertIndex;
            //            pdfViewer.Document.ImportPagesAtIndex(dragDoc, "1-" + dragDoc.PageCount, index);
            //            PopulateThumbnailList();
            //            ItemsInViewHitTest();

            //            pdfViewer.UndoManager.ClearHistory();
            //            pdfViewer.UndoManager.CanSave = true;
            //            pdfViewer.ReloadDocument();
            //            PageEditListBox.ScrollIntoView(PageEditListBox.SelectedItem as ListBoxItem);
            //            PageMoved.Invoke(this, new RoutedEventArgs());
            //            PDFViewerCtrl viewerCtrl = ParentPage?.GetCurrentViewer();
            //            if (viewerCtrl != null)
            //            {
            //                viewerCtrl.IsPageEdit = true;
            //            }
            //            dragDoc.Release();
            //        }
            //        else
            //        {
            //            MessageBoxEx.Show(App.MainPageLoader.GetString("Merge_FileCannotOpenedWarningd"));
            //        }
            //        //提示文档损坏无法打开
            //    }
            //    else if (!string.IsNullOrEmpty(dragingEnterPath))
            //    {
            //        //其他文件  则新增一个页签打开
            //        //    DragAddTab.Invoke(dragingEnterPath, new RoutedEventArgs());//底层库需要加一个  Load(TPDFDocument)的接口
            //    }
            //    MidLane.Visibility = Visibility.Collapsed;
            //    isDragingEnter = false;
            //    dragingEnterPath = null;
            //    return;
            //}
            #endregion

            var pos = e.GetPosition(ListPageEdit);
            var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
            if (result == null)
            {
                //超出当前可控区域
                ExitDraging();
                return;
            }
            //查找元数据
            var sourcePerson = e.Data.GetData(typeof(StackPanel)) as StackPanel;
            if (sourcePerson == null)
            {
                ExitDraging();
                return;
            }
            //查找目标数据
            int targetindex = 0;//目标插入位置
            if (InsertIndex != -1)
            {
                //往前移动时  此index  不是准确的，需要处理++
                targetindex = InsertIndex;
            }
            else//基本不会命中  仅作为保险措施
            {
                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
                if (listBoxItem == null)
                {
                    ////鼠标停留在两个item之间或其他无效区域  暂时不做处理(比较麻烦)
                    ExitDraging();
                    return;
                }
                var targetPerson = listBoxItem;
                targetPerson.Opacity = 1;
                sourcePerson.Opacity = 1;
                if (ReferenceEquals(targetPerson, sourcePerson))
                {
                    ExitDraging();
                    return;
                }

                targetindex = ListPageEdit.Items.IndexOf(targetPerson);
            }

            List<ListBoxItem> list = new List<ListBoxItem>();
            List<int> sourceindex = new List<int>();//需要保存每个页面对应的位置
            //开始排序
            List<int> pages = new List<int>();
            //要先对所有选中项 根据页码排序
            for (int i = 0; i < ListPageEdit.SelectedItems.Count; i++)
            {
                var pageindex = ListPageEdit.Items.IndexOf(ListPageEdit.SelectedItems[i] as ListBoxItem);
                pages.Add(pageindex);//存入的为页码索引值
            }
            pages.Sort();
            if (pages.Count <= 0)
            {
                ExitDraging();
                return;
            }

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

            //    sourceindex.Add(0);
            //    list = new List<ListBoxItem>();
            //    for (i = 0; i <= k; i++)//局部往后移动
            //    {
            //        list.Add(PageEditListBox.Items[pages[k - i]] as ListBoxItem);
            //        sourceindex.Add(pages[k - i]);
            //        DragToSort(pages[k - i], targetindex - 1 - i);
            //    }
            //    for (j = i; j < pages.Count; j++)//局部往前移动
            //    {
            //        list.Add(PageEditListBox.Items[pages[j]] as ListBoxItem);
            //        sourceindex.Add(pages[j]);
            //        DragToSort(pages[j], targetindex);
            //        targetindex++;
            //    }
            //    sourceindex.Add(k);//往中间移时， index数组的最后一位 表示 间隔位置K
            //}
            isDraging = false;
        }

        private void MidLane_Drop(object sender, DragEventArgs e)
        {
            ListPageEdit_Drop(sender, e);
        }

        private void ImgPicture_Drop(object sender, DragEventArgs e)
        {
            ListPageEdit_Drop(sender, e);
        }

        /// <summary>
        /// 拖拽事件写在外部的Grid里，会更加流畅
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Grid_DragOver(object sender, DragEventArgs e)
        {
            try
            {
                //ctrl建按下 不显示插入标记和虚影  因为释放不会响应drop事件
                if (e.KeyStates == (DragDropKeyStates.ControlKey | DragDropKeyStates.LeftMouseButton) || e.KeyStates == (DragDropKeyStates.ShiftKey | DragDropKeyStates.LeftMouseButton | DragDropKeyStates.ControlKey))
                    return;

                //滚动后有 位置不准确 要减去滚动偏移量
                //控制线的位置
                var pos = e.GetPosition(ListPageEdit);
                var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
                if (result == null)
                {
                    //MidLane.Visibility = Visibility.Collapsed;
                    //return;
                }

                //获取当前鼠标指针下的容器
                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
                if (listBoxItem == null)
                {
                    //MidLane.Visibility = Visibility.Collapsed;
                    //return;
                }

                #region  计算虚影位置
                //xaml层 要设置 虚影控件为左上
                double xPos = 0;
                double yPos = 0;
                //内部拖动
                if (!isDragingEnter)
                {
                    //Viewbox viewBox = (tempItem.Content as StackPanel).Children[0] as Viewbox;//获取item宽度

                    ImgPicture.Width = tempItem.ActualWidth;
                    ImgPicture.Height = tempItem.ActualHeight;
                    ImgPicture.Source = (tempItem.DataContext as PageEditItem).Image;
                    xPos = e.GetPosition(ListPageEdit).X - item_x;
                    yPos = e.GetPosition(ListPageEdit).Y - item_y;
                }
                //else
                //{
                //    //从外部拖入的逻辑
                //    //var pic = ToBitmapSource(dragingEnterPath);
                //    //ShadowPicture.Width = pic.Width;
                //    //ShadowPicture.Height = pic.Height;
                //    //ShadowPicture.Source = pic;
                //    //xPos = e.GetPosition(ListPageEdit).X - pic.Width / 2;
                //    //yPos = e.GetPosition(ListPageEdit).Y - pic.Height / 2;
                //}

                ImgPicture.Margin = new Thickness(xPos, yPos, 0, 0);
                #endregion

                #region 计算插入标记位置
                var scroll = GetScrollHost(ListPageEdit);
                if (listBoxItem != null)
                {
                    //虚拟化影响到该值计算
                    var p = VisualTreeHelper.GetOffset(listBoxItem);//计算控件在容器中的偏移(位置)
                    LineInset.Visibility = Visibility.Visible;

                    var panel = GetWrapPanel(ListPageEdit);

                    //var item = panel.ItemSize.Width;
                    //var item = (ListPageEdit.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem).DesiredSize.Width;
                    var item = listBoxItem.DesiredSize.Width;

                    int count = (int)(panel.ViewportWidth / item);
                    var gap = (panel.ViewportWidth - count * item) / (count + 1) * 1.0;

                    LineInset.X2 = LineInset.X1 = p.X + gap / 2 + listBoxItem.DesiredSize.Width;

                    if (pos.X < p.X + gap / 2 + listBoxItem.ActualWidth / 2)
                    {
                        isFrontHalf = true;//前半部 线条出现在位置前 
                        LineInset.X2 = LineInset.X1 = p.X - gap / 2;
                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem);
                    }
                    else
                    {
                        isFrontHalf = false;
                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem) + 1;
                    }
                    //MidLane.Y1 = p.Y - scroll.VerticalOffset;//向下滑动后要减去滑动值
                    LineInset.Y1 = p.Y;
                    if (LineInset.Y1 < 0)//避免超出上边界
                    {
                        LineInset.Y1 = 0;
                    }
                    //MidLane.Y2 = p.Y + listBoxItem.ActualHeight - scroll.VerticalOffset;//仿智能滚动后可能会导致 垂直滚动偏量不准确
                    LineInset.Y2 = p.Y + listBoxItem.ActualHeight;
                    if (LineInset.Y2 < 0)
                    {
                        LineInset.Y2 = 0;
                    }
                }
                #endregion

                //暂时处理  鼠标移出边框时，虚影的显示问题
                if (pos.Y <= 30 || pos.Y >= ListPageEdit.ActualHeight - 10)
                {
                    LineInset.Visibility = Visibility.Collapsed;
                    needScroll = false;
                }

                if (pos.X <= 40 || pos.X >= scroll.ViewportWidth - 50)
                {
                    LineInset.Visibility = Visibility.Collapsed;
                    needScroll = false;
                }

                #region 靠近上下边界时，自动滚动，离边界越近，滚动速度越快
                speed = 0;
                if (pos.Y >= ListPageEdit.ActualHeight - 30)
                {
                    speed = 30 - (int)(ListPageEdit.ActualHeight - pos.Y);
                    needScroll = true;
                }
                else if (pos.Y <= 30)
                {
                    speed = (int)(pos.Y - 30);
                    needScroll = true;
                }
                else
                    needScroll = false;

                var v = scroll.VerticalOffset;
                scroll.ScrollToVerticalOffset(v + speed);//触发连续滚动
                #endregion
            }
            catch
            {

            }
        }
    }
}
