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.Documents;
using System.Windows.Input;
using System.Windows.Media;
using static PDF_Master.CustomControl.ColorDropBox;

namespace PDF_Master.Helper
{
    #region 悬浮窗口
    public class AdornerPresenter : Adorner
    {
        private VisualCollection VisualChildren;
        private ContentPresenter Content;
        public AdornerPresenter(UIElement adornedElement) : base(adornedElement)
        {
            VisualChildren = new VisualCollection(this);
            Content = new ContentPresenter();
            VisualChildren.Add(Content);
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Content.Measure(constraint);
            return Content.DesiredSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            Content.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
            return Content.RenderSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            return VisualChildren[index];
        }

        protected override int VisualChildrenCount
        {
            get
            {
                return VisualChildren.Count;
            }
        }

        public object VisualContent
        {
            get
            {
                return Content.Content;
            }
            set
            {
                Content.Content = value;
            }
        }
    }

    //悬浮窗口
    //hwnd:鼠标点击区域所在的窗口或控件
    //targetPop:悬浮窗口
    //offset:位于某窗口的位置,默认为整个主窗口的位置

    //Helper.PopControlHelper popControlHelper;
    //        if (popControlHelper == null)
    //            popControlHelper = new Helper.PopControlHelper(sender as Control, new CustomControl.CompositeControl.SlidContentPop());
    //        else
    //            popControlHelper.UpdatePointOffset(Mouse.GetPosition(App.Current.MainWindow));

    //        popControlHelper.ShowLayer();

    public class PopControlHelper : UserControl
    {
        private AdornerLayer popLayer;
        private AdornerPresenter layerPresent;
        private bool layerAdded = false;
        private Canvas popCanvas;
        private UserControl TargetPop;//悬浮窗口
        private Control HwndControl;//悬浮窗口的上一级窗口,即鼠标点击的区域所在的窗口
        private Point offset;//悬浮窗口,位于某窗口的位置
        public PopControlHelper(Control hwnd, UserControl targetPop, Point offset)
        {
            this.offset = offset;
            HwndControl = hwnd;
            TargetPop = targetPop;
            InitData();
        }

        public PopControlHelper(Control hwnd, UserControl targetPop)
        {
            //默认为主窗口的位置
            offset = Mouse.GetPosition(App.Current.MainWindow);
            HwndControl = hwnd;
            TargetPop = targetPop;
            InitData();
        }

        public void UpdatePointOffset(Point point)
        {
            offset = point;
        }

        public void ShowLayer(DependencyObject dependencyObject = null)
        {
            if (layerAdded)
            {
                RemoveFromLayer();
                return;
            }
            AddToLayer(dependencyObject);
        }

        public void RemoveLayer()
        {
            if (layerAdded)
            {
                RemoveFromLayer();
                return;
            }
        }

        //绑定鼠标点击整个窗口区域的事件
        private void InitData()
        {
            if (popLayer == null)
            {
                Window parentWnd = Window.GetWindow(HwndControl);
                if (parentWnd != null && parentWnd.Content is UIElement && TargetPop != null)
                {
                    parentWnd.AddHandler(MouseDownEvent, new MouseButtonEventHandler((eventsender, param) =>
                    {
                        if (layerAdded)
                        {
                            try
                            {

                                Point p = Mouse.GetPosition(TargetPop);
                                double width = 0;
                                double height = 0;
                                if (double.IsNaN(TargetPop.Width) == false && double.IsNaN(TargetPop.Height) == false)
                                {
                                    width = TargetPop.Width;
                                    height = TargetPop.Height;
                                }
                                else
                                {
                                    width = TargetPop.ActualWidth;
                                    height = TargetPop.ActualHeight;
                                }

                                if (p.X < 0 || p.Y < 0 || p.X > width || p.Y > height)
                                {
                                    RemoveFromLayer();
                                }
                            }
                            catch (Exception ex)
                            {

                            }

                        }
                    }), true);
                }
            }
        }

        private void AddToLayer(DependencyObject dependencyObject = null)
        {
            Window parentWnd = Window.GetWindow(HwndControl);
            popLayer = AdornerLayer.GetAdornerLayer(parentWnd.Content as UIElement);
            if (popLayer != null && TargetPop != null && !layerAdded)
            {
                if (layerPresent == null)
                {
                    layerPresent = new AdornerPresenter(popLayer);
                }
                popLayer.Add(layerPresent);
                if (popCanvas == null)
                {
                    popCanvas = new Canvas();
                    popCanvas.Children.Add(TargetPop);
                    layerPresent.VisualContent = popCanvas;
                }

                TargetPop.Visibility = Visibility.Visible;
                TargetPop.Measure(new Size(parentWnd.ActualWidth, parentWnd.ActualHeight));
                TargetPop.SetValue(Canvas.TopProperty, offset.Y + HwndControl.ActualHeight + 2);

                if (offset.X + TargetPop.DesiredSize.Width + SystemParameters.ResizeFrameVerticalBorderWidth * 2 > parentWnd.ActualWidth)
                {
                    TargetPop.SetValue(Canvas.LeftProperty, parentWnd.ActualWidth - TargetPop.DesiredSize.Width - 5 - SystemParameters.ResizeFrameVerticalBorderWidth * 2);
                }
                else
                {
                    TargetPop.SetValue(Canvas.LeftProperty, offset.X);
                }
                layerAdded = true;
            }
        }
        private void RemoveFromLayer()
        {
            if (popLayer != null && layerPresent != null && layerAdded)
            {
                popLayer.Remove(layerPresent);
                layerAdded = false;
            }
        }

    }

    #endregion

    #region 自定义菜单
    //自定义菜单:事件绑定、内容等

    public class CustomPopMenu
    {
        public ContextMenu PopMenu { get; private set; }
        public List<MenuItem> MenuItems { get; private set; }
        private object CommandTarget { get; set; }
        public CustomPopMenu(ContextMenu popMenu,object commandTarget)
        {
            PopMenu = popMenu;
            CommandTarget = commandTarget;
            GetMenuItems();
        }

        private void GetMenuItems()
        {
            if (PopMenu == null || PopMenu.Items == null)
                return;

            MenuItems = new List<MenuItem>();

            foreach (var item in PopMenu.Items)
            {
                if (item as MenuItem != null)
                {
                    MenuItems.Add(item as MenuItem);
                }
            }
        }

        //显示或隐藏所有菜单项
        public void AllMenuVisibility(bool isVisual)
        {
            if (MenuItems == null) return;

            foreach (var item in MenuItems)
            {
                item.Visibility = (isVisual ? Visibility.Visible : Visibility.Collapsed);
            }
        }

        private MenuItem ContainterOfIndex(int index)
        {
            if (MenuItems == null || MenuItems.Count <= index || index < 0)
                return null;

            MenuItem menuItem = MenuItems[index] as MenuItem;
            return menuItem;
        }

        private MenuItem ContainterOfTag(string tag)
        {
            if (MenuItems == null ||  string.IsNullOrEmpty(tag))
                return null;
            var menuItem = MenuItems.FirstOrDefault(temp => temp.Tag.ToString() == tag);
            return menuItem;
        }

        public void SetVisibilityProperty(int index, bool isVisual)
        {
            var menuItem = ContainterOfIndex(index);
            if (menuItem != null)
            {
                menuItem.Visibility = (isVisual?Visibility.Visible:Visibility.Collapsed);
            }
        }

        public void SetVisibilityProperty(string tag, bool isVisual)
        {
            var menuItem = ContainterOfTag(tag);
            if (menuItem != null)
            {
                menuItem.Visibility = (isVisual ? Visibility.Visible : Visibility.Collapsed);
            }
        }

        public void SetTagProperty(int index, string tag)
        {
            var menuItem = ContainterOfIndex(index);
            if (menuItem != null)
            {
                menuItem.Tag = tag;
            }
        }
        public void SetHeaderProperty(int index, string header)
        {
            var menuItem = ContainterOfIndex(index);

            if (menuItem != null)
            {
                menuItem.Header = header;
            }
        }

        //设置UI内容
        public void SetMenuUI(int index, UIElement controls)
        {
            var menuItem = ContainterOfIndex(index);

            if (menuItem != null)
            {
                menuItem.Header = controls;
            }

        }

        //按索引号设置菜单
        public void SetMenuBinding(int index, ICommand command,object comTarget = null)
        {
            var menuItem = ContainterOfIndex(index);

            if (menuItem != null)
            {
                if (comTarget == null)
                {
                    if (CommandTarget is UIElement)
                    {
                        menuItem.CommandTarget = (UIElement)CommandTarget;
                    }

                    menuItem.CommandParameter = CommandTarget;
                }
                   
                else
                {
                    if(comTarget is UIElement)
                    {
                        menuItem.CommandTarget = (UIElement)comTarget;
                    }
                    menuItem.CommandParameter = comTarget;
                }
                    
                menuItem.Command = command;
            }

        }

        //按Tag设置菜单
        public void SetMenuBinding(string tag, ICommand command, object comTarget = null)
        {
            var menuItem = ContainterOfTag(tag);

            if (menuItem != null)
            {
                if (comTarget == null)
                    menuItem.CommandTarget = (UIElement)CommandTarget;
                else
                    menuItem.CommandTarget = (UIElement)comTarget;

                menuItem.Command = command;
            }

        }

        //按索引号设置子菜单
        public void SetSubMenuBinding(int index, int subIndex, ICommand command, object comTarget = null,bool isChecked = false)
        {
            var menuItem = ContainterOfIndex(index);

            if (menuItem != null && menuItem.Items != null && menuItem.Items.Count > 0 && subIndex >= 0)
            {
                if(menuItem.Items.Count > subIndex)
                {
                   var item = menuItem.Items[subIndex];
                    if(item is RadioButton)
                    {
                        var radioItem = item as RadioButton;
                        radioItem.IsChecked = isChecked;
                        if (CommandTarget == null)
                            CommandTarget = comTarget;

                        radioItem.DataContext = CommandTarget;
                        radioItem.CommandParameter = radioItem;

                        radioItem.Command = command;
                    }
                    else if(item is MenuItem)
                    {
                        var submenuitem = item as MenuItem;

                        if (comTarget == null)
                        {
                            if (CommandTarget is UIElement)
                            {
                                submenuitem.CommandTarget = (UIElement)CommandTarget;
                            }

                            
                            if (isChecked)
                            {
                                submenuitem.DataContext = CommandTarget;
                                submenuitem.CommandParameter = submenuitem;//isChecked为true时,可拿MenuItem
                            }
                            else
                            {
                                submenuitem.DataContext = CommandTarget;
                                submenuitem.CommandParameter = CommandTarget;
                            }
                            
                        }

                        else
                        {
                            if (comTarget is UIElement)
                            {
                                submenuitem.CommandTarget = (UIElement)comTarget;
                            }
                            if (isChecked)
                            {
                                submenuitem.CommandParameter = submenuitem;//isChecked为true时,可拿MenuItem
                            }
                            else
                            {
                                submenuitem.CommandParameter = CommandTarget;
                            }
                           
                        }
                        submenuitem.Command = command;
                    }
                }
                

            }

        }

        public void SetSubMenuBinding(string tag, string subTag, ICommand command, object comTarget = null)
        {
            var menuItem = ContainterOfTag(tag);

            if (menuItem != null && menuItem.Items != null && menuItem.Items.Count > 0)
            {
                    object theItem = null;

                    foreach(var item in menuItem.Items)
                    {
                        if(item is RadioButton)
                        {
                            var radioItem = item as RadioButton;
                            if(radioItem.Tag != null && radioItem.Tag.ToString() == subTag)
                            {
                                theItem = item;
                                break;
                            }
                        }
                        else if(item is MenuItem)
                        {
                            var menuitem = item as MenuItem;
                            if (menuitem.Tag != null && menuitem.Tag.ToString() == subTag)
                            {
                                theItem = item;
                                break;
                            }
                        }

                    }

                    if(theItem != null)
                    {
                        if (theItem is RadioButton)
                        {
                            var radioTheItem = theItem as RadioButton;
                            radioTheItem.CommandParameter = radioTheItem.IsChecked;

                            if (comTarget == null)
                                radioTheItem.DataContext = (UIElement)CommandTarget;
                            else
                                radioTheItem.DataContext = (UIElement)comTarget;

                            radioTheItem.Command = command;
                        }
                        else if(theItem is MenuItem)
                        {
                            var menuTheitem = theItem as MenuItem;

                            if (comTarget == null)
                                menuTheitem.CommandTarget = (UIElement)CommandTarget;
                            else
                                menuTheitem.CommandTarget = (UIElement)comTarget;

                            menuTheitem.Command = command;
                        }
                    }

            }

        }

    }

    //菜单按钮类
    public class CusMenuItem
    {
        public Control control { get; private set; }//菜单按钮控件
        public int Level { get; private set; }//菜单按钮的层级数。Level为0是一级菜单
        public object Parameter { get; private set; }//核心处理的参数
        public object tag { get; private set; }//菜单控件Tag
        public void SetFlagControl(Control control)
        {
            this.control = control;
            tag = control.Tag;
        }

        public void SetParameter(object parameter)
        {
            Parameter = parameter;
        }
    }




    public class PopMenu
    {
        /// <summary>
        /// 菜单栏
        /// </summary>
        public ContextMenu ContMenu { get; private set; }
        /// <summary>
        /// 菜单按钮集合
        /// </summary>
        public List<CusMenuItem> Controls { get; private set; }

        public PopMenu(ContextMenu popMenu)
        {
            ContMenu = popMenu;
        }

        /// <summary>
        /// 打开右键菜单(parameter:commmand核心参数,uiParameter:响应复制粘贴等指令的参数)
        /// </summary>
        public ContextMenu OpenMenu(object parameter, object uiParameter = null)
        {
            if (Controls == null) return null;

            foreach(var item in Controls)
            {
                item.control.DataContext = parameter;
                if (uiParameter is UIElement && uiParameter != null)
                    BindingParameter(item, parameter, (UIElement)uiParameter);
                else
                    BindingParameter(item, parameter);
            }

            return ContMenu;
        }

        /// <summary>
        /// 右键菜单:创建菜单按钮、单选按钮等
        /// </summary>
        public CusMenuItem AddItem(Control control)
        {
            if (control == null) return null;

            CusMenuItem controlMenu = new CusMenuItem();
            controlMenu.SetFlagControl(control);
            if (Controls == null)
                Controls = new List<CusMenuItem>();

            ContMenu.Items.Add(controlMenu.control);
            Controls.Add(controlMenu);

            return controlMenu;
        }

        //在某菜单按钮的子级,新增子菜单按钮
        public CusMenuItem AddChild(string parentName, Control child)
        {
            if (Controls == null || child == null) return null;

            CusMenuItem childItem = null;
            foreach (var item in Controls)
            {
                var menu = item.control as MenuItem;

                if (menu != null && menu.Name == parentName)
                {
                    childItem = new CusMenuItem();
                    childItem.SetFlagControl(child);
                    menu.Items.Add(child);
                    Controls.Add(childItem);
                    break;
                }
            }

            return childItem;
        }

        //菜单按钮事件绑定
        public void BindingEvent(CusMenuItem controlMenu,ICommand command)
        {
            if (controlMenu == null) return;



            if(controlMenu.control is RadioButton)
            {
                var Btn = (RadioButton)controlMenu.control;
                Btn.CommandParameter = controlMenu;
                Btn.Command = command;
            }
            else if(controlMenu.control is MenuItem)
            {
                var Btn = (MenuItem)controlMenu.control;
                Btn.CommandParameter = controlMenu;
                Btn.Command = command;
            }
        }

        /// <summary>
        /// 右键菜单时,菜单按钮command需要的参数
        /// </summary>
        private void BindingParameter(CusMenuItem controlMenu, object CommandParameter, UIElement uIElement = null)
        {
            if (controlMenu == null) return;

            if (controlMenu.control is RadioButton)
            {
                var Btn = (RadioButton)controlMenu.control;
                if (uIElement != null)
                    Btn.CommandTarget = uIElement;

                Btn.CommandParameter = controlMenu;
            }
            else if (controlMenu.control is MenuItem)
            {
                var Btn = (MenuItem)controlMenu.control;

                if(uIElement != null)
                Btn.CommandTarget = uIElement;

                Btn.CommandParameter = controlMenu;
            }

            controlMenu.SetParameter(CommandParameter);
        }

        /// <summary>
        /// 菜单按钮是否可见
        /// </summary>
        public void SetVisual(string controlName, bool isVisible)
        {
            if (Controls == null) return;

            foreach(var item in Controls)
            {
                if(item.control.Name == controlName)
                {
                    item.control.Visibility = (isVisible?Visibility.Visible:Visibility.Collapsed);
                    break;
                }
            }
        }

        /// <summary>
        /// 菜单按钮选中状态(若菜单为单选按钮)
        /// </summary>
        public void SetIsChecked(string controlName, bool isChecked)
        {
            if (Controls == null) return;

            foreach (var item in Controls)
            {
                if (item.control.Name == controlName && (item.control as RadioButton) != null)
                {
                    var btn = item.control as RadioButton;
                    btn.IsChecked = isChecked;
                    break;
                }
            }

        }

    }

    #endregion

}