using Krypton.Toolkit;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.Control;

namespace CloudBuilder.Gui
{
    public class BindingContextAttributeProvider
    {
        private readonly ConcurrentDictionary<Control, BindingContextCustomAttribute> m_props =
                   new ConcurrentDictionary<Control, BindingContextCustomAttribute>();

        private readonly ConcurrentDictionary<DataGridViewColumn, BindingContextCustomAttribute> m_prop_column_s =
           new ConcurrentDictionary<DataGridViewColumn, BindingContextCustomAttribute>();

        public BindingContextCustomAttribute GetCustomAttribute(DataGridViewColumn ctrl)
        {
            m_prop_column_s.TryGetValue(ctrl, out var attribute);

            if (attribute == null) SetCustomAttribute(ctrl);

            m_prop_column_s.TryGetValue(ctrl, out attribute);

            return attribute;
        }

        public BindingContextCustomAttribute GetCustomAttribute(Control ctrl)
        {
            m_props.TryGetValue(ctrl, out var attribute);

            if (attribute == null) SetCustomAttribute(ctrl);

            m_props.TryGetValue(ctrl, out attribute);

            return attribute;
        }

        public bool HasCustomAttribute(Control ctrl)
        {
            m_props.TryGetValue(ctrl, out var attribute);

            if (attribute == null) return false;

            return true;
        }

        public bool HasCustomAttribute(DataGridViewColumn ctrl)
        {
            m_prop_column_s.TryGetValue(ctrl, out var attribute);

            if (attribute == null) return false;

            return true;
        }

        public void RemoveControlBinding(DataGridViewColumn ctrl)
        {
            m_prop_column_s.TryRemove(ctrl, out _);
        }

        public void RemoveControlBinding(ControlCollection ctrl)
        {
            if (ctrl.Count > 0)
            {
                foreach (Control childCtrl in ctrl)
                {
                    RemoveControlBinding(childCtrl);
                    if (childCtrl.Controls.Count > 0)
                    {
                        RemoveControlBinding(childCtrl.Controls);
                    }
                }
            }
        }
        public void RemoveControlBinding(Control ctrl)
        {
            m_props.TryRemove(ctrl, out _);
        }

        public void RemoveControlBinding(params Control[] ctrls)
        {
            foreach (var ctrl in ctrls)
            {
                RemoveControlBinding(ctrl);
            }
        }


        #region SetCustomAttribute

        #region DataGridViewColumn
        public void SetCustomAttribute(DataGridViewColumn ctrl)
        {
            BindingContextCustomAttribute bindingContext = new BindingContextCustomAttribute();
            m_prop_column_s.AddOrUpdate(ctrl, bindingContext, (key, oldValue) => bindingContext);
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, BindingContextCustomAttribute bindingContext)
        {
            m_prop_column_s.AddOrUpdate(ctrl, bindingContext, (key, oldValue) => bindingContext);
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, EnumEditModeColor editModeColor)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                // 如果键不存在，创建新属性
                key => new BindingContextCustomAttribute
                {
                    EditModeColor = editModeColor
                },
                // 如果键存在，更新属性
                (key, existing) =>
                {
                    existing.EditModeColor = editModeColor;
                    return existing;
                });
        }


        public void SetCustomAttribute(DataGridViewColumn ctrl, string bindDataName, EnumEditModeColor editModeColor)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                // 如果键不存在，创建新属性
                key => new BindingContextCustomAttribute
                {
                    BindDataName = bindDataName,
                    BindDirection = EnumBindDirection.Both,
                    EditModeColor = editModeColor
                },
                // 如果键存在，更新属性
                (key, existing) =>
                {
                    existing.BindDataName = bindDataName;
                    existing.BindDirection = EnumBindDirection.Both;
                    existing.EditModeColor = editModeColor;
                    return existing;
                });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string bindDataName, string bindFormat, EnumEditModeColor editModeColor)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                      // 如果键不存在，创建新属性
                      key => new BindingContextCustomAttribute
                      {
                          BindDataName = bindDataName,
                          BindFormat = bindFormat,
                          EditModeColor = editModeColor
                      },
                      // 如果键存在，更新属性
                      (key, existing) =>
                      {
                          existing.BindDataName = bindDataName;
                          existing.BindFormat = bindFormat;
                          existing.EditModeColor = editModeColor;
                          return existing;
                      });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string bindDataName, EnumBindDirection bindDirection, EnumEditModeColor editModeColor)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                      // 如果键不存在，创建新属性
                      key => new BindingContextCustomAttribute
                      {
                          BindDataName = bindDataName,
                          BindDirection = bindDirection,
                          EditModeColor = editModeColor
                      },
                      // 如果键存在，更新属性
                      (key, existing) =>
                      {
                          existing.BindDirection = bindDirection;
                          existing.BindDataName = bindDataName;
                          existing.EditModeColor = editModeColor;
                          return existing;
                      });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string bindDataName, EnumBindDirection bindDirection)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        BindDataName = bindDataName,
                        BindDirection = bindDirection
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.BindDirection = bindDirection;
                        existing.BindDataName = bindDataName;
                        return existing;
                    });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string bindDataName, string bindFormat, EnumBindDirection bindDirection)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        BindDataName = bindDataName,
                        BindFormat = bindFormat,
                        BindDirection = bindDirection,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.BindDirection = bindDirection;
                        existing.BindDataName = bindDataName;
                        existing.BindFormat = bindFormat;
                        return existing;
                    });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string permissionName, Operate permissionMode)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        PermissionMode = permissionMode,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.PermissionMode = permissionMode;
                        return existing;
                    });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string permissionName, string dependentDetailName, Operate permissionMode)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        DependentDetailName = dependentDetailName,
                        PermissionMode = permissionMode,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.DependentDetailName = dependentDetailName;
                        existing.PermissionMode = permissionMode;
                        return existing;
                    });
        }

        public void SetCustomAttribute(DataGridViewColumn ctrl, string permissionName, string dependentDetailName)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        DependentDetailName = dependentDetailName,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.DependentDetailName = dependentDetailName;
                        return existing;
                    });
        }


        public void SetCustomAttribute(DataGridViewColumn ctrl, DataTable dataTableSource, DataTable deleteDataTableSource)
        {
            var attribute = m_prop_column_s.AddOrUpdate(ctrl,
            // 如果键不存在，创建新属性
            key => new BindingContextCustomAttribute
            {
                DataTableSource = dataTableSource,
                DeleteDataTableSource = deleteDataTableSource,
            },
            // 如果键存在，更新属性
            (key, existing) =>
            {
                existing.DataTableSource = dataTableSource;
                existing.DeleteDataTableSource = deleteDataTableSource;
                return existing;
            });
        }

        #endregion

        #region Control
        public void SetCustomAttribute(Control ctrl)
        {
            BindingContextCustomAttribute bindingContext = new BindingContextCustomAttribute();
            m_props.AddOrUpdate(ctrl, bindingContext, (key, oldValue) => bindingContext);
        }
        public void SetCustomAttribute(Control ctrl, BindingContextCustomAttribute bindingContext)
        {
            m_props.AddOrUpdate(ctrl, bindingContext, (key, oldValue) => bindingContext);
        }

        public void SetCustomAttribute(Control ctrl, EnumEditModeColor editModeColor)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                // 如果键不存在，创建新属性
                key => new BindingContextCustomAttribute
                {
                    EditModeColor = editModeColor
                },
                // 如果键存在，更新属性
                (key, existing) =>
                {
                    existing.EditModeColor = editModeColor;
                    return existing;
                });
        }

        public void SetCustomAttribute(Control ctrl, EnumEditModeColor editModeColor, string bindDisplayName)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                // 如果键不存在，创建新属性
                key => new BindingContextCustomAttribute
                {
                    BindDisplayName = bindDisplayName,
                    EditModeColor = editModeColor
                },
                // 如果键存在，更新属性
                (key, existing) =>
                {
                    existing.EditModeColor = editModeColor;
                    existing.BindDisplayName = bindDisplayName;
                    return existing;
                });
        }


        public void SetCustomAttribute(Control ctrl, string bindDataName, EnumEditModeColor editModeColor)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                // 如果键不存在，创建新属性
                key => new BindingContextCustomAttribute
                {
                    BindDataName = bindDataName,
                    EditModeColor = editModeColor
                },
                // 如果键存在，更新属性
                (key, existing) =>
                {
                    existing.BindDataName = bindDataName;
                    existing.EditModeColor = editModeColor;
                    return existing;
                });
        }

        public void SetCustomAttribute(Control ctrl, string bindDataName, string bindFormat, string bindDisplayName, EnumEditModeColor editModeColor)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                      // 如果键不存在，创建新属性
                      key => new BindingContextCustomAttribute
                      {
                          BindDataName = bindDataName,
                          BindFormat = bindFormat,
                          BindDisplayName = bindDisplayName,
                          EditModeColor = editModeColor
                      },
                      // 如果键存在，更新属性
                      (key, existing) =>
                      {
                          existing.BindDataName = bindDataName;
                          existing.BindFormat = bindFormat;
                          existing.BindDisplayName = bindDisplayName;
                          existing.EditModeColor = editModeColor;
                          return existing;
                      });
        }

        public void SetCustomAttribute(Control ctrl, string bindDataName, string bindDisplayName, EnumEditModeColor editModeColor)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                      // 如果键不存在，创建新属性
                      key => new BindingContextCustomAttribute
                      {
                          BindDataName = bindDataName,
                          BindDisplayName = bindDisplayName,
                          EditModeColor = editModeColor
                      },
                      // 如果键存在，更新属性
                      (key, existing) =>
                      {
                          existing.BindDataName = bindDataName;
                          existing.BindDisplayName = bindDisplayName;
                          existing.EditModeColor = editModeColor;
                          return existing;
                      });
        }

        public void SetCustomAttribute(Control ctrl, string bindDataName, EnumBindDirection bindDirection, EnumEditModeColor editModeColor)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                      // 如果键不存在，创建新属性
                      key => new BindingContextCustomAttribute
                      {
                          BindDataName = bindDataName,
                          BindDirection = bindDirection,
                          EditModeColor = editModeColor
                      },
                      // 如果键存在，更新属性
                      (key, existing) =>
                      {
                          existing.BindDirection = bindDirection;
                          existing.BindDataName = bindDataName;
                          existing.EditModeColor = editModeColor;
                          return existing;
                      });
        }

        public void SetCustomAttribute(Control ctrl, string bindDataName, EnumBindDirection bindDirection)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        BindDataName = bindDataName,
                        BindDirection = bindDirection
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.BindDirection = bindDirection;
                        existing.BindDataName = bindDataName;
                        return existing;
                    });
        }

        public void SetCustomAttribute(Control ctrl, string bindDataName, string bindDisplayName, EnumBindDirection bindDirection)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        BindDataName = bindDataName,
                        BindDisplayName = bindDisplayName,
                        BindDirection = bindDirection
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.BindDirection = bindDirection;
                        existing.BindDisplayName = bindDisplayName;
                        existing.BindDataName = bindDataName;
                        return existing;
                    });
        }


        public void SetCustomAttribute(Control ctrl, string bindDataName, string bindFormat, string bindDisplayName, EnumBindDirection bindDirection)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        BindDataName = bindDataName,
                        BindFormat = bindFormat,
                        BindDisplayName = bindDisplayName,
                        BindDirection = bindDirection,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.BindDirection = bindDirection;
                        existing.BindDataName = bindDataName;
                        existing.BindDisplayName = bindDisplayName;
                        existing.BindFormat = bindFormat;
                        return existing;
                    });
        }

        public void SetCustomAttribute(Control ctrl, string permissionName, Operate permissionMode)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        PermissionMode = permissionMode,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.PermissionMode = permissionMode;
                        return existing;
                    });
        }

        public void SetCustomAttribute(Control ctrl, string permissionName, string dependentDetailName, Operate permissionMode)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        DependentDetailName = dependentDetailName,
                        PermissionMode = permissionMode,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.DependentDetailName = dependentDetailName;
                        existing.PermissionMode = permissionMode;
                        return existing;
                    });
        }

        public void SetCustomAttribute(Control ctrl, string permissionName, string dependentDetailName)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
                    // 如果键不存在，创建新属性
                    key => new BindingContextCustomAttribute
                    {
                        PermissionName = permissionName,
                        DependentDetailName = dependentDetailName,
                    },
                    // 如果键存在，更新属性
                    (key, existing) =>
                    {
                        existing.PermissionName = permissionName;
                        existing.DependentDetailName = dependentDetailName;
                        return existing;
                    });
        }


        public void SetCustomAttribute(Control ctrl, List<dynamic> dataSource, DataTable dataTableSource, DataTable deleteDataTableSource)
        {
            var attribute = m_props.AddOrUpdate(ctrl,
            // 如果键不存在，创建新属性
            key => new BindingContextCustomAttribute
            {
                DataSource = dataSource,
                DataTableSource = dataTableSource,
                DeleteDataTableSource = deleteDataTableSource,
            },
            // 如果键存在，更新属性
            (key, existing) =>
            {
                existing.DataSource = dataSource;
                existing.DataTableSource = dataTableSource;
                existing.DeleteDataTableSource = deleteDataTableSource;
                return existing;
            });
        }
        #endregion

        #endregion

        // IExtenderProvider interface
        public bool CanExtend(object extendee)
        {
            // Exclude myself and not Control class
            return (extendee is KryptonTextBox ||
                extendee is KryptonComboBox ||
                extendee is KryptonDataGridView ||
                extendee is KryptonDataGridView ||
                extendee is KryptonCheckBox ||
                extendee is KryptonDateTimePicker ||
                extendee is KryptonMaskedTextBox ||
                extendee is KryptonCheckedListBox ||
                extendee is KryptonListBox ||
                extendee is KryptonRadioButton ||
                extendee is KryptonButton
                );
        }
    }
}
