using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RyzStudio.Windows.Forms
{
    public class ThreadControl
    {
        public static void Add(Control control, Control value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Controls.Add(value);
                }));
            }
            else
            {
                control.Controls.Add(value);
            }
        }

        public static void Add(ListBox control, string value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Items.Add(value);
                }));
            }
            else
            {
                control.Items.Add(value);
            }
        }

        public static void Add(ComboBox control, string value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Items.Add(value);
                }));
            }
            else
            {
                control.Items.Add(value);
            }
        }

        //public static void Add(FlowLayoutPanel control, Control value)
        //{
        //    if (control.InvokeRequired)
        //    {
        //        control.Invoke(new MethodInvoker(() => {
        //            control.Controls.Add(value);
        //        }));
        //    }
        //    else
        //    {
        //        control.Controls.Add(value);
        //    }
        //}

        public static int Add(TreeView control, TreeNode value)
        {
            int n = -1;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    n = control.Nodes.Add(value);
                }));
            }
            else
            {
                n = control.Nodes.Add(value);
            }

            return n;
        }

        public static int Add(TreeNode control, TreeNode value)
        {
            int n = -1;

            if (control.TreeView.InvokeRequired)
            {
                control.TreeView.Invoke(new MethodInvoker(() => {
                    n = control.Nodes.Add(value);
                }));
            }
            else
            {
                n = control.Nodes.Add(value);
            }

            return n;
        }

        public static int Add(DataGridView control, object[] value)
        {
            int n = -1;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    n = control.Rows.Add(value);
                }));
            }
            else
            {
                n = control.Rows.Add(value);
            }

            return n;
        }

        public static int Add(DataGridView control, object[] value, object tag)
        {
            int n = -1;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    n = control.Rows.Add(value);
                    control.Rows[n].Tag = tag;
                }));
            }
            else
            {
                n = control.Rows.Add(value);
                control.Rows[n].Tag = tag;
            }

            return n;
        }

        public static TreeNode Add(TreeView control, string key, string text)
        {
            TreeNode rv = null;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    rv = control.Nodes.Add(key, text);
                }));
            }
            else
            {
                rv = control.Nodes.Add(key, text);
            }

            return rv;
        }

        public static TreeNode Add(TreeNode control, string key, string text)
        {
            TreeNode rv = null;

            if (control.TreeView.InvokeRequired)
            {
                control.TreeView.Invoke(new MethodInvoker(() => {
                    rv = control.Nodes.Add(key, text);
                }));
            }
            else
            {
                rv = control.Nodes.Add(key, text);
            }

            return rv;
        }

        public static TreeNode Add(TreeView parentControl, TreeNodeCollection control, string key, string text, int imageIndex, int selectedImageIndex)
        {
            TreeNode rv = null;

            if (parentControl.InvokeRequired)
            {
                parentControl.Invoke(new MethodInvoker(() => {
                    rv = control.Add(key, text, imageIndex, selectedImageIndex);
                }));
            }
            else
            {
                rv = control.Add(key, text, imageIndex, selectedImageIndex);
            }

            return rv;
        }

        public static TreeNode Add(TreeNode control, string key, string text, int imageIndex, int selectedImageIndex)
        {
            TreeNode rv = null;

            if (control.TreeView.InvokeRequired)
            {
                control.TreeView.Invoke(new MethodInvoker(() => {
                    rv = control.Nodes.Add(key, text, imageIndex, selectedImageIndex);
                }));
            }
            else
            {
                rv = control.Nodes.Add(key, text, imageIndex, selectedImageIndex);
            }

            return rv;
        }

        public static TreeNode Add(TreeView control, string key, string text, int imageIndex, int selectedImageIndex)
        {
            TreeNode rv = null;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    rv = control.Nodes.Add(key, text, imageIndex, selectedImageIndex);
                }));
            }
            else
            {
                rv = control.Nodes.Add(key, text, imageIndex, selectedImageIndex);
            }

            return rv;
        }

        public static void Add(TreeView parentControl, ImageList control, Image value)
        {
            if (parentControl.InvokeRequired)
            {
                parentControl.Invoke(new MethodInvoker(() => {
                    control.Images.Add(value);
                }));
            }
            else
            {
                control.Images.Add(value);
            }
        }

        public static void Add(Control parentControl, ImageList control, string key, Image value)
        {
            if (parentControl.InvokeRequired)
            {
                parentControl.Invoke(new MethodInvoker(() => {
                    control.Images.Add(key, value);
                }));
            }
            else
            {
                control.Images.Add(key, value);
            }
        }

        public static void AddLine(RichTextBox control, string text)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Text += text + Environment.NewLine;
                }));
            }
            else
            {
                control.Text += text + Environment.NewLine;
            }
        }

        public static void Clear(ListBox control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Items.Clear();
                }));
            }
            else
            {
                control.Items.Clear();
            }
        }

        public static void Clear(ComboBox control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Items.Clear();
                }));
            }
            else
            {
                control.Items.Clear();
            }
        }

        public static void Clear(TreeView parentControl, ImageList control)
        {
            if (parentControl.InvokeRequired)
            {
                parentControl.Invoke(new MethodInvoker(() => {
                    control.Images.Clear();
                }));
            }
            else
            {
                control.Images.Clear();
            }
        }

        public static void Clear(FlowLayoutPanel control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Controls.Clear();
                }));
            }
            else
            {
                control.Controls.Clear();
            }
        }

        public static void Clear(TreeView control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Nodes.Clear();
                }));
            }
            else
            {
                control.Nodes.Clear();
            }
        }

        public static void Clear(Label control) => SetText(control, string.Empty);

        public static void Clear(PictureBox control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Image = null;
                }));
            }
            else
            {
                control.Image = null;
            }
        }

        public static void Clear(DataGridView control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Rows.Clear();
                }));
            }
            else
            {
                control.Rows.Clear();
            }
        }

        public static void Expand(TreeNode control)
        {
            if (control.TreeView.InvokeRequired)
            {
                control.TreeView.Invoke(new MethodInvoker(() => {
                    control.Expand();
                }));
            }
            else
            {
                control.Expand();
            }
        }

        public static List<T> FindChildControl<T>(Control control) where T : Control
        {
            List<T> rs = new List<T>();

            foreach (Control item in control.Controls)
            {
                var ctr = item as T;
                if (ctr == null)
                {
                    rs.AddRange(FindChildControl<T>(item));
                }
                else
                {
                    rs.Add(ctr);
                }
            }

            return rs;
        }

        public static string GetSelectedValue(ListBox sender)
        {
            string rv = string.Empty;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => {
                    rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString();
                }));
            }
            else
            {
                rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString();
            }

            return rv;
        }

        public static string GetText(Control control, bool doTrim = true)
        {
            string rv = string.Empty;

            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    rv = (doTrim ? control.Text?.Trim() : control.Text);
                }));
            }
            else
            {
                rv = (doTrim ? control.Text?.Trim() : control.Text);
            }

            return rv;
        }

        public static int GetValue(NumericUpDown sender)
        {
            int rv = 0;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => {
                    rv = (int)sender.Value;
                }));
            }
            else
            {
                rv = (int)sender.Value;
            }

            return rv;
        }

        public static bool IsChild(TreeNode dragNode, TreeNode dropNode)
        {
            TreeNode tn = dropNode;
            while (true)
            {
                if (tn.Parent == null)
                {
                    break;
                }

                if (tn.Equals(dragNode))
                {
                    return true;
                }

                tn = tn.Parent;
            }

            return false;
        }

        public static void SetChecked(ToolStripMenuItem control, bool value)
        {
            if (control.GetCurrentParent().InvokeRequired)
            {
                control.GetCurrentParent().Invoke(new MethodInvoker(() =>
                {
                    control.Checked = value;
                }));
            }
            else
            {
                control.Checked = value;
            }
        }

        public static void SetClientHeight(Control control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.ClientSize = new Size(control.ClientSize.Width, value);
                }));
            }
            else
            {
                control.ClientSize = new Size(control.ClientSize.Width, value);
            }
        }

        public static void SetClientSize(Control control, int width, int height) => SetClientSize(control, new Size(width, height));

        public static void SetClientSize(Control control, Size value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.ClientSize = value;
                }));
            }
            else
            {
                control.ClientSize = value;
            }
        }

        public static void SetClientWidth(Control control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.ClientSize = new Size(value, control.ClientSize.Height);
                }));
            }
            else
            {
                control.ClientSize = new Size(value, control.ClientSize.Height);
            }
        }

        public static void SetEnable(Control control, bool value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Enabled = value;
                }));
            }
            else
            {
                control.Enabled = value;
            }
        }

        public static void SetEnable(ToolStripMenuItem control, bool value)
        {
            if (control.GetCurrentParent() == null)
            {
                control.Enabled = value;
                return;
            }

            if (control.GetCurrentParent().InvokeRequired)
            {
                control.GetCurrentParent().Invoke(new MethodInvoker(() =>
                {
                    control.Enabled = value;
                }));
            }
            else
            {
                control.Enabled = value;
            }
        }

        public static void SetFocus(Control control)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Focus();
                }));
            }
            else
            {
                control.Focus();
            }
        }

        public static void SetHeight(Control control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Height = value;
                }));
            }
            else
            {
                control.Height = value;
            }
        }

        public static void SetLocation(Control control, Point value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Location = value;
                }));
            }
            else
            {
                control.Location = value;
            }
        }

        public static void SetSize(Control control, int width, int height) => SetSize(control, new Size(width, height));

        public static void SetSize(Control control, Size value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Size = value;
                }));
            }
            else
            {
                control.Size = value;
            }
        }

        public static void SetText(Control control, string text)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Text = text;
                }));
            }
            else
            {
                control.Text = text;
            }
        }

        public static void SetTopMost(Form control, bool value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.TopMost = value;
                }));
            }
            else
            {
                control.TopMost = value;
            }
        }

        public static void SetValue(Control control, string value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Text = value;
                }));
            }
            else
            {
                control.Text = value;
            }
        }

        public static void SetValue(ComboBox control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.SelectedIndex = value;
                }));
            }
            else
            {
                control.SelectedIndex = value;
            }
        }

        public static void SetValue(PictureBox control, Image value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() =>
                {
                    control.Image = value;
                }));
            }
            else
            {
                control.Image = value;
            }
        }

        public static string GetValue(ListBox sender)
        {
            string rv = string.Empty;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => {
                    rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString();
                }));
            }
            else
            {
                rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString();
            }

            return rv;
        }

        public static int GetValue(ComboBox sender)
        {
            int rv = -1;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => {
                    rv = sender.SelectedIndex;
                }));
            }
            else
            {
                rv = sender.SelectedIndex;
            }

            return rv;
        }

        public static void SetVisible(Control control, bool value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Visible = value;
                }));
            }
            else
            {
                control.Visible = value;
            }
        }

        public static void SetVisible(Form control, bool value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    if (value)
                    {
                        //control.ShowInTaskbar = value;
                        //control.Opacity = 100;
                        control.Visible = value;
                    }
                    else
                    {
                        control.Visible = value;
                        //control.ShowInTaskbar = value;
                        //control.Opacity = 0;
                    }
                }));
            }
            else
            {
                if (value)
                {
                    //control.ShowInTaskbar = value;
                    //control.Opacity = 100;
                    control.Visible = value;
                }
                else
                {
                    control.Visible = value;
                    //control.ShowInTaskbar = value;
                    //control.Opacity = 0;
                }
            }
        }

        public static void SetWidth(Control control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(() => {
                    control.Width = value;
                }));
            }
            else
            {
                control.Width = value;
            }
        }

    }
}