using FLY.UI.Module;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

using System.Linq;
using System.Text;
using System.Windows.Controls;
using ThickTcpUiInWindow;
using System.Windows.Media;
using System.Globalization;
using System.Threading;

namespace ThickTcpUiInWindow.MainEdit
{
    public class GraphTabItem : INotifyPropertyChanged
    {
        public TabItem mTabItem;
        private string title = "??";

        /// <summary>
        /// 唯一标识码
        /// </summary>
        public int ID = 0;

        public string Title
        {
            get { return title; }
            set
            {
                if (title != value)
                {
                    title = value;
                    NotifyPropertyChanged("Title");
                }
            }
        }
        private int colcnt = 1;

        public int ColCnt
        {
            get { return colcnt; }
            protected set
            {
                colcnt = value;
                NotifyPropertyChanged("ColCnt");
            }
        }
        private int rowcnt = 1;

        public int RowCnt
        {
            get { return rowcnt; }
            protected set
            {
                rowcnt = value;
                NotifyPropertyChanged("RowCnt");
            }
        }
        private List<bool> rowDefinitions = new List<bool>();

        public List<bool> RowDefinitions
        {
            get { return rowDefinitions; }
        }

        private List<bool> columnDefinitions = new List<bool>();
        public List<bool> ColumnDefinitions
        {
            get
            {
                return columnDefinitions;
            }
        }
        public List<GraphComponent> Components = new List<GraphComponent>();
        public event Action<GraphTabItem> RCChanged;

        public GraphTabItem()
        {
            RefreshRC();
        }
        bool refresh(List<bool> list, int cnt)
        {
            int n = cnt - list.Count();
            if (n == 0)
                return false;
            if (n > 0)
            {
                for (int i = 0; i < n; i++)
                {
                    list.Add(false);
                }
            }
            else
            {
                list.RemoveRange(cnt, -n);
            }
            return true;
        }
        void RefreshRC()
        {
            bool b1 = refresh(RowDefinitions, RowCnt);
            bool b2 = refresh(ColumnDefinitions, ColCnt);

            if (b1 || b2)
            {
                //把在范围外的控件缩小，或删除
                MakeComponentRectVaild();
                RCChanged?.Invoke(this);
            }
        }
        public void RefreshRC(int rowcnt, int colcnt)
        {
            RowCnt = rowcnt;
            ColCnt = colcnt;
            RefreshRC();
        }
        public bool IsComponentRectVaild(System.Drawing.Rectangle rect)
        {
            return IsComponentRectVaild(rect, null);
        }
        public bool IsComponentRectVaild(System.Drawing.Rectangle rect, GraphComponent component)
        {
            //判断超出范围
            if (!new System.Drawing.Rectangle(0, 0, ColCnt, RowCnt).Contains(rect))
            {
                return false;
            }
            //判断是否与其它控件有交集
            for (int i = 0; i < Components.Count(); i++)
            {
                if (Components[i] == component)
                    continue;
                if (rect.IntersectsWith(Components[i].Rect))
                    return false;
            }
            return true;
        }
        void MakeComponentRectVaild()
        {
            System.Drawing.Rectangle total = new System.Drawing.Rectangle(0, 0, ColCnt, RowCnt);
            for (int i = 0; i < Components.Count(); i++)
            {
                System.Drawing.Rectangle r = Components[i].Rect;
                if (r.IntersectsWith(total))
                {
                    r.Intersect(total);
                    Components[i].Rect = r;
                }
                else
                {
                    //删除
                    Components.RemoveAt(i);
                    i--;
                    continue;
                }
            }
        }

        /// <summary>
        /// 获取空的位置
        /// </summary>
        /// <returns></returns>
        public System.Drawing.Point GetFreeLocal()
        {
            //System.Drawing.Point
            //System.Drawing.Rectangle.
            for (int y = 0; y < RowCnt; y++)
            {
                for (int x = 0; x < ColCnt; x++)
                {
                    System.Drawing.Point p = new System.Drawing.Point(x, y);
                    bool isContains = false;
                    foreach (GraphComponent c in Components)
                    {
                        if (c.Rect.Contains(p))
                        {
                            isContains = true;
                            break;
                        }
                    }
                    if (!isContains)
                        return p;
                }

            }
            return new System.Drawing.Point(-1, -1);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyname"></param>
        protected void NotifyPropertyChanged(string propertyname)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    /// <summary>
    /// 图表控件
    /// </summary>
    public class GraphComponent : INotifyPropertyChanged
    {
        /// <summary>
        /// 唯一标识码
        /// </summary>
        public int ID = 0;

        public string TypeID { get; set; }

        private System.Drawing.Rectangle rect;
        public System.Drawing.Rectangle Rect
        {
            get { return rect; }
            set
            {
                if (rect != value)
                {
                    rect = value;
                    NotifyPropertyChanged("Rect");
                }
            }
        }

        /// <summary>
        /// 对应在grid中的button
        /// </summary>
        public Button mButton;

        public GraphComponentType Type { get; set; }

        public GraphTabItem mItem;

        protected void NotifyPropertyChanged(string propertyname)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    /// <summary>
    /// 图表控件类型
    /// </summary>
    public class GraphComponentType : INotifyPropertyChanged
    {
        /// <summary>
        /// 
        /// </summary>
        public string ID
        {
            get;
            set;
        }
        /// <summary>
        /// 
        /// </summary>

        public Brush Background
        {
            get; set;
        }
        /// <summary>
        /// 
        /// </summary>

        public string Header
        {
            get; set;
        }

        /// <summary>
        /// 只能添加一次
        /// </summary>
        public bool IsUnique
        {
            get; set;
        }
        private bool isenable = true;
        /// <summary>
        /// 当只能添加一次，且当前已经添加了，isenable=false
        /// </summary>
        public bool IsEnable
        {
            get
            {
                return isenable;
            }
            protected set
            {
                if (isenable != value)
                {
                    isenable = value;
                    NotifyPropertyChanged("IsEnable");
                }
            }
        }

        private int count = 0;
        /// <summary>
        /// 当前一共添加了多少控件
        /// </summary>
        public int Count
        {
            get { return count; }
            set
            {
                if (count != value)
                {
                    count = value;
                    NotifyPropertyChanged("Count");
                    if (IsUnique && count > 0)
                    {
                        IsEnable = false;
                    }
                    else
                    {
                        IsEnable = true;
                    }
                }
            }
        }

        /// <summary>
        /// 第3方控件
        /// </summary>
        public bool IsCustom
        {
            get; set;
        }

        protected void NotifyPropertyChanged(string propertyname)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    public class DynAreaComponent
    {
        /// <summary>
        /// 唯一标识码
        /// </summary>
        public int ID = 0;

        public string TypeID { get; set; }

        /// <summary>
        /// 对应在grid中的button
        /// </summary>
        public Button mButton;

        public GraphComponentType Type { get; set; }
    }
    public class GraphConverter
    {
        public static ObservableCollection<GraphComponentType> GetToolboxItems(FLYLayoutManager mManager, bool isGraphComponent)
        {
            ObservableCollection<GraphComponentType> toolboxitems = new ObservableCollection<GraphComponentType>();
            //custom
            foreach (string key in mManager.lmodule.UIModules.Keys)
            {
                UIModuleInfo moduleinfo = mManager.lmodule.UIModules[key];
                if (isGraphComponent && !moduleinfo.Param.IsGraphCompnonent)
                    continue;
                if (!isGraphComponent && !moduleinfo.Param.IsDynAreaComponent)
                    continue;

                GraphComponentType ctype = new GraphComponentType();
                ctype.IsCustom = true;
                ctype.ID = key;
                ctype.IsUnique = moduleinfo.Param.IsUnique;
                ctype.Header = moduleinfo.UIModule.Title;
                if (ctype.Header == null)
                    ctype.Header = key;

                ctype.Background = new SolidColorBrush(Colors.Gray);
                toolboxitems.Add(ctype);
            }


            return toolboxitems;
        }
        public static ObservableCollection<GraphTabItem> GetTabItems(List<UIModule.GraphTabItem> bulkTabItems)
        {
            ObservableCollection<GraphTabItem> graphTabItems = new ObservableCollection<GraphTabItem>();

            foreach (UIModule.GraphTabItem bulkTabItem in bulkTabItems)
            {
                GraphTabItem graphTabItem = new GraphTabItem();
                graphTabItem.Title = bulkTabItem.Header;
                graphTabItem.RefreshRC(bulkTabItem.RowCount, bulkTabItem.ColumnCount);
                graphTabItem.ID = bulkTabItem.GetHashCode();
                for (int i = 0; i < graphTabItem.ColCnt; i++)
                {
                    if (bulkTabItem.ColumnDefinitions.Count() <= i)
                        break;
                    graphTabItem.ColumnDefinitions[i] = bulkTabItem.ColumnDefinitions[i];
                }
                for (int i = 0; i < graphTabItem.RowCnt; i++)
                {
                    if (bulkTabItem.RowDefinitions.Count() <= i)
                        break;
                    graphTabItem.RowDefinitions[i] = bulkTabItem.RowDefinitions[i];

                }
                foreach (UIModule.GraphComponent bulkGraphItem in bulkTabItem.Graphs)
                {
                    GraphComponent graphComponent = new GraphComponent();
                    graphComponent.ID = bulkGraphItem.ID;
                    graphComponent.mItem = graphTabItem;
                    graphComponent.Rect = new System.Drawing.Rectangle(
                        bulkGraphItem.Column,
                        bulkGraphItem.Row,
                        bulkGraphItem.ColumnSpan,
                        bulkGraphItem.RowSpan
                        );

                    graphComponent.TypeID = bulkGraphItem.Module;
                    graphTabItem.Components.Add(graphComponent);
                }
                graphTabItems.Add(graphTabItem);
            }
            return graphTabItems;
        }

        public static void ToTabItems(ObservableCollection<GraphTabItem> src_graphTabItems, List<UIModule.GraphTabItem> dest_bulkTabItems)
        {
            for (int i = 0; i < src_graphTabItems.Count(); i++)
            {
                GraphTabItem graphTabItem = src_graphTabItems[i];
                UIModule.GraphTabItem bulkTabItem;

                if (graphTabItem.ID != 0)//有对应的tabitem
                {
                    int idx = dest_bulkTabItems.FindIndex((bitem) => { return bitem.GetHashCode() == graphTabItem.ID; });
                    if (idx == -1)
                    {
                        //异常
                        bulkTabItem = new UIModule.GraphTabItem();
                        dest_bulkTabItems.Insert(i, bulkTabItem);
                    }
                    else
                    {
                        bulkTabItem = dest_bulkTabItems[idx];

                        if (idx != i)
                        {
                            //顺序错了
                            dest_bulkTabItems.RemoveAt(idx);
                            dest_bulkTabItems.Insert(i, bulkTabItem);
                        }
                    }
                }
                else
                {
                    bulkTabItem = new UIModule.GraphTabItem();
                    dest_bulkTabItems.Insert(i, bulkTabItem);
                }

                bulkTabItem.Header = graphTabItem.Title;
                bulkTabItem.RowCount = graphTabItem.RowCnt;
                bulkTabItem.ColumnCount = graphTabItem.ColCnt;
                for (int c = 0; c < graphTabItem.ColCnt; c++)
                {
                    if (bulkTabItem.ColumnDefinitions.Count() <= c)
                    {
                        bulkTabItem.ColumnDefinitions.Add(graphTabItem.ColumnDefinitions[c]);
                    }
                    else
                    {
                        bulkTabItem.ColumnDefinitions[c] = graphTabItem.ColumnDefinitions[c];
                    }
                }
                for (int c = 0; c < graphTabItem.RowCnt; c++)
                {
                    if (bulkTabItem.RowDefinitions.Count() <= c)
                    {
                        bulkTabItem.RowDefinitions.Add(graphTabItem.RowDefinitions[c]);
                    }
                    else
                    {
                        bulkTabItem.RowDefinitions[c] = graphTabItem.RowDefinitions[c];
                    }
                }

                for (int j = 0; j < graphTabItem.Components.Count(); j++)
                {
                    GraphComponent component = graphTabItem.Components[j];
                    UIModule.GraphComponent bulkGraphItem = null;

                    if (component.ID != 0)//有对应的控件
                    {
                        int idx = bulkTabItem.Graphs.FindIndex((g) => { return g.ID == component.ID; });
                        if (idx == -1)
                        {
                            //异常
                        }
                        else
                        {
                            bulkGraphItem = bulkTabItem.Graphs[idx];
                            if (idx != j)
                            {
                                //顺序错了
                                bulkTabItem.Graphs.RemoveAt(idx);
                                bulkTabItem.Graphs.Insert(j, bulkGraphItem);
                            }

                        }
                    }
                    if (bulkGraphItem == null)
                    {
                        bulkGraphItem = new UIModule.GraphComponent();
                        bulkGraphItem.ID = bulkGraphItem.GetHashCode();
                        bulkGraphItem.Module = component.TypeID;
                        bulkTabItem.Graphs.Insert(j, bulkGraphItem);
                    }

                    bulkGraphItem.Row = component.Rect.Y;
                    bulkGraphItem.Column = component.Rect.X;
                    bulkGraphItem.RowSpan = component.Rect.Height;
                    bulkGraphItem.ColumnSpan = component.Rect.Width;
                }
                //剩下是多出来的，删除
                int rm = bulkTabItem.Graphs.Count() - graphTabItem.Components.Count();
                if (rm > 0)
                    bulkTabItem.Graphs.RemoveRange(graphTabItem.Components.Count(), rm);
            }
            {
                //剩下是多出来的，删除
                int rm = dest_bulkTabItems.Count() - src_graphTabItems.Count();
                if (rm > 0)
                    dest_bulkTabItems.RemoveRange(src_graphTabItems.Count(), rm);
            }
        }

        public static ObservableCollection<DynAreaComponent> GetDynAreaComponents(List<UIModule.DynAreaComponent> dynAreaItems)
        {
            ObservableCollection<DynAreaComponent> components = new ObservableCollection<DynAreaComponent>();
            for (int i = 0; i < dynAreaItems.Count(); i++)
            {
                DynAreaComponent component = new DynAreaComponent();
                component.ID = dynAreaItems[i].ID;
                component.TypeID = dynAreaItems[i].Module;
                components.Add(component);
            }
            return components;
        }

        public static void ToDynArea(ObservableCollection<DynAreaComponent> src_dynAreaComponent, List<UIModule.DynAreaComponent> dest_dynAreaItems)
        {
            for (int i = 0; i < src_dynAreaComponent.Count(); i++)
            {
                DynAreaComponent component = src_dynAreaComponent[i];
                UIModule.DynAreaComponent dynAreaItem;
                if (component.ID != 0)
                {
                    int idx = dest_dynAreaItems.FindIndex((daitem) => { return daitem.ID == component.ID; });
                    if (idx == -1)
                    {
                        //异常
                        dynAreaItem = new UIModule.DynAreaComponent();
                        dynAreaItem.ID = dynAreaItem.GetHashCode();
                        dynAreaItem.Module = component.TypeID;
                        dest_dynAreaItems.Insert(i, dynAreaItem);
                    }
                    else
                    {
                        dynAreaItem = dest_dynAreaItems[idx];

                        if (idx != i)
                        {
                            //顺序错了
                            dest_dynAreaItems.RemoveAt(idx);
                            dest_dynAreaItems.Insert(i, dynAreaItem);
                        }
                    }
                }
                else
                {
                    dynAreaItem = new UIModule.DynAreaComponent();
                    dynAreaItem.ID = dynAreaItem.GetHashCode();
                    dynAreaItem.Module = component.TypeID;
                    dest_dynAreaItems.Insert(i, dynAreaItem);
                }
            }
            //剩下全部删除
            dest_dynAreaItems.RemoveRange(
                src_dynAreaComponent.Count,
                dest_dynAreaItems.Count - src_dynAreaComponent.Count);
        }
    }
}
