using NetTaste;
using Prism.Commands;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
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;
namespace DM_Weight.Components.pagination
{
    /// 
    /// Pagination.xaml 的交互逻辑
    /// 
    public partial class Pagination : UserControl
    {
        public Pagination()
        {
            InitializeComponent();
            ResetInfoText();
            ResetCurrentPageText();
        }
        static Pagination()
        {
            InitializeCommands();
        }
        private static readonly Type _typeofSelf = typeof(Pagination);
        private static void InitializeCommands()
        {
            FirstCommand = new RoutedCommand("First", _typeofSelf);
            PrevCommand = new RoutedCommand("Prev", _typeofSelf);
            NextCommand = new RoutedCommand("Next", _typeofSelf);
            EndCommand = new RoutedCommand("End", _typeofSelf);
            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(FirstCommand, OnFirstComman, OnCanFirstComman));
            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(PrevCommand, OnPrevCommand, OnCanPrevCommand));
            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(NextCommand, OnNextCommand, OnCanNextCommand));
            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(EndCommand, OnEndCommand, OnCanEndCommand));
        }
        
        public static RoutedCommand FirstCommand { get; private set; }
        private static void OnFirstComman(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.CurrentPage = 1;
        }
        private static void OnCanFirstComman(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.CurrentPage > 1;
        }
        public static RoutedCommand PrevCommand { get; private set; }
        private static void OnPrevCommand(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.CurrentPage--;
        }
        private static void OnCanPrevCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.CurrentPage > 1;
        }
        public static RoutedCommand NextCommand { get; private set; }
        private static void OnNextCommand(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.CurrentPage++;
        }
        private static void OnCanNextCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.CurrentPage < ctrl.PageCount;
        }
        public static RoutedCommand EndCommand { get; private set; }
        private static void OnEndCommand(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.CurrentPage = ctrl.PageCount;
        }
        private static void OnCanEndCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.CurrentPage < ctrl.PageCount;
        }
        // 默认当前页码
        public static int DefaultCurrentPage = 1;
        // 默认总条数
        public static int DefaultTotalPages = 0;
        // 默认每页条数列表
        public static List DefaultPageSizeList = new List { 10, 20, 50, 100 };
        // 是否显示页码条数信息
        public static bool DefaultInfoTextIsEnabel = true;
        // 默认每页条数
        public static int DefaultPageSize = 10;
        public static readonly DependencyProperty CurrentPageProperty = DependencyProperty
                .Register("CurrentPage",
                typeof(int),
                typeof(Pagination),
                new FrameworkPropertyMetadata(DefaultCurrentPage, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        public static readonly DependencyProperty PageSizeProperty = DependencyProperty
                .Register("PageSize",
                typeof(int),
                typeof(Pagination),
                new FrameworkPropertyMetadata(DefaultPageSize, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        public static readonly DependencyProperty TotalPagesProperty = DependencyProperty
                .Register("TotalPages",
                typeof(int),
                typeof(Pagination),
                new FrameworkPropertyMetadata(DefaultTotalPages, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnItemsSourceChanged)));
        public static readonly DependencyProperty InfoTextIsEnabelProperty = DependencyProperty
                .Register("InfoTextIsEnabel",
                typeof(bool),
                typeof(Pagination),
                new FrameworkPropertyMetadata(DefaultInfoTextIsEnabel, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Pagination p = (Pagination)d;
            p.ResetInfoText();
        }
        [Bindable(true)]
        [Category("Appearance")]
        public int CurrentPage
        {
            get { return (int)GetValue(CurrentPageProperty); }
            set
            {
                SetValue(CurrentPageProperty, value);
                if (InfoTextIsEnabel)
                {
                    ResetInfoText();
                }
                ResetCurrentPageText();
            }
        }
        //private static void OnCurrentPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
        //    Pagination p = d as Pagination;
        //    if (p != null)
        //    {
        //        Console.WriteLine(e.NewValue);
        //    }
        //}
        [Bindable(true)]
        [Category("Appearance")]
        public int PageSize
        {
            get { return (int)GetValue(PageSizeProperty); }
            set
            {
                SetValue(PageSizeProperty, value);
                if (InfoTextIsEnabel)
                {
                    ResetInfoText();
                }
                ResetCurrentPageText();
            }
        }
        [Bindable(true)]
        [Category("Appearance")]
        public int TotalPages
        {
            get { return (int)GetValue(TotalPagesProperty); }
            set
            { 
                SetValue(TotalPagesProperty, value);
                if (InfoTextIsEnabel)
                {
                    ResetInfoText();
                }
                ResetCurrentPageText();
            }
        }
        public bool InfoTextIsEnabel
        {
            get { return (bool)GetValue(InfoTextIsEnabelProperty); }
            set { SetValue(InfoTextIsEnabelProperty, value); }
        }
        public int PageCount
        {
            get => (int)Math.Ceiling((double)TotalPages / PageSize);
        }
        public void ResetInfoText()
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                if (InfoTextIsEnabel)
                {
                    if (TotalPages <= PageSize)
                    {
                        this.InfoBlock.Text = $"1-{TotalPages}/{TotalPages}";
                        if (TotalPages == 0)
                        {
                            this.InfoBlock.Text = $"0-{TotalPages}/{TotalPages}";
                        }
                    } else
                    {
                        this.InfoBlock.Text = ((CurrentPage - 1) * PageSize + 1) + "-" + (CurrentPage * PageSize > TotalPages ? TotalPages : CurrentPage * PageSize) + "/" + TotalPages;
                    }
                    
                } else
                {
                    this.InfoBlock.Visibility = Visibility.Visible;
                }
                
            });
            
        }
        public void ResetCurrentPageText()
        {
            this.Dispatcher.BeginInvoke(() =>
            { 
                this.CurrentPageText.Text = CurrentPage + "";
            });
        }
    }
}