using CloudBuilder;
using CloudBuilder.Core.DependencyInjection.Form;
using CloudBuilder.Core.DependencyInjection.Request;
using CloudBuilder.Gui;
using CloudBuilder.Gui.DependencyInjection;
using CloudBuilder.Request.Security;
using CloudBuilder.Security;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.Policy;
using CloudBuilder.Util;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;

namespace Krypton.Toolkit
{
    public partial class KryptonDataGridViewColumnSetDialog : KryptonForm
    {
        private SecurityMessagePolicy securityMessagePolicy;
        private string frozenColumnName;
        private TableLayoutPanel tableLayoutPanel1;
        private TableLayoutPanel tableLayoutPanel2;
        private KryptonButton allBut;
        private KryptonButton clearBut;
        private KryptonButton reverseBut;
        private KryptonButton upBut;
        private KryptonButton downBut;
        private KryptonButton unfreezeBut;
        private KryptonButton frozenBut;
        private KryptonLabel kryptonLabel1;
        private KryptonLabel kryptonLabel2;
        private TableLayoutPanel tableLayoutPanel3;
        private KryptonButton okBut;
        private KryptonButton cancelBut;
        private KryptonTextBox controlNameTxt;
        private KryptonTextBox frozenColumnTxt;
        private TreeView tv;
        private string parentName;
        private GuiBindingContext guiBindingContext;
        private KryptonButton resetBut;
        private GuiOperateHelper guiHelper = null;

        public KryptonDataGridViewColumnSetDialog(KryptonDataGridView _dgv)
        {
            InitializeComponent();

            securityMessagePolicy = ServiceHelper.GetTypeService<SecurityMessagePolicy>()!;

            this.Text = "调整列属性";
            guiBindingContext = new GuiBindingContext();
            guiHelper = new GuiOperateHelper();


            dgv = _dgv;
            controlNameTxt.Text = parentName = _dgv.GetFormName(_dgv) + "." + _dgv.Name;


            this.AcceptButton = okBut;
            this.CancelButton = cancelBut;


            guiHelper.EnableControls(false, controlNameTxt, frozenColumnTxt);

            OnLoad();
        }
        private KryptonDataGridView dgv;

        private Dictionary<string, string[]> dic;

        private void OnLoad()
        {
            if (dgv == null) return;
            TreeNode node;
            DataGridViewColumn column;
            DataGridViewColumn tmpcol;

            dic = dgv.SaveGridView();

            for (int i = 0; i < dgv.Columns.Count; i++)
            {
                for (int j = 0; j < dgv.Columns.Count; j++)
                {
                    tmpcol = dgv.Columns[j];
                    if (tmpcol.DisplayIndex == i)
                    {
                        column = dgv.Columns[j];
                        if (column.Tag == null || (int)(column.Tag) != 0) //不显示的隐藏列初始化为tag＝0
                        {
                            node = new TreeNode(column.HeaderText);
                            node.Tag = column;

                            node.Checked = column.Visible;

                            node.ImageIndex = i;

                            node.ToolTipText = (i * 2).ToString();

                            tv.Nodes.Add(node);

                            if (column.Frozen)
                            {
                                frozenColumnName = column.Name;
                                frozenColumnTxt.Text = column.HeaderText;
                            }
                        }
                    }
                }
            }
        }

        private void okBut_Click(object sender, EventArgs e)
        {
            RefreshDataGridView();

            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void RefreshDataGridView()
        {
            dic = new Dictionary<string, string[]>();

            int i = 0;

            List<DataGridViewColumnsInfo> df = new List<DataGridViewColumnsInfo>();
            DataGridViewColumnsInfo cf;

            foreach (TreeNode node in tv.Nodes)
            {
                dgv.Columns[i].Frozen = false;

                cf = new DataGridViewColumnsInfo();
                cf.DisplayIndex = tv.Nodes[i].ImageIndex.ToString();
                cf.Width = ((DataGridViewColumn)node.Tag).Width.ToString();
                cf.Visiable = tv.Nodes[i].Checked ? "true" : "false";
                cf.Name = ((DataGridViewColumn)node.Tag).Name;

                df.Add(cf);

                dic.Add(cf.Name, new string[] { cf.DisplayIndex, cf.Width, cf.Visiable });

                i++;
            }

            dgv.LoadGridView(dic);

            if (!string.IsNullOrEmpty(frozenColumnName)) dgv.Columns[frozenColumnName].Frozen = true;


            ExDataGridViewInfo info = new ExDataGridViewInfo();
            info.FrozenName = frozenColumnName;

            info.ColumnsInfo = df.ToArray();

            string serializable = SerializeHelper.Serialize(info);

            SecurityUserPreferenceEntity upf = new SecurityUserPreferenceEntity();
            upf.PreferenceKey = parentName;
            upf.Preference = serializable;
            upf.CreatedDatetime = upf.UpdatedDatetime = DateTime.Now;
            upf.CreatedBy = upf.UpdatedBy = upf.Username = ApplicationServiceContext.Context.Requestor;
            try
            {
                SecurityUserPreferenceRequest request = ServiceHelper.GetTypeService<SecurityUserPreferenceRequest>();

                request.Update(upf);

                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_UPDATED_NULL));
            }
            catch (ValidationException validation)
            {
                ShowMessageBox.ShowInfo(validation);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex);
            }
        }

        private void upBut_Click(object sender, EventArgs e)
        {
            TreeNode selected = tv.SelectedNode;
            tv.SelectedNode.ToolTipText = (Convert.ToInt32(tv.SelectedNode.ToolTipText) - 3).ToString();
            ResetTreeNode(selected);
        }

        private void downBut_Click(object sender, EventArgs e)
        {
            TreeNode selected = tv.SelectedNode;

            tv.SelectedNode.ToolTipText = (Convert.ToInt32(tv.SelectedNode.ToolTipText) + 3).ToString();

            ResetTreeNode(selected);
        }

        private void ResetTreeNode(TreeNode selected)
        {
            List<TreeNode> ls = new List<TreeNode>();
            TreeNode temp = selected;

            foreach (TreeNode node in tv.Nodes)
            {
                ls.Add(node);
            }

            tv.Nodes.Clear();

            ls = ls.OrderBy(x => Convert.ToInt32(x.ToolTipText)).ToList();

            int i = 0;
            foreach (TreeNode node in ls)
            {
                node.ToolTipText = (i * 2).ToString();
                node.ImageIndex = i;
                tv.Nodes.Add(node);
                i++;

                if (node.Text != selected.Text) continue;

                temp = node;
            }

            tv.SelectedNode = temp;
            tv.Select();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void frozenBut_Click(object sender, EventArgs e)
        {
            if (!tv.SelectedNode.Checked) return;

            frozenColumnName = ((DataGridViewColumn)tv.SelectedNode.Tag).Name;
            frozenColumnTxt.Text = ((DataGridViewColumn)tv.SelectedNode.Tag).HeaderText;

            tv.Select();
        }

        private void unfreezeBut_Click(object sender, EventArgs e)
        {
            frozenColumnTxt.Text = null;
            frozenColumnName = null;
            tv.Select();
        }

        private void tv_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            tv.SelectedNode.Checked = !tv.SelectedNode.Checked;
        }

        private void InitializeComponent()
        {
            tableLayoutPanel1 = new TableLayoutPanel();
            tableLayoutPanel2 = new TableLayoutPanel();
            allBut = new KryptonButton();
            clearBut = new KryptonButton();
            reverseBut = new KryptonButton();
            upBut = new KryptonButton();
            downBut = new KryptonButton();
            unfreezeBut = new KryptonButton();
            frozenBut = new KryptonButton();
            kryptonLabel1 = new KryptonLabel();
            kryptonLabel2 = new KryptonLabel();
            tableLayoutPanel3 = new TableLayoutPanel();
            okBut = new KryptonButton();
            cancelBut = new KryptonButton();
            resetBut = new KryptonButton();
            controlNameTxt = new KryptonTextBox();
            frozenColumnTxt = new KryptonTextBox();
            tv = new TreeView();
            tableLayoutPanel1.SuspendLayout();
            tableLayoutPanel2.SuspendLayout();
            tableLayoutPanel3.SuspendLayout();
            SuspendLayout();
            // 
            // tableLayoutPanel1
            // 
            tableLayoutPanel1.ColumnCount = 3;
            tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
            tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 2, 2);
            tableLayoutPanel1.Controls.Add(kryptonLabel1, 0, 1);
            tableLayoutPanel1.Controls.Add(kryptonLabel2, 0, 0);
            tableLayoutPanel1.Controls.Add(tableLayoutPanel3, 1, 3);
            tableLayoutPanel1.Controls.Add(controlNameTxt, 1, 0);
            tableLayoutPanel1.Controls.Add(frozenColumnTxt, 1, 1);
            tableLayoutPanel1.Controls.Add(tv, 1, 2);
            tableLayoutPanel1.Dock = DockStyle.Fill;
            tableLayoutPanel1.Location = new Point(0, 0);
            tableLayoutPanel1.Name = "tableLayoutPanel1";
            tableLayoutPanel1.RowCount = 4;
            tableLayoutPanel1.RowStyles.Add(new RowStyle());
            tableLayoutPanel1.RowStyles.Add(new RowStyle());
            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
            tableLayoutPanel1.RowStyles.Add(new RowStyle());
            tableLayoutPanel1.Size = new Size(467, 596);
            tableLayoutPanel1.TabIndex = 0;
            // 
            // tableLayoutPanel2
            // 
            tableLayoutPanel2.AutoSize = true;
            tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            tableLayoutPanel2.ColumnCount = 1;
            tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel2.Controls.Add(allBut, 0, 2);
            tableLayoutPanel2.Controls.Add(clearBut, 0, 3);
            tableLayoutPanel2.Controls.Add(reverseBut, 0, 4);
            tableLayoutPanel2.Controls.Add(upBut, 0, 5);
            tableLayoutPanel2.Controls.Add(downBut, 0, 6);
            tableLayoutPanel2.Controls.Add(unfreezeBut, 0, 0);
            tableLayoutPanel2.Controls.Add(frozenBut, 0, 1);
            tableLayoutPanel2.Location = new Point(371, 58);
            tableLayoutPanel2.Margin = new Padding(0);
            tableLayoutPanel2.Name = "tableLayoutPanel2";
            tableLayoutPanel2.RowCount = 7;
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.RowStyles.Add(new RowStyle());
            tableLayoutPanel2.Size = new Size(96, 217);
            tableLayoutPanel2.TabIndex = 0;
            // 
            // allBut
            // 
            allBut.Location = new Point(3, 65);
            allBut.Name = "allBut";
            allBut.Size = new Size(90, 25);
            allBut.TabIndex = 1;
            allBut.Values.Text = "全选";
            allBut.Click += allBut_Click;
            // 
            // clearBut
            // 
            clearBut.Location = new Point(3, 96);
            clearBut.Name = "clearBut";
            clearBut.Size = new Size(90, 25);
            clearBut.TabIndex = 1;
            clearBut.Values.Text = "清空";
            clearBut.Click += clearBut_Click;
            // 
            // reverseBut
            // 
            reverseBut.Location = new Point(3, 127);
            reverseBut.Name = "reverseBut";
            reverseBut.Size = new Size(90, 25);
            reverseBut.TabIndex = 1;
            reverseBut.Values.Text = "反选";
            reverseBut.Click += reverseBut_Click;
            // 
            // upBut
            // 
            upBut.Location = new Point(3, 158);
            upBut.Name = "upBut";
            upBut.Size = new Size(90, 25);
            upBut.TabIndex = 1;
            upBut.Values.Text = "向上";
            upBut.Click += upBut_Click;
            // 
            // downBut
            // 
            downBut.Location = new Point(3, 189);
            downBut.Name = "downBut";
            downBut.Size = new Size(90, 25);
            downBut.TabIndex = 1;
            downBut.Values.Text = "向下";
            downBut.Click += downBut_Click;
            // 
            // unfreezeBut
            // 
            unfreezeBut.Location = new Point(3, 3);
            unfreezeBut.Name = "unfreezeBut";
            unfreezeBut.Size = new Size(90, 25);
            unfreezeBut.TabIndex = 1;
            unfreezeBut.Values.Text = "解冻";
            unfreezeBut.Click += unfreezeBut_Click;
            // 
            // frozenBut
            // 
            frozenBut.Location = new Point(3, 34);
            frozenBut.Name = "frozenBut";
            frozenBut.Size = new Size(90, 25);
            frozenBut.TabIndex = 1;
            frozenBut.Values.Text = "冻结";
            frozenBut.Click += frozenBut_Click;
            // 
            // kryptonLabel1
            // 
            kryptonLabel1.Location = new Point(3, 32);
            kryptonLabel1.Name = "kryptonLabel1";
            kryptonLabel1.Size = new Size(65, 20);
            kryptonLabel1.TabIndex = 1;
            kryptonLabel1.Values.Text = "冻结列名:";
            // 
            // kryptonLabel2
            // 
            kryptonLabel2.Location = new Point(3, 3);
            kryptonLabel2.Name = "kryptonLabel2";
            kryptonLabel2.Size = new Size(65, 20);
            kryptonLabel2.TabIndex = 2;
            kryptonLabel2.Values.Text = "组件名称:";
            kryptonLabel2.Visible = false;
            // 
            // tableLayoutPanel3
            // 
            tableLayoutPanel3.AutoSize = true;
            tableLayoutPanel3.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            tableLayoutPanel3.ColumnCount = 4;
            tableLayoutPanel1.SetColumnSpan(tableLayoutPanel3, 2);
            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle());
            tableLayoutPanel3.Controls.Add(okBut, 2, 0);
            tableLayoutPanel3.Controls.Add(cancelBut, 3, 0);
            tableLayoutPanel3.Controls.Add(resetBut, 1, 0);
            tableLayoutPanel3.Dock = DockStyle.Fill;
            tableLayoutPanel3.Location = new Point(71, 565);
            tableLayoutPanel3.Margin = new Padding(0);
            tableLayoutPanel3.Name = "tableLayoutPanel3";
            tableLayoutPanel3.RowCount = 1;
            tableLayoutPanel3.RowStyles.Add(new RowStyle());
            tableLayoutPanel3.Size = new Size(396, 31);
            tableLayoutPanel3.TabIndex = 3;
            // 
            // okBut
            // 
            okBut.Location = new Point(207, 3);
            okBut.Name = "okBut";
            okBut.Size = new Size(90, 25);
            okBut.TabIndex = 0;
            okBut.Values.Text = "确定";
            okBut.Click += okBut_Click;
            // 
            // cancelBut
            // 
            cancelBut.Location = new Point(303, 3);
            cancelBut.Name = "cancelBut";
            cancelBut.Size = new Size(90, 25);
            cancelBut.TabIndex = 1;
            cancelBut.Values.Text = "取消";
            // 
            // resetBut
            // 
            resetBut.Location = new Point(111, 3);
            resetBut.Name = "resetBut";
            resetBut.Size = new Size(90, 25);
            resetBut.TabIndex = 0;
            resetBut.Values.Text = "重置";
            resetBut.Click += resetBut_Click;
            // 
            // controlNameTxt
            // 
            controlNameTxt.Dock = DockStyle.Fill;
            controlNameTxt.Location = new Point(74, 3);
            controlNameTxt.Name = "controlNameTxt";
            controlNameTxt.Size = new Size(294, 23);
            controlNameTxt.TabIndex = 4;
            controlNameTxt.Visible = false;
            // 
            // frozenColumnTxt
            // 
            frozenColumnTxt.Dock = DockStyle.Fill;
            frozenColumnTxt.Location = new Point(74, 32);
            frozenColumnTxt.Name = "frozenColumnTxt";
            frozenColumnTxt.Size = new Size(294, 23);
            frozenColumnTxt.TabIndex = 4;
            // 
            // tv
            // 
            tv.CheckBoxes = true;
            tv.Dock = DockStyle.Fill;
            tv.Location = new Point(74, 58);
            tv.Margin = new Padding(3, 0, 3, 3);
            tv.Name = "tv";
            tv.Size = new Size(294, 504);
            tv.TabIndex = 7;
            tv.NodeMouseDoubleClick += tv_NodeMouseDoubleClick;
            // 
            // KryptonDataGridViewColumnSetDialog
            // 
            ClientSize = new Size(467, 596);
            Controls.Add(tableLayoutPanel1);
            Name = "KryptonDataGridViewColumnSetDialog";
            tableLayoutPanel1.ResumeLayout(false);
            tableLayoutPanel1.PerformLayout();
            tableLayoutPanel2.ResumeLayout(false);
            tableLayoutPanel3.ResumeLayout(false);
            ResumeLayout(false);

        }

        private void allBut_Click(object sender, EventArgs e)
        {
            foreach (TreeNode node in tv.Nodes)
            {
                node.Checked = true;
            }
        }

        private void clearBut_Click(object sender, EventArgs e)
        {
            foreach (TreeNode node in tv.Nodes)
            {
                node.Checked = false;
            }
        }

        private void reverseBut_Click(object sender, EventArgs e)
        {
            foreach (TreeNode node in tv.Nodes)
            {
                node.Checked = !node.Checked;
            }
        }

        private void resetBut_Click(object sender, EventArgs e)
        {
            SecurityUserPreferenceEntityKey upf = new SecurityUserPreferenceEntityKey();
            upf.PreferenceKey = parentName;
            upf.Username = ApplicationServiceContext.Context.Requestor;
            try
            {
            
                    SecurityUserPreferenceRequest request = ServiceHelper.GetTypeService<SecurityUserPreferenceRequest>();

                    request.Delete(upf);

                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_UPDATED_NULL));

                    this.DialogResult = DialogResult.OK;
                    this.Close();
            }
            catch (ValidationException validation)
            {
                ShowMessageBox.ShowInfo(validation);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex);
            }
        }
    }
}
